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

View File

@@ -1,7 +1,7 @@
{
"generatedAt": "2026-06-30T09:16:20.352Z",
"generatedAt": "2026-06-30T13:14:09.584Z",
"overallStatus": "PASS",
"quotationCode": "CRA2606-1107",
"quotationCode": "CRA2606-1121",
"expectedFixtureCode": "QT-H5-AUDIT",
"template": {
"templateName": "ALLA Demo Organization Quotation Standard",
@@ -238,11 +238,11 @@
]
},
"metrics": {
"topicCount": 3,
"itemCount": 4,
"partyCount": 1,
"dynamicTopicFieldCount": 3,
"dynamicTopicItemFieldCount": 3,
"topicCount": 0,
"itemCount": 0,
"partyCount": 2,
"dynamicTopicFieldCount": 0,
"dynamicTopicItemFieldCount": 0,
"mappingCount": 23
},
"mappingCoverage": {
@@ -256,14 +256,14 @@
"itemTableColumns": []
},
"runtimePayload": {
"templateInputKeys": 31,
"topicInputKeys": 6,
"templateInputKeys": 25,
"topicInputKeys": 0,
"priceTableRows": 1
},
"consistency": {
"status": "PASS",
"approvedSnapshotAvailable": true,
"approvedArtifactReference": "artifact:6dfd7a74-8e9a-48ad-a4fe-dbb520edf581",
"approvedArtifactReference": null,
"inconsistentKeys": []
},
"integritySummary": {

View File

@@ -1,16 +1,16 @@
# PDF Audit Report
- Generated At: 2026-06-30T09:16:20.352Z
- Generated At: 2026-06-30T13:14:09.584Z
- Overall Status: PASS
- Quotation Code: CRA2606-1107
- Quotation Code: CRA2606-1121
- Template: ALLA Demo Organization Quotation Standard v1.0
- Previous Version: None
## Metrics
- Topic Count: 3
- Item Count: 4
- Project Party Count: 1
- Topic Count: 0
- Item Count: 0
- Project Party Count: 2
- Mapping Count: 23
## Mapping Coverage

View File

@@ -0,0 +1,56 @@
# Quotation Create 400 Investigation - 2026-06-30
## Scope
Investigate why quotation creation fails with `POST /api/crm/quotations -> 400`.
## Summary
The failure is reproducible on the running local app and the API returns:
```json
{"message":"Missing product type code configuration quotation type."}
```
This happens inside the document-sequence layer during quotation code generation, not in the quotation form schema itself.
## Reproduction
1. Sign in with seeded UAT admin account:
- `admin.uat@alla.local`
- `UatDemo123!`
2. Submit a valid-looking quotation payload to `POST /api/crm/quotations`.
3. The API returns `400` with message:
- `Missing product type code configuration quotation type.`
Reproduced against the local app at `http://localhost:3000` with authenticated session.
## Findings
1. Quotation creation reaches [createQuotation()](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/server/service.ts:1329), passes quotation payload validation, and then calls `generateNextDocumentCode()` for document code allocation.
2. The failure occurs inside the document-sequence product-type resolution path in [src/features/foundation/document-sequence/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-sequence/service.ts:152) and [generateNextDocumentCode()](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-sequence/service.ts:527).
3. Database inspection shows the organization does have valid master options for both:
- `crm_quotation_type`: `crane`, `dockdoor`, `solarcell`, `service`, `other`
- `crm_product_type`: `crane`, `dockdoor`, `solarcell`, `service`, `sparepart`
4. Database inspection also shows quotation document sequences already exist for:
- `crane`
- `dockdoor`
- `solarcell`
- `service`
5. Because both option categories and document-sequence rows are present, the `400` is not caused by missing seed data in `ms_options` or missing quotation sequence rows.
6. The remaining failure point is the runtime mapping logic that resolves a quotation type id/code into the product-type code used by document sequences. That logic is currently rejecting a valid quotation type before sequence generation completes.
## Likely Root Cause
The product-type map resolution in [src/features/foundation/document-sequence/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-sequence/service.ts:152) is not successfully resolving the incoming quotation type id/code to a usable document-sequence product type, even though:
- the quotation type option exists
- the product type option exists
- the document sequence row exists
In other words, this is a mapping bug in the document-sequence resolution path, not a missing reference-data problem in the quotation form.
## Secondary Observation
The frontend currently surfaces quotation create failures through [apiClient](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/lib/api-client.ts:1) as generic `API error: 400 Bad Request`, which hides the backend message unless the request is inspected manually. That makes this class of failure harder to diagnose from the UI alone.
## Status
- Investigation completed
- Root cause area identified
- No production code fix applied in this investigation round
## Recommended Next Step
Patch the document-sequence product-type resolution so quotation type ids from quotation creation resolve consistently to the corresponding `crm_product_type` code before `generateNextDocumentCode()` runs.

View File

@@ -0,0 +1,54 @@
# Task D.4.6 Implementation Report - 2026-06-30
## Scope
- Fix `POST /api/crm/quotations` returning `400` during document-number generation.
- Preserve existing quotation, sequence, branch, organization, and approval rules.
- Improve frontend propagation of backend error messages.
## Root Cause
- Quotation create sends `payload.quotationType` as a master-option `id` from category `crm_quotation_type`.
- Document-sequence resolution was looking up only `crm_product_type` options.
- Because `crm_quotation_type.id` and `crm_product_type.id` are different records, valid quotation-type ids never resolved to a product-type code even though the codes and document-sequence rows already existed.
- Result: document-sequence generation failed before quotation insert with message `Missing product type code configuration for quotation type.`
## Implementation
- Added shared resolver [product-type-resolver.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-sequence/product-type-resolver.ts) to normalize and resolve:
- product-type option ids
- product-type codes
- document-sequence aliases such as `dock_door` and `solar`
- quotation-type ids/codes via reference-option translation into product-type codes
- Updated [service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-sequence/service.ts) so quotation document-sequence generation now resolves:
- `crm_quotation_type` option -> code
- code -> matching `crm_product_type`
- product type -> document sequence / prefix
- Added internal diagnostic details to failed document-sequence audit payloads:
- requested product type
- normalized requested value
- available product-type ids/codes
- available quotation-type ids/codes
- Updated [api-client.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/lib/api-client.ts) to surface backend `message`/`error` payloads instead of always throwing generic `API error: 400 Bad Request`.
## Tests
- Added [product-type-resolver.test.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-sequence/product-type-resolver.test.ts) covering:
- quotation-type id resolution
- direct code resolution
- alias resolution
- non-quotation fallback
- unresolved input handling
## Verification
- `npm exec tsc --noEmit`
- `node --import tsx --test src/features/foundation/document-sequence/config.test.ts src/features/foundation/document-sequence/product-type-resolver.test.ts`
- Live API verification against local app on `http://localhost:3000` on `2026-06-30` with authenticated UAT admin session:
- `crane` -> `CRA2606-002`
- `dockdoor` -> `DKA2606-001`
- `solarcell` -> `SCA2606-001`
- `service` -> `SVA2606-001`
## Regression Notes
- No schema changes
- No seed changes
- No duplicate `ms_options`
- No duplicate `document_sequences`
- Existing organization and branch scoping preserved
- Existing document prefix format preserved

View File

@@ -0,0 +1,63 @@
# Task P.7.1.1 Implementation Report - 2026-06-30
## Scope
- Add quotation-detail UI actions for customer package generation, preview, and download.
- Reuse existing assembled PDF foundation from Task P.7 instead of creating a new document flow.
- Expose package status and included-document metadata in quotation detail.
## Review Summary
Reviewed before implementation:
- [AGENTS.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/AGENTS.md)
- [docs/standards/project-foundations.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/project-foundations.md)
- [docs/standards/architecture-rules.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/architecture-rules.md)
- [docs/standards/ui-ux-rules.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/ui-ux-rules.md)
- [docs/standards/task-review-checklist.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/task-review-checklist.md)
- [docs/standards/task-catalog.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/standards/task-catalog.md)
- [docs/business/crm-terminology.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/business/crm-terminology.md)
- [docs/implementation/task-p.7-implementation.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-p.7-implementation.md)
- [docs/implementation/task-p.7.1-implementation.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/docs/implementation/task-p.7.1-implementation.md)
- [plans/task-p.7.1.1.md](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/plans/task-p.7.1.1.md)
Foundations reused:
- assembled quotation package generation and retrieval from [src/features/foundation/document-assembly/server/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-assembly/server/service.ts)
- artifact lifecycle from [src/features/foundation/document-artifact/server/service.ts](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/foundation/document-artifact/server/service.ts)
- quotation detail page and React Query integration from [src/features/crm/quotations/components/quotation-detail.tsx](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/components/quotation-detail.tsx)
## Implementation
- Added `POST` alias on [assembled-pdf route](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/api/crm/quotations/[id]/assembled-pdf/route.ts) so the UI can call `POST /api/crm/quotations/[id]/assembled-pdf` exactly as the task specified while preserving the existing generate handler implementation.
- Extended quotation detail payload in [quotation types](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/api/types.ts) and [quotation server service](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/server/service.ts) with `customerPackage` summary metadata sourced from the active `assembled_pdf` artifact.
- Added client helpers in [quotation api service](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/api/service.ts) for:
- `generateQuotationCustomerPackage()`
- `downloadQuotationCustomerPackage()`
- Added [React Query mutation support](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/api/mutations.ts) that invalidates quotation detail/header and document queries after package generation.
- Added [customer package UI helpers](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/customer-package.ts) and [tests](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/customer-package.test.ts) for:
- package status mapping
- role labels for included documents
- business-readable error mapping for forbidden, not-generated, and missing-required-document cases
- Added quotation-detail UI in [quotation-detail.tsx](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/features/crm/quotations/components/quotation-detail.tsx):
- `Customer Package` card
- generate / regenerate action with confirmation dialog
- preview action
- blob-based download action with toast-driven errors
- generated-at / generated-by / page-count / checksum display
- included-document list and warning display
- Reused existing quotation PDF permissions in [detail page route](/C:/Users/mtpphtaps/Documents/gitea/alla-allaos-fullstack/src/app/dashboard/crm/quotations/[id]/page.tsx):
- preview customer package -> `crmQuotationPdfPreview`
- generate/download customer package -> `crmQuotationPdfDownload`
## Design Notes
- No separate package-status endpoint was added. The UI reads status from the quotation detail payload because the active assembled artifact already provides the required metadata.
- Download intentionally uses `fetch` plus `Blob` instead of a raw anchor download so API errors can be converted into business-readable toast messages.
- Warning rows are displayed as server-provided messages because they may represent optional append-document gaps, not only fatal errors.
## 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` -> FAIL on existing baseline issues unrelated to this task:
- `template-version-integrity`: `ACTIVE_VERSION_SCHEMA_DRIFT`
- `audit:pdf:integrity`: overall `FAIL`
- `topicRuntime`: `FAIL`
## Outcome
Task P.7.1.1 now gives the quotation detail page a usable customer-package workflow on top of the existing assembly foundation, including generation, preview, download, package metadata visibility, and clearer failure handling without introducing email delivery behavior.