Skip to main content

Repair Issue Notes Module

Overview

The repair-issue-notes module tracks items sent for repair as part of a customer return. When a customer return is approved with a "REPAIR" condition, a repair issue note is created to follow the item through the repair lifecycle until it is returned to the customer.

Domain Concepts

Status Lifecycle

IN_REPAIR → REPAIRED → RETURNED
StatusDescription
IN_REPAIRItem is currently being repaired
REPAIREDRepair completed, awaiting return to customer
RETURNEDRepaired item returned to customer

Key Entities

  • Repair Issue Note — the document tracking a repair, linked to a customer return
  • Detail — JSON object containing the line items being repaired (product, quantity, price, taxes)
  • Cost Detail — optional JSON snapshot of item costs at time of creation

Relationships

EntityRelationship
customer_returnOriginating return (FK: customerReturnId)
customerCustomer who owns the item (FK: customerId)
businessMulti-tenant scope (FK: businessId)
locationStore handling the repair (FK: locationId)
currencyTransaction currency (FK: currencyId)

Architecture

repair-issue-notes/
├── repair-issue-notes.module.ts
├── domain/
│ └── repair-issue-notes-repository.domain.ts # Port interface, sortable keys, enum re-exports
├── application/
│ ├── repair-issue-notes.service.ts # Use cases + event emission
│ └── events/
│ └── on-update-repair-issue-note.event.ts # Update event payload
├── infrastructure/
│ └── repair-issue-notes.repository.ts # Kysely adapter
└── interfaces/
├── repair-issue-notes.controller.ts # HTTP endpoints (Swagger-documented)
├── dtos/
│ ├── create-repair-issue-note.dto.ts
│ └── update-repair-issue-note.dto.ts
└── query/
└── paginate-repair-issue-notes.query.ts

Layer Dependencies

  • Domain — framework-agnostic: repository interface, sortable keys, enum re-exports
  • Application — orchestrates: existence checks, event emission after updates
  • Infrastructure — Kysely queries implementing IRepairIssueNotesRepository
  • Interfaces — thin controller mapping HTTP to service calls

Cross-Module Integration

ModuleRelationship
Customer ReturnsOriginating document; repair note references customerReturnId
InventoriesInventoryReturnHandler listens for repairIssueNote.update events to process inventory adjustments

API Endpoints

MethodPathDescription
POST/repair-issue-notesCreate a repair issue note
GET/repair-issue-notesList with pagination, search, and sorting
GET/repair-issue-notes/:idGet a single repair issue note
PATCH/repair-issue-notes/:idUpdate (status transitions)
DELETE/repair-issue-notes/:idDelete a repair issue note

Query Parameters (GET list)

ParameterTypeDescription
sizenumberPage size (0 = no limit)
pagenumberPage number (1-based)
orderBystringSort field: status, taxId, taxName, taxAddress, locationName
orderstringSort direction: asc or desc
searchstringFull-text search across sortable fields

Example: Create Repair Issue Note

POST /repair-issue-notes
{
"businessId": "550e8400-e29b-41d4-a716-446655440000",
"status": "IN_REPAIR",
"createdBy": "550e8400-e29b-41d4-a716-446655440001",
"issueDate": "2026-03-26",
"customerId": "550e8400-e29b-41d4-a716-446655440002",
"taxId": "17195594",
"taxName": "LUIS RANGEL",
"taxAddress": "CIUDAD",
"locationId": "550e8400-e29b-41d4-a716-446655440003",
"locationName": "Main Store",
"totalAmount": 24.00,
"exchangeRate": 7.90,
"totalBaseAmount": 21.43,
"currencyId": "550e8400-e29b-41d4-a716-446655440004",
"detail": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"productId": "550e8400-e29b-41d4-a716-446655440005",
"productName": "COCA COLA",
"goodOrService": "B",
"unitOfMeasure": "UNI",
"quantity": 1,
"unitPrice": 12.00,
"total": 12.00
}
]
},
"customerReturnId": "550e8400-e29b-41d4-a716-446655440006"
}

Example: Update Status to REPAIRED

PATCH /repair-issue-notes/:id
{
"status": "REPAIRED",
"updatedBy": "550e8400-e29b-41d4-a716-446655440001"
}

Event-Driven Integration

Emitted Events

EventTriggerPayload
repairIssueNote.updateAny PATCH update{ previousRepairIssueNoteRecord, updatedRepairIssueNoteRecord }

Consumers

HandlerModuleAction
InventoryReturnHandler.handleOnUpdateRepairIssueNoteEvent()InventoriesProcesses inventory adjustments based on status transitions

Design Decisions

  1. Event-driven side effects — Status changes emit events rather than directly calling inventory logic, keeping modules decoupled.
  2. Denormalized tax/location fieldstaxId, taxName, taxAddress, locationName are stored on the document to preserve the snapshot at creation time, even if the source records change later.
  3. JSON detail column — Line items are stored as a JSON blob rather than normalized child rows, matching the pattern used by customer returns and other document modules.