# Spec Delta

## Purpose

Keep public domain data consistent when CMMS operations cross Inventory, Maintenance, Assets, and reporting boundaries. Feature boundaries are logical service ownership within the existing layered folders. Domain transaction requirements apply when the corresponding operations are introduced; this baseline does not introduce their endpoints.

## ADDED Requirements

### Requirement: Existing layered structure
The API SHALL preserve its existing routes, controllers, services, validators, middlewares, config and interfaces folders. Auth files SHALL remain in their existing layer folders and the shared Prisma client SHALL remain at config/prisma.ts. This change SHALL NOT introduce modules, http, domain or infrastructure directory trees. Logical domain ownership SHALL be expressed through service responsibilities and public service contracts.

#### Scenario: Extend authentication within the existing architecture
- **WHEN** authentication adopts the shared response/error contract
- **THEN** auth.routes.ts remains under routes, auth.controller.ts under controllers, auth.service.ts under services, auth.schema.ts under validators and auth.middleware.ts under middlewares
- **AND** config/prisma.ts remains the shared database client entry point

#### Scenario: Preserve dependency direction
- **WHEN** a feature operation accesses persistence or coordinates another feature
- **THEN** its controller calls the owning service and that service owns the business operation
- **AND** services do not import Express Request/Response, controllers, routes or middleware
- **AND** public DTO fields are selected explicitly within services

### Requirement: Consistent inventory effects
Every operation that posts inventory effects, including maintenance-related consumption, SHALL apply the same stock availability, approval, and ledger rules. Posted movements SHALL be the source of work-order consumption; the system SHALL NOT maintain an independently editable consumption total.

#### Scenario: Maintenance consumes a part
- **WHEN** a posted issue is associated with a work order
- **THEN** the inventory ledger and balance reflect that issue and the work-order consumption view derives its quantity from the posted movement

### Requirement: Atomic cross-domain mutations
Mutations representing one business operation SHALL commit related domain changes, ledger entries, balance updates, and required audit records together or leave them unchanged on failure. Concurrent requests SHALL NOT overdraw available stock or post the same movement twice.

#### Scenario: Posting fails after balance work begins
- **WHEN** any required write in a stock posting operation fails
- **THEN** the operation leaves no partial balance, ledger, or associated work-order mutation

#### Scenario: Competing stock issues
- **WHEN** two requests compete for stock sufficient for only one
- **THEN** at most one issue succeeds and the other returns a conflict without creating a negative available balance

### Requirement: Retry-safe stock mutations
Stock-posting operations SHALL use a stable idempotency key for one logical request. An identical retry with that key SHALL NOT create another movement or stock effect. Reuse of the key with a different payload SHALL return a conflict. A retry SHALL retain the original key.

#### Scenario: Response lost after commit
- **WHEN** a client retries a committed stock operation with the same key and payload
- **THEN** it receives the original business result with no additional stock effect

### Requirement: Public data isolation
Domain responses SHALL expose explicit public fields and SHALL NOT expose persistence internals or sensitive account fields. Reporting and frontend presentation SHALL NOT alter business state merely by reading or formatting domain data.

#### Scenario: Public authentication DTO
- **WHEN** a stored user includes a password hash
- **THEN** the public user representation excludes that hash regardless of storage schema changes

### Requirement: Historical integrity
Archiving master data SHALL preserve inventory, maintenance, and audit history and their attribution. Read models SHALL derive presentation states without replacing underlying lifecycle state.

#### Scenario: Overdue work order
- **WHEN** an open work order passes its due instant
- **THEN** it can be displayed as overdue while its lifecycle status remains OPEN

#### Scenario: Archived part remains in history
- **WHEN** a part referenced by posted movements is archived
- **THEN** historical movements and related work-order consumption remain available
