task-p.7.1.1

This commit is contained in:
phaichayon
2026-06-30 20:42:28 +07:00
parent e5766ea311
commit 8feaee61cb
29 changed files with 2673 additions and 875 deletions

379
plans/task-d.4.6.md Normal file
View File

@@ -0,0 +1,379 @@
# Task D.4.6: Fix Quotation Document Sequence Product-Type Resolution
## Objective
Fix quotation creation failure caused by incorrect quotation-type to product-type resolution during document number generation.
This task must correct the runtime mapping logic inside the document sequence service without introducing duplicate master data or changing existing business rules.
---
## Background
Creating a quotation currently fails with:
```json
{
"message": "Missing product type code configuration quotation type."
}
```
The failure occurs after quotation validation succeeds and immediately before document number allocation.
Investigation confirmed this is **not** caused by missing seed data.
---
## Current Findings
Verified:
- Quotation payload validation succeeds.
- `createQuotation()` reaches document code generation.
- `generateNextDocumentCode()` throws before allocating a sequence.
- Database already contains:
### Master Options
Category:
```
crm_quotation_type
```
Values:
- crane
- dockdoor
- solarcell
- service
- other
Category:
```
crm_product_type
```
Values:
- crane
- dockdoor
- solarcell
- service
- sparepart
### Document Sequences
Quotation sequences already exist for:
- crane
- dockdoor
- solarcell
- service
Therefore the failure is **not** caused by missing:
- master option
- document sequence
- seed data
---
## Root Cause
The document sequence service is failing to consistently resolve:
Quotation Type
Product Type
Document Sequence
The runtime mapping rejects a valid quotation type before sequence generation.
This is a logic bug.
---
## Scope
Review:
```
src/features/crm/quotations/server/service.ts
```
```
src/features/foundation/document-sequence/service.ts
```
```
src/features/foundation/master-options/*
```
```
src/db/seeds/*
```
Do **not** redesign the quotation module.
Do **not** modify document numbering rules.
---
## Requirements
### 1. Trace Runtime Resolution
Document the complete resolution path.
Expected flow:
```
Quotation
quotationTypeId
Master Option
productTypeCode
Document Sequence
Document Number
```
Verify every transformation.
---
### 2. Normalize Product Type Resolution
Support all valid inputs.
The resolver should accept:
- option id
- option code
- normalized product type code
It must not depend on display labels.
---
### 3. Standardize Mapping
Support at minimum:
| Quotation Type | Product Type | Prefix |
|----------------|-------------|--------|
| crane | crane | CR |
| dockdoor | dockdoor | DK |
| solarcell | solarcell | SC |
| service | service | SV |
| sparepart | sparepart | SP |
Future product types should require configuration only, not new code branches.
---
### 4. Remove Duplicate Lookup Logic
If quotation service and document sequence service both perform mapping independently:
Refactor into a shared resolver.
Avoid duplicated switch statements.
---
### 5. Improve Error Messages
Replace generic runtime errors with diagnostic information.
Example:
```
Unable to resolve product type for quotation.
quotationTypeId:
xxxxxxxx
quotationTypeCode:
crane
organizationId:
...
branchId:
...
resolvedProductType:
null
```
This should only be returned internally/logged during development.
User-facing messages should remain business friendly.
---
### 6. Preserve Existing Business Rules
Do not modify:
- organization isolation
- branch isolation
- document numbering format
- document sequence locking
- approval workflow
- quotation schema
---
### 7. Frontend Error Handling
Improve API error handling.
Current UI displays:
```
API Error 400 Bad Request
```
Instead display backend messages when available.
Example:
```
Missing product type code configuration quotation type.
```
Fallback to generic messages only when backend provides none.
---
## Validation
Verify quotation creation succeeds for:
- Crane
- Dock Door
- Solar Cell
- Service
Each must generate the correct sequence.
Example:
```
CRA2606-001
```
```
DKA2606-001
```
```
SCA2606-001
```
```
SVA2606-001
```
Verify the sequence increments correctly.
---
## Regression Checklist
Confirm no regression for:
- Document sequence generation
- Branch-specific numbering
- Organization-specific numbering
- Product-specific numbering
- Existing document types
- Existing sequence rows
- Existing seeds
---
## Technical Constraints
- No database schema changes unless absolutely required.
- No duplicate `ms_options`.
- No duplicate `document_sequences`.
- Keep seed scripts idempotent.
- Preserve current APIs.
---
## Deliverables
- Fixed runtime product-type resolution.
- Shared resolver (if duplication exists).
- Improved backend diagnostics.
- Improved frontend API error display.
- Updated unit/integration tests where applicable.
- Verification report summarizing:
- root cause
- implementation
- validation results
- regression results
---
## Acceptance Criteria
- Quotation creation succeeds without 400 errors for all configured product types.
- Document numbers are generated correctly.
- Existing numbering rules remain unchanged.
- No additional seed data is required.
- TypeScript passes.
```bash
npm exec tsc --noEmit
```
- Existing test suite passes.
- No regression in document sequence generation.
---
## Implementation Status - 2026-06-30
- Status: Completed
- Implementation report:
- [task-d.4.6-quotation-document-sequence-fix-2026-06-30.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-d.4.6-quotation-document-sequence-fix-2026-06-30.md)
### Result Summary
- Fixed quotation-type to product-type resolution in document sequence generation.
- Added a shared resolver for option id/code/alias handling plus quotation-type reference mapping.
- Preserved current numbering rules and existing sequence rows.
- Improved API client error handling so backend messages can be shown in the UI.
### Validation Summary
- `npm exec tsc --noEmit` passed.
- `node --import tsx --test src/features/foundation/document-sequence/config.test.ts src/features/foundation/document-sequence/product-type-resolver.test.ts` passed.
- Authenticated API verification on `http://localhost:3000` passed for:
- `crane` -> `CRA2606-002`
- `dockdoor` -> `DKA2606-001`
- `solarcell` -> `SCA2606-001`
- `service` -> `SVA2606-001`

