7.3 KiB
Task P.6.1 - Document Sequence Scope Refactor
Objective
Refactor document sequence generation so document numbers are scoped by:
Organization + Branch + Product Type + Document Type + Period
This task must be completed before P.7 Document Assembly, because generated/approved/merged documents depend on stable and correct document numbers.
Background
Current document sequence behavior is not sufficient for CRM quotation numbering.
The required numbering examples are:
ALLA
CRA2606-001
DKA2606-001
ONVALLA
CRO2606-001
DKO2606-001
SCO2606-001
Meaning:
CR= Product Type code, e.g. CraneDK= Product Type code, e.g. Dock DoorSC= Product Type code, e.g. Solar CellA/O= Organization or company code2606= YYMM period001= running number within the sequence scope
Required Sequence Scope
Document sequence must be unique per:
organizationId
branchId
productType
documentType
period
The same period may have separate counters for different product types.
Example:
ALLA + Branch A + Crane + Quotation + 2606 = CRA2606-001
ALLA + Branch A + Dock Door + Quotation + 2606 = DKA2606-001
ONVALLA + Branch O + Crane + Quotation + 2606 = CRO2606-001
ONVALLA + Branch O + Dock Door + Quotation + 2606 = DKO2606-001
ONVALLA + Branch O + Solar Cell + Quotation + 2606 = SCO2606-001
Discovery Requirement
Before implementation, inspect the actual current implementation.
Review at minimum:
src/features/foundation/document-sequence
src/db/schema.ts
drizzle migrations
foundation seed
CRM quotation create flow
CRM document sequence settings UI
/dashboard/crm/settings/document-sequences
Identify:
- current table structure
- current unique indexes
- current sequence service behavior
- current seed data
- current UI assumptions
- current document code format
- current quotation create integration
Do not assume the current implementation.
Functional Requirements
1. Schema Refactor
Update document_sequences to support:
- organizationId
- branchId
- productType
- documentType
- period
- prefix
- currentNumber
- padding
- format
- resetPolicy
- isActive
Required uniqueness:
organizationId + branchId + productType + documentType + period
If product type is optional for some future document types, represent this explicitly.
Do not collapse product type into prefix only.
2. Product Type Code Resolution
Resolve product type code from master data or mapping.
Examples:
| Product Type | Code |
|---|---|
| Crane | CR |
| Dock Door | DK |
| Solar Cell | SC |
| Service | SV |
| Spare Part | SP |
The implementation must not hardcode business labels throughout the codebase.
Preferred source:
ms_options / master options
or a centralized CRM product type code map.
3. Organization / Company Code Resolution
Resolve organization/company code for document number middle segment.
Examples:
| Organization | Code |
|---|---|
| ALLA | A |
| ONVALLA | O |
The source should be centralized.
Do not infer by taking the first letter of the organization name unless explicitly configured.
4. Number Format
Required quotation number format:
{productTypeCode}{organizationCode}{YYMM}-{running}
Examples:
CRA2606-001
DKA2606-001
CRO2606-001
DKO2606-001
SCO2606-001
Document type should still be part of the sequence scope even if it does not appear visibly in the final code.
5. Period Handling
Use period format:
YYMM
Example:
2026-06 => 2606
Sequence resets per period.
6. Quotation Create Flow
Quotation creation must request the next sequence using:
- organizationId
- branchId
- productType
- documentType = quotation
- quotation date / created date period
The generated code must be stored on the quotation.
7. Settings UI
Update:
/dashboard/crm/settings/document-sequences
The UI must show and filter by:
- Organization
- Branch
- Product Type
- Document Type
- Period
- Prefix / Format
- Current Number
- Next Number
- Active Status
It must be clear that Branch means internal company branch, not customer branch.
8. Seed Data
Update seed data to create realistic document sequence rows for:
ALLA + Crane
ALLA + Dock Door
ONVALLA + Crane
ONVALLA + Dock Door
ONVALLA + Solar Cell
At minimum seed quotation sequence examples for the current period.
9. Backward Compatibility
Existing generated quotations must keep their current codes.
Do not retroactively change old quotation codes.
Only new generated codes use the new sequence logic.
If existing document_sequences rows lack product type, migration must either:
- backfill product type where determinable, or
- mark them as legacy/inactive, or
- keep them compatible without being used for new CRM quotation generation
Concurrency Requirement
Sequence generation must be concurrency-safe.
When two users create quotations at the same time under the same scope, they must not receive duplicate codes.
Preferred approach:
- database transaction
- row-level lock
- atomic increment
Do not generate next number purely in client code.
Error Handling
Handle:
- missing product type
- missing branch
- missing organization code
- missing product type code
- inactive sequence
- duplicate sequence row
- unsupported document type
- period mismatch
Errors should be business-readable.
Audit Logging
Record audit logs for:
- sequence created
- sequence updated
- sequence activated/deactivated
- next number generated
- sequence generation failed
Testing Requirements
Add tests for:
- separate counter per product type
- separate counter per organization
- separate counter per branch
- monthly reset
- concurrent generation safety if practical
- missing product type code
- missing organization code
- quotation create integration
- backward compatibility with existing quotation codes
Run:
npm run typecheck
npm run build
npm run audit:pdf
Acceptance Criteria
- Document sequence scope includes Organization + Branch + Product Type + Document Type + Period.
- Quotation number format matches
{productTypeCode}{organizationCode}{YYMM}-{running}. - ALLA Crane can generate
CRA2606-001. - ALLA Dock Door can generate
DKA2606-001. - ONVALLA Crane can generate
CRO2606-001. - ONVALLA Dock Door can generate
DKO2606-001. - ONVALLA Solar Cell can generate
SCO2606-001. - Different product types do not share counters.
- Different organizations do not share counters.
- Different branches do not share counters.
- Existing quotation codes remain unchanged.
- Settings UI shows product type and branch clearly.
- Sequence generation is concurrency-safe.
- Runtime PDF audit still passes.
Out of Scope
P.7
- PDF merge
- Document Assembly
- SLA append rules
- Final merged artifact
P.8
- Render configuration
- Optional sections
- User-selectable product table visibility
Final Success Condition
Task P.6.1 is complete when new CRM quotations generate document numbers using the correct Organization + Branch + Product Type + Document Type + Period scope, while existing documents remain unchanged and the system is safe to proceed to P.7 Document Assembly.