Shop It Docs
Developer Resourcesrepair

Repair Requests Backend Documentation

Repair Requests — Backend Documentation

1. Backend Scope and Boundaries

The repair request backend owns:

  • customer-facing ticket creation, listing, retrieval, and self-cancellation
  • admin-facing ticket management: status progression, collection method update, notes management
  • push notification dispatch on every admin status change
  • no payment logic (repair is free)
  • no technician assignment
  • no duplicate-ticket prevention

The backend does not manage repair scheduling, technician routing, or part sourcing.

2. Module Composition

RepairModule composes:

  • RepairCustomerModule — customer controller + service
  • RepairAdminModule — admin controller + service

NotificationsService is injected directly in both leaf services. NotificationsModule is @Global() so no explicit module import is needed.

3. Data Model (Drizzle / PostgreSQL)

repair_ticket

  • id serial primary key
  • public_id uuid not null unique — UUID7, generated at creation
  • ticket_number varchar(20) not null unique — format: TR-YYYYMMDD-XXXXX (5 uppercase alphanumeric suffix)
  • user_id uuid not null → customers(id) ON DELETE CASCADE
  • order_id integer nullable → orders(id) ON DELETE SET NULL
  • status repair_status not null default 'request_received'
  • collection_method repair_collection_method not null default 'pickup'
  • source_type repair_source_type not null default 'direct_booking'
  • shared_description text nullable
  • admin_notes text nullable
  • estimated_delivery_at timestamptz nullable
  • 8 status timestamp columns: requested_at, picked_up_at, under_repair_at, repaired_at, packed_at, delivered_at, cancelled_at, created_at, updated_at
  • inline shipping fields: shipping_address_line_1, shipping_address_line_2, shipping_city, shipping_state, shipping_postal_code, shipping_district, shipping_landmark, shipping_mobile_num, shipping_latitude, shipping_longitude

repair_ticket_device

  • id serial primary key
  • repair_ticket_id integer not null → repair_ticket(id) ON DELETE CASCADE
  • brand_id integer nullable → brands(id) ON DELETE SET NULL
  • custom_brand_name varchar(120) nullable
  • laptop_model varchar(200) not null
  • problem_description text nullable
  • order_item_id integer nullable → order_items(id) ON DELETE SET NULL
  • CHECK (brand_id IS NOT NULL OR custom_brand_name IS NOT NULL) — enforced at DB level

repair_ticket_status_history

  • id serial primary key
  • repair_ticket_id integer not null → repair_ticket(id) ON DELETE CASCADE
  • status repair_status not null
  • actor_type repair_actor_type not nullcustomer | admin | system
  • notes text nullable
  • created_at timestamptz — append-only; NO updated_at column

Enums

EnumValues
repair_statusrequest_received, picked_up, under_repair, repaired, packed, delivered, cancelled
repair_collection_methodpickup, dropoff
repair_actor_typecustomer, admin, system
repair_source_typedirect_booking, support_ticket, order_linked

4. Status Machine

request_received → picked_up → under_repair → repaired → packed → delivered (terminal)
                  └────────────────────────────────────────────────→ cancelled (terminal)

All non-terminal statuses may transition to cancelled. Admin drives all transitions except self-cancellation (customer may cancel only from request_received).

Each status transition:

  1. Updates repair_ticket.status and the corresponding timestamp column (in one UPDATE).
  2. Inserts a row in repair_ticket_status_history with actor_type = 'admin'.
  3. Fires a push notification to the customer (fire-and-forget via void).

Both the UPDATE and the INSERT execute inside a single DB transaction. The notification is dispatched after the transaction completes, not inside it.

Status → Timestamp Column Mapping

StatusColumn
picked_uppicked_up_at
under_repairunder_repair_at
repairedrepaired_at
packedpacked_at
delivereddelivered_at
cancelledcancelled_at

5. Notifications

All notifications use NotificationsService.sendToUser() with type: "transactional", priority: "high", inAppTargets: ["mobile_in_app", "web_in_app"], pushTargets: ["mobile_push"].

TriggerTitleBody
request_received (creation)"Repair Request Received""Your repair request has been received. Ticket #<number>."
picked_up"Laptop Picked Up""Your laptop has been picked up for repair."
under_repair"Repair In Progress""Your laptop is now being repaired by our technicians."
repaired"Repair Completed""Your laptop repair is complete and is being prepared for delivery."
packed"Out for Delivery Soon""Your laptop has been packed and will be delivered shortly."
delivered"Laptop Delivered""Your laptop has been successfully delivered. Thank you!"
cancelled"Repair Cancelled""Your repair request has been cancelled. Contact support for assistance."

Customer cancel (SP2 service) does not fire a separate notification — the customer initiated it.

6. Performance Notes

  • findAll (both customer and admin services) uses inArray to batch-fetch devices and history for all ticket IDs on a page, avoiding N+1 queries.
  • Device rows are fetched via LEFT JOIN brands to resolve brand name in one query.
  • Admin list filters build a SQL[] array and spread into and() — no unnecessary filter clauses for undefined params.
  • Paginated responses include a separate COUNT(*) query when pagination = true.

7. File Map

packages/db/src/schema/repair/          — schema source of truth
  enums.ts
  repair-tickets.ts
  repair-ticket-devices.ts
  repair-ticket-status-history.ts
  index.ts

packages/db/src/migrations/
  0005_repair_request_schema.sql         — generated Drizzle migration (78 lines)

apps/api/src/modules/repair/
  repair.module.ts                       — aggregate module
  customer/
    repair-customer.module.ts
    repair-customer.controller.ts        — 4 customer endpoints
    repair-customer.service.ts
    dto/                                 — 5 files (create-device, create-request, fetch, response, barrel)
    __tests__/unit/services/             — 14 unit tests
  admin/
    repair-admin.module.ts
    repair-admin.controller.ts           — 5 admin endpoints
    repair-admin.service.ts
    dto/                                 — 6 files (fetch-admin, update-status, update-method, update-notes, admin-response, barrel)
    __tests__/unit/services/             — 14 unit tests
    __tests__/integration/               — 10 integration tests