421
plans/task-d.4.7.md Normal file
View File

@@ -0,0 +1,421 @@
# Task D.4.7 Organization-aware Document Sequence & Prefix Strategy
## Objective
Redesign the document-sequence strategy so document prefixes are configuration-driven and organization-aware, eliminating hardcoded prefix logic from the application.
The new design must support multiple companies, branches, product types, and document types without requiring source code changes.
---
# Background
Current document numbering works correctly after Task D.4.6 but still assumes product prefixes are fixed inside the application.
Example:
```
CRA2606-001
DKA2606-001
SCA2606-001
```
However, the business requires different companies (organizations) to use different prefixes while keeping the same product types.
Example:
## ALLA
```
CRA2606-001
DKA2606-001
SCA2606-001
SVA2606-001
```
## ONVALLA
```
CRO2606-001
DKO2606-001
SCO2606-001
SVO2606-001
```
The application should support additional organizations in the future without code modifications.
---
# Business Requirements
Document numbers must be isolated by:
```
Organization
Branch
Document Type
Product Type
Running Number
```
Running numbers must never overlap across organizations.
Example
ALLA
```
CRA2606-001
CRA2606-002
```
ONVALLA
```
CRO2606-001
CRO2606-002
```
Both organizations maintain independent counters.
---
# Scope
Review:
```
src/features/foundation/document-sequence/*
```
```
src/features/foundation/master-options/*
```
```
src/db/schema.ts
```
```
src/db/seeds/*
```
Review existing document sequence configuration before introducing new structures.
Avoid duplicate concepts.
---
# Requirements
## 1. Remove Hardcoded Prefix Logic
No document prefix may be hardcoded.
Avoid patterns such as:
```ts
switch(productType){
case "crane":
return "CRA";
}
```
or
```ts
if(productType==="crane")
```
Prefix generation must be configuration-driven.
---
## 2. Introduce Organization-aware Prefix Configuration
Design a configuration that determines:
```
Organization
Document Type
Product Type
Prefix
```
Example
| Organization | Document | Product | Prefix |
|--------------|----------|----------|--------|
| ALLA | quotation | crane | CRA |
| ALLA | quotation | dockdoor | DKA |
| ALLA | quotation | solarcell | SCA |
| ALLA | quotation | service | SVA |
| ONVALLA | quotation | crane | CRO |
| ONVALLA | quotation | dockdoor | DKO |
| ONVALLA | quotation | solarcell | SCO |
| ONVALLA | quotation | service | SVO |
Future organizations must be configurable without code changes.
---
## 3. Preserve Existing Sequence Strategy
Current uniqueness must remain:
```
Organization
+
Branch
+
Document Type
+
Product Type
+
Period
```
Running numbers remain independent.
---
## 4. Keep Product Resolver Generic
Task D.4.6 introduced a shared product-type resolver.
Do not move organization logic into the resolver.
Responsibilities should become:
### Product Resolver
Responsible only for
```
Quotation Type
Product Type
```
### Document Sequence
Responsible only for
```
Organization
Prefix
Running Number
```
Keep these responsibilities separated.
---
## 5. Centralize Prefix Configuration
Avoid scattered constants.
Design a single source of truth.
Example
```
Document Prefix Configuration
Resolver
Document Sequence
```
No module should define its own prefixes.
---
## 6. Support Future Document Types
The strategy must support future modules.
Examples
```
Quotation
Delivery Note
Sales Contract
Purchase Order
Invoice
Service Report
Work Order
```
Each document type may define its own prefixes.
---
## 7. Preserve Backward Compatibility
Existing document numbers remain valid.
Do not change
- existing quotations
- revisions
- approved PDFs
- audit logs
Only affect newly generated numbers.
---
## 8. Improve Configuration Validation
During startup or seed validation verify:
- duplicate prefixes
- missing prefix
- missing organization mapping
- invalid product type
- invalid document type
Configuration errors should fail early with clear messages.
---
# Database Considerations
Review whether existing `document_sequences` already contains sufficient information.
If additional configuration is required:
- prefer extending existing structures
- avoid introducing duplicate master tables
- justify any schema change
Migration must remain backward compatible.
---
# Tests
Add coverage for:
- ALLA quotation
- ONVALLA quotation
- branch isolation
- organization isolation
- period rollover
- configuration validation
- missing prefix
- duplicate configuration
---
# Verification
Verify:
ALLA
```
CRA2606-001
CRA2606-002
```
```
DKA2606-001
```
ONVALLA
```
CRO2606-001
CRO2606-002
```
```
DKO2606-001
```
Ensure counters remain independent.
---
# Regression Checklist
Confirm no regression for:
- Quotation creation
- Revision creation
- Approval workflow
- PDF generation
- Document preview
- Audit log
- Existing APIs
- Existing seed data
---
# Deliverables
- Organization-aware prefix strategy
- Configuration-driven prefix resolution
- Removal of hardcoded prefix logic
- Updated seed/configuration (if required)
- Updated unit tests
- Verification report
- Architecture notes describing the new numbering strategy
---
# Acceptance Criteria
- No hardcoded document prefixes remain.
- Prefixes are configurable per organization.
- Running numbers remain isolated by organization, branch, document type, product type, and period.
- Existing document numbers remain valid.
- Future organizations can be added through configuration without modifying application logic.
- TypeScript passes.
```bash
npm exec tsc --noEmit
```
- All document-sequence tests pass.

