Developer Resourcesrepair Repair Requests API Guide
Repair Requests API contracts for customer and admin surfaces.
- Module:
RepairRequests
- Customer auth:
JwtAuthGuard (global APP_GUARD — no explicit guard on customer controller)
- Admin auth:
JwtAuthGuard + RoleGuard + @Permissions(...)
- Customer base path:
/api/repair-requests
- Admin base path:
/api/admin/repair-requests
- Admin identifier: internal integer
id (not publicId)
- Success envelope:
ResponseDto<T>
| Method | Path | Description |
|---|
POST | /api/repair-requests | Create repair request |
GET | /api/repair-requests | List own repair requests (paginated) |
GET | /api/repair-requests/:publicId | Get single repair request by public ID |
PATCH | /api/repair-requests/:publicId/cancel | Cancel repair request |
Customer cancel is allowed only when status = request_received. Any other status returns 422 REPAIR_REQUEST_CANNOT_CANCEL.
| Method | Path | Permission |
|---|
GET | /api/admin/repair-requests | RepairRequests_READ |
GET | /api/admin/repair-requests/:id | RepairRequests_READ |
PATCH | /api/admin/repair-requests/:id/status | RepairRequests_UPDATE |
PATCH | /api/admin/repair-requests/:id/collection-method | RepairRequests_UPDATE |
PATCH | /api/admin/repair-requests/:id/notes | RepairRequests_UPDATE |
POST /api/repair-requests
- Request body:
{
"devices": [
{
"brandId": 3,
"laptopModel": "HP Pavilion 15",
"problemDescription": "Screen flickering and battery drain"
}
],
"collectionMethod": "pickup",
"sourceType": "direct_booking",
"sharedDescription": "All devices have the same issue."
}
brandId OR customBrandName must be provided per device (not both, not neither).
orderId is optional — links the repair to an existing order.
orderItemId is optional per device — links device to an order line item.
- Minimum 1 device required.
GET /api/admin/repair-requests?status=under_repair&userId=uuid&dateFrom=2026-06-01&dateTo=2026-06-30&search=TR-&page=1&size=20
| Param | Type | Description |
|---|
status | RepairStatus enum | Filter by current status |
userId | UUID string | Filter by customer UUID |
dateFrom | ISO date string | Tickets created on or after this date |
dateTo | ISO date string | Tickets created on or before this date (inclusive) |
search | string | ILIKE match on ticket number |
page | number | Page number (default: 1) |
size | number | Page size (default: 20) |
PATCH /api/admin/repair-requests/:id/status
- Request body:
{
"status": "picked_up",
"notes": "Picked up at 10:30 AM from customer.",
"estimatedDeliveryAt": "2026-06-25T18:00:00.000Z"
}
notes and estimatedDeliveryAt are optional.
- Triggers a push notification to the customer.
PATCH /api/admin/repair-requests/:id/collection-method
- Request body:
{
"collectionMethod": "dropoff"
}
PATCH /api/admin/repair-requests/:id/notes
- Request body:
{
"adminNotes": "Customer confirmed pickup window: 9 AM–12 PM."
}
| Code | HTTP | Description |
|---|
REPAIR_REQUEST_NOT_FOUND | 404 | Repair request not found by ID or publicId |
REPAIR_REQUEST_NOT_OWNED | 403 | Customer attempted to access another user's ticket |
REPAIR_REQUEST_CANNOT_CANCEL | 422 | Cancel attempted when status is not request_received |
REPAIR_REQUEST_INVALID_STATUS_TRANSITION | 400 | Admin attempted an invalid status transition |
REPAIR_REQUEST_ORDER_NOT_FOUND | 404 | Linked order ID does not exist |
REPAIR_REQUEST_ORDER_NOT_OWNED | 403 | Linked order ID belongs to another customer |
REPAIR_REQUEST_DEVICE_BRAND_REQUIRED | 422 | Device has neither brandId nor customBrandName |
REPAIR_REQUEST_NO_DEVICES | 422 | Create request submitted with zero devices |
REPAIR_REQUEST_CREATE_FAILED | 500 | Ticket number generation or DB write failed |
REPAIR_REQUEST_ORDER_ITEM_NOT_IN_ORDER | 422 | Device's orderItemId does not belong to the linked order |
- Repair requests are free of charge — no payment step.
- Guest users save partial form state in localStorage; after login they are redirected with pre-filled data but do not carry a backend session.
- No duplicate ticket prevention — the same customer may submit multiple tickets for the same device.
publicId is a UUID7 identifier, used in all customer-facing routes.
- Internal
id (serial integer) is used in admin routes.
- Push notifications fire asynchronously after every status transition set by admin (fire-and-forget with
void).