uat-doc-perfix
This commit is contained in:
389
plans/task-p.6.1.md
Normal file
389
plans/task-p.6.1.md
Normal file
@@ -0,0 +1,389 @@
|
||||
# Task P.6.1 - Document Sequence Scope Refactor
|
||||
|
||||
## Objective
|
||||
|
||||
Refactor document sequence generation so document numbers are scoped by:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
ALLA
|
||||
CRA2606-001
|
||||
DKA2606-001
|
||||
|
||||
ONVALLA
|
||||
CRO2606-001
|
||||
DKO2606-001
|
||||
SCO2606-001
|
||||
```
|
||||
|
||||
Meaning:
|
||||
|
||||
* `CR` = Product Type code, e.g. Crane
|
||||
* `DK` = Product Type code, e.g. Dock Door
|
||||
* `SC` = Product Type code, e.g. Solar Cell
|
||||
* `A` / `O` = Organization or company code
|
||||
* `2606` = YYMM period
|
||||
* `001` = running number within the sequence scope
|
||||
|
||||
---
|
||||
|
||||
# Required Sequence Scope
|
||||
|
||||
Document sequence must be unique per:
|
||||
|
||||
```text
|
||||
organizationId
|
||||
branchId
|
||||
productType
|
||||
documentType
|
||||
period
|
||||
```
|
||||
|
||||
The same period may have separate counters for different product types.
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
{productTypeCode}{organizationCode}{YYMM}-{running}
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
YYMM
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```text
|
||||
/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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```bash
|
||||
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.
|
||||
Reference in New Issue
Block a user