366
plans/task-p.7.1.1.md Normal file
View File

@@ -0,0 +1,366 @@
# Task P.7.1.1 - Customer Package UI Integration
## Objective
Add user-facing UI controls for generating, viewing, and downloading the assembled customer document package from the quotation detail page.
This task connects the existing Document Assembly API to the CRM UI.
It does not introduce SMTP, email sending, or notification automation.
---
# Background
Completed:
* P.7 Document Assembly Framework
* P.7.1 Notification Foundation
Current backend APIs exist:
```text
POST /api/crm/quotations/[id]/assembled-pdf
GET /api/crm/quotations/[id]/assembled-pdf/download
```
However, users currently have no UI button to generate the assembled PDF before download.
This causes:
```text
Assembled quotation PDF has not been generated yet.
```
when the download endpoint is called before package generation.
---
# Scope
Included:
* Quotation detail UI integration
* Generate Customer Package action
* Download Customer Package action
* Package status display
* Included document list display
* Error handling for missing SLA or required documents
* Loading and success states
* Query/mutation integration
* Permission guard
Excluded:
* SMTP / Email provider configuration
* Sending customer email
* Notification event automation
* Render configuration
* User-selectable append documents
* Assembly policy editor
---
# UI Placement
Add a section in quotation detail page.
Suggested label:
```text
Customer Package
```
Suggested actions:
```text
Generate Customer Package
Download Customer Package
Regenerate Package
```
Suggested display:
```text
Status: Not Generated / Generated / Failed
Generated At
Generated By
Included Documents:
- Quotation
- SLA
- Warranty
- Datasheet
Page Count
File Size
Checksum
```
---
# API Usage
## Generate
Call:
```http
POST /api/crm/quotations/[id]/assembled-pdf
```
Expected behavior:
* generate quotation PDF if needed
* resolve active SLA / append documents
* merge PDFs
* store final artifact
* return package metadata
---
## Download
Call:
```http
GET /api/crm/quotations/[id]/assembled-pdf/download
```
If package is not generated:
* show user-friendly message
* do not show raw API error only
* suggest generating package first
---
# Client Service
Add client service methods.
Example:
```ts
generateQuotationCustomerPackage(quotationId: string)
downloadQuotationCustomerPackage(quotationId: string)
getQuotationCustomerPackageStatus(quotationId: string)
```
If a status endpoint does not exist yet, either:
* add one, or
* return status from existing quotation/detail payload if already available
---
# React Query
Add mutation/query support:
* generate customer package mutation
* package status query
* invalidate quotation detail after successful generation
* invalidate document/artifact query if applicable
---
# Permissions
Use existing or add permission:
```text
crmQuotationGenerateCustomerPackage
crmQuotationDownloadCustomerPackage
```
If permission model already has quotation PDF permissions, reuse only if semantically correct.
---
# Error Handling
Handle:
## Not Generated
Show:
```text
Customer package has not been generated yet. Please generate it first.
```
## Missing Required Document
Example:
```text
Cannot generate package because required SLA document is missing.
```
## Assembly Failure
Show:
```text
Customer package generation failed. Please check document library configuration.
```
## Permission Denied
Show:
```text
You do not have permission to generate or download customer package.
```
---
# UX Rules
* Disable download button until package exists.
* Show loading state while generating.
* Allow regenerate after package exists.
* Confirm before regenerate if it overwrites or creates a new artifact version.
* Do not automatically email after generation.
* Do not automatically activate any template or library document.
---
# Verification Scenarios
Test manually:
## Scenario 1 - No Package
Open quotation detail.
Expected:
* status = Not Generated
* Download disabled
* Generate enabled
## Scenario 2 - Generate Package
Click Generate Customer Package.
Expected:
* package generated
* included documents visible
* SLA listed if policy requires it
* Download enabled
## Scenario 3 - Download Package
Click Download.
Expected:
* PDF downloads
* PDF includes quotation + SLA
## Scenario 4 - Missing Required SLA
Temporarily remove/inactivate SLA.
Click Generate.
Expected:
* business-readable error
* no broken artifact
## Scenario 5 - Regenerate
Click Regenerate.
Expected:
* new artifact created or existing artifact updated according to backend behavior
* UI status refreshes
---
# Testing Requirements
Run:
```bash
npm run typecheck
npm run build
npm run audit:pdf
```
Add tests where practical for:
* mutation service
* UI state helper
* permission visibility
* error message mapping
---
# Acceptance Criteria
* Quotation detail page has Customer Package section.
* User can generate assembled package from UI.
* User can download assembled package after generation.
* UI clearly shows package status.
* UI shows included documents such as SLA.
* Missing required SLA displays clear error.
* Download before generation is prevented in UI.
* Existing approved PDF actions remain unchanged.
* No email is sent in this task.
* Build and typecheck pass.
---
# Out of Scope
## P.7.2
* SMTP configuration
* Email provider settings
* Real email delivery verification
## P.7.3
* Approval notification automation
* Request approval email
* Approve/reject email
## P.7.4
* Send Customer Package Email
* Customer recipient selection
* Email history from quotation detail
---
# Final Success Condition
Task P.7.1.1 is complete when users can generate and download the assembled Customer Package directly from quotation detail, confirm that SLA is included, and proceed to P.7.2 email configuration with a usable package artifact already available.
---
## Implementation Status - 2026-06-30
Status: Completed
Implemented:
- Added `Customer Package` section on quotation detail page with generate, regenerate, preview, and download actions.
- Reused assembled quotation package APIs and existing quotation PDF permissions instead of adding a separate permission model.
- Extended quotation detail payload with active assembled artifact metadata so UI can show package status, generator, checksum, file size, page count, included documents, and warnings.
- Added customer-package error/status helpers and focused tests.
- Added `POST /api/crm/quotations/[id]/assembled-pdf` support by exporting the existing generate handler from the assembled-pdf route.
Verification:
- `npm exec tsc --noEmit` -> PASS
- `node --import tsx --test src/features/foundation/document-sequence/config.test.ts src/features/crm/quotations/customer-package.test.ts` -> PASS
- `npm run build` -> PASS
- `npm run audit:pdf` -> baseline FAIL unrelated to this task:
- `ACTIVE_VERSION_SCHEMA_DRIFT`
- `topicRuntime` / integrity summary failure
Implementation report:
- [task-p.7.1.1-customer-package-ui-integration-2026-06-30.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-p.7.1.1-customer-package-ui-integration-2026-06-30.md)