Skip to main content

Damage Reasons API

Module Overview

The DamageReasonsModule provides a CRUD catalog for business-specific reasons why inventory items were damaged. These reasons are referenced by damage_report_line records when creating damage reports.

ControllerBase PathDescription
DamageReasonsController/damage-reasonsCRUD for damage/loss reason catalog entries

Authentication

All endpoints require Firebase authentication:

  • Header: Authorization: Bearer <firebase-id-token>
  • Cookie: Alternatively, send the token via the flowpos-id-token cookie

Architecture

damage-reasons/
├── damage-reasons.module.ts # NestJS module (DI wiring)
├── domain/
│ └── damage-reasons-repository.domain.ts # Port interface + injection token
├── application/
│ └── damage-reasons.service.ts # Business logic (framework-agnostic params)
├── infrastructure/
│ └── damage-reasons.repository.ts # Kysely implementation
└── interfaces/
├── damage-reasons.controller.ts # HTTP routes (Swagger-documented)
├── dtos/
│ ├── create-damage-reason.dto.ts
│ └── update-damage-reason.dto.ts
└── query/
└── paginate-damage-reasons.query.ts

Key design decisions:

  • Repository injected via DAMAGE_REASONS_REPOSITORY symbol token (dependency inversion)
  • Service accepts plain parameter objects — no DTO imports from the interfaces layer
  • Hard delete on reasons; FK on damage_report_line.damageReasonId uses onDelete("set null")

Endpoints

1. Create Damage Reason

POST /damage-reasons

Body:

FieldTypeRequiredDescription
businessIdUUIDYesUUID of the owning business
namestringYesHuman-readable name (e.g. "Breakage")
descriptionstringNoLonger explanation of when this reason applies
createdByUUIDNoUUID of the creating user

Response: 201 — The created damage reason object.


2. List Damage Reasons

GET /damage-reasons

Query parameters:

ParamTypeDefaultDescription
businessIdUUIDRequired. Filter by business
qstringSearch by name (case-insensitive)
pagenumber1Page number
limitnumber50Items per page
includeInactivebooleanfalseInclude inactive reasons

Response: 200

{
"currentPage": 1,
"pages": 3,
"results": [
{
"id": "uuid",
"businessId": "uuid",
"name": "Breakage",
"description": "Items damaged during handling",
"isActive": true,
"createdAt": "2026-03-01T00:00:00.000Z",
"createdBy": "uuid",
"updatedAt": null,
"updatedBy": null
}
]
}

3. Get Damage Reason by ID

GET /damage-reasons/:id

Response: 200 — Single damage reason object. 404 if not found.


4. Update Damage Reason

PATCH /damage-reasons/:id

Body (all optional):

FieldTypeDescription
namestringUpdated name
descriptionstringUpdated description
isActivebooleanToggle active/inactive status
updatedByUUIDUUID of the user making the change

Response: 200 — The updated damage reason object.


5. Delete Damage Reason

DELETE /damage-reasons/:id

Response: 200

{
"message": "DamageReason <id> deleted."
}

This is a hard delete. Existing damage_report_line rows referencing this reason will have damage_reason_id set to null.


Bruno Collection

API requests are available in:

api-client/flowpos/collections/damage-reasons/

Environment variables used: BASE_URL, ID_TOKEN, businessId, userId, damageReasonId.


Database Schema

CREATE TABLE damage_reason (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
business_id UUID NOT NULL REFERENCES business(id),
name VARCHAR NOT NULL,
description TEXT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by UUID,
updated_at TIMESTAMPTZ,
updated_by UUID
);

The damage_report_line table references damage_reason(id) with ON DELETE SET NULL.