task-d5.5.1

This commit is contained in:
phaichayon
2026-06-25 12:16:41 +07:00
parent f2c7156851
commit c2a74b6764
121 changed files with 3407 additions and 2679 deletions

View File

@@ -113,7 +113,7 @@ If ADR coverage is incomplete, this registry marks the gap explicitly.
| Related ADRs | ADR-0006. Governance gap: no dedicated ADR yet for numbering policy or reset policy. |
| Reusable services | `listDocumentSequences()`, `getDocumentSequence()`, `createDocumentSequence()`, `updateDocumentSequence()`, `resetDocumentSequence()`, `previewDocumentSequenceById()`, `previewNextDocumentCode()`, `generateNextDocumentCode()` |
| Reusable APIs | `/api/crm/settings/document-sequences`, `/api/crm/settings/document-sequences/[id]`, `/api/crm/settings/document-sequences/[id]/preview`, `/api/crm/settings/document-sequences/[id]/reset` |
| Reuse status | Reusable and active. Current production source for customer, contact, enquiry, quotation, and approval codes. |
| Reuse status | Reusable and active. Current production source for customer, contact, opportunity, quotation, and approval codes. |
### Document Template Foundation
@@ -247,31 +247,31 @@ If ADR coverage is incomplete, this registry marks the gap explicitly.
| Reusable services | None production-ready yet. D.5.1 only stabilizes schema and seed foundations before D.5.2 API work. |
| Reusable APIs | None yet. Lead API surface is explicitly deferred to Task D.5.2. |
| Reuse status | Foundation introduced and partially stabilized. Schema and seed contracts exist, but feature services, APIs, UI, migration flows, and separated datasets are not complete yet. |
| Governance note | This foundation supersedes the long-term direction of the old single-record lead/enquiry model in ADR-0011, but current production behavior still largely runs on the shared `crm_enquiries` implementation until later D.5 phases are completed. |
| Governance note | This foundation supersedes the old shared lead/enquiry model in ADR-0011. After Task D.5.5.1, active sales execution behavior runs on the renamed `crm_opportunities` implementation while older ADRs and implementation notes remain historical references. |
### Lead / Enquiry Foundation
### Lead / Opportunity Foundation
| Field | Details |
| --- | --- |
| Purpose | Single-record `crm_enquiries` lifecycle with marketing-owned leads, sales-owned enquiries, assignment governance, related project parties, and follow-up child resources |
| Location | `src/features/crm/enquiries/**`, `src/app/api/crm/enquiries/**`, `docs/adr/0011-lead-enquiry-ownership-model.md` |
| Purpose | Shared opportunity lifecycle with linked lead provenance, assignment governance, related project parties, and follow-up child resources |
| Location | `src/features/crm/opportunities/**`, `src/app/api/crm/opportunities/**`, `docs/adr/0011-lead-enquiry-ownership-model.md`, `docs/implementation/task-d551-force-rename-enquiry-domain-opportunity.md` |
| Related tasks | Task D, Task D.1, Task D.3, Task D.3.1 |
| Related ADRs | ADR-0011, ADR-0014 |
| Reusable services | `getEnquiryReferenceData()`, `listEnquiries()`, `getEnquiryDetail()`, `createEnquiry()`, `updateEnquiry()`, `softDeleteEnquiry()`, `assignEnquiryToUser()`, `reassignEnquiryToUser()`, `listEnquiryProjectParties()` |
| Reusable APIs | `/api/crm/enquiries`, `/api/crm/enquiries/[id]`, `/api/crm/enquiries/[id]/assign`, `/api/crm/enquiries/[id]/reassign`, `/api/crm/enquiries/[id]/customers` |
| Reuse status | Reusable and active. This is the source of truth for lead versus enquiry separation. |
| Governance note | ADR-0018 introduces the target split-domain direction, but this shared enquiry foundation still describes the active production service layer until D.5 migration phases complete. |
| Reusable services | `getOpportunityReferenceData()`, `listOpportunities()`, `getOpportunityDetail()`, `createOpportunity()`, `updateOpportunity()`, `softDeleteOpportunity()`, `assignOpportunityToUser()`, `reassignOpportunityToUser()`, `listOpportunityProjectParties()` |
| Reusable APIs | `/api/crm/opportunities`, `/api/crm/opportunities/[id]`, `/api/crm/opportunities/[id]/assign`, `/api/crm/opportunities/[id]/reassign`, `/api/crm/opportunities/[id]/customers` |
| Reuse status | Reusable and active. This is the source of truth for the sales opportunity domain. |
| Governance note | Historical ADR/task lineage may still say `enquiry`, but active application code, APIs, and schema were force-renamed to `opportunity` in Task D.5.5.1. |
### Won / Lost Governance Foundation
| Field | Details |
| --- | --- |
| Purpose | Freeze business outcome lifecycle on `crm_enquiries`, including PO capture, lost reason governance, and reopen rules |
| Location | `src/features/crm/enquiries/**`, `src/app/api/crm/enquiries/[id]/mark-won/route.ts`, `src/app/api/crm/enquiries/[id]/mark-lost/route.ts`, `src/app/api/crm/enquiries/[id]/reopen/route.ts` |
| Purpose | Freeze business outcome lifecycle on `crm_opportunities`, including PO capture, lost reason governance, and reopen rules |
| Location | `src/features/crm/opportunities/**`, `src/app/api/crm/opportunities/[id]/mark-won/route.ts`, `src/app/api/crm/opportunities/[id]/mark-lost/route.ts`, `src/app/api/crm/opportunities/[id]/reopen/route.ts` |
| Related tasks | Task D.4, Task J, Task K |
| Related ADRs | ADR-0016 |
| Reusable services | `markEnquiryAsWon()`, `markEnquiryAsLost()`, `reopenLostEnquiry()`, PO attachment helpers under enquiry service |
| Reusable APIs | `/api/crm/enquiries/[id]/mark-won`, `/api/crm/enquiries/[id]/mark-lost`, `/api/crm/enquiries/[id]/reopen`, `/api/crm/enquiries/[id]/po-attachments` |
| Reusable services | `markOpportunityAsWon()`, `markOpportunityAsLost()`, `reopenLostOpportunity()`, PO attachment helpers under opportunity service |
| Reusable APIs | `/api/crm/opportunities/[id]/mark-won`, `/api/crm/opportunities/[id]/mark-lost`, `/api/crm/opportunities/[id]/reopen`, `/api/crm/opportunities/[id]/po-attachments` |
| Reuse status | Reusable and active. Mandatory for outcome transitions and outcome-driven KPI/report work. |
### Quotation Foundation
@@ -328,14 +328,14 @@ If ADR coverage is incomplete, this registry marks the gap explicitly.
| Field | Details |
| --- | --- |
| Purpose | Shared follow-up tracking across enquiries and quotations, including list/detail child resources, dashboard analytics, and report visibility |
| Location | `src/features/crm/enquiries/**`, `src/features/crm/quotations/**`, `src/features/crm/dashboard/**`, `src/features/crm/reports/server/datasets/pipeline-report.dataset.ts` |
| Purpose | Shared follow-up tracking across opportunities and quotations, including list/detail child resources, dashboard analytics, and report visibility |
| Location | `src/features/crm/opportunities/**`, `src/features/crm/quotations/**`, `src/features/crm/dashboard/**`, `src/features/crm/reports/server/datasets/pipeline-report.dataset.ts` |
| Related tasks | Task D, Task E, Task J, Task K |
| Related ADRs | ADR-0011, ADR-0016, ADR-0017 |
| Reusable services | `listEnquiryFollowups()`, `createEnquiryFollowup()`, `updateEnquiryFollowup()`, `softDeleteEnquiryFollowup()`, quotation follow-up mutation and query flows under `src/features/crm/quotations/server/service.ts`, dashboard follow-up analytics in `getCrmDashboardData()` |
| Reusable APIs | `/api/crm/enquiries/[id]/followups`, `/api/crm/enquiries/[id]/followups/[followupId]`, `/api/crm/quotations/[id]/followups` |
| Reusable services | `listOpportunityFollowups()`, `createOpportunityFollowup()`, `updateOpportunityFollowup()`, `softDeleteOpportunityFollowup()`, quotation follow-up mutation and query flows under `src/features/crm/quotations/server/service.ts`, dashboard follow-up analytics in `getCrmDashboardData()` |
| Reusable APIs | `/api/crm/opportunities/[id]/followups`, `/api/crm/opportunities/[id]/followups/[followupId]`, `/api/crm/quotations/[id]/followups` |
| Reuse status | Active but fragmented. |
| Governance gap | There is no single shared standalone follow-up server foundation yet. Reuse existing enquiry and quotation follow-up services rather than building a third implementation. |
| Governance gap | There is no single shared standalone follow-up server foundation yet. Reuse existing opportunity and quotation follow-up services rather than building a third implementation. |
### Reporting Foundation
@@ -345,8 +345,8 @@ If ADR coverage is incomplete, this registry marks the gap explicitly.
| Location | `src/features/crm/reports/**`, `src/app/api/crm/reports/**`, `docs/adr/0017-report-foundation.md` |
| Related tasks | Task K.1, Task K.2 |
| Related ADRs | ADR-0010, ADR-0011, ADR-0016, ADR-0017 |
| Reusable services | `buildResolvedReportContext()`, `getCrmReportsResponse()`, `getCrmReportCatalogResponse()`, `getCrmReportFiltersResponse()`, `getCrmPipelineReportResponse()`, `getCrmLeadAgingReportResponse()`, `getCrmEnquiryAgingReportResponse()`, `buildSharedReportFilters()`, export helpers in `server/exports/service.ts` |
| Reusable APIs | `/api/crm/reports`, `/api/crm/reports/catalog`, `/api/crm/reports/filters`, `/api/crm/reports/pipeline`, `/api/crm/reports/lead-aging`, `/api/crm/reports/enquiry-aging`, `/api/crm/reports/export` |
| Reusable services | `buildResolvedReportContext()`, `getCrmReportsResponse()`, `getCrmReportCatalogResponse()`, `getCrmReportFiltersResponse()`, `getCrmPipelineReportResponse()`, `getCrmLeadAgingReportResponse()`, `getCrmOpportunityAgingReportResponse()`, `buildSharedReportFilters()`, export helpers in `server/exports/service.ts` |
| Reusable APIs | `/api/crm/reports`, `/api/crm/reports/catalog`, `/api/crm/reports/filters`, `/api/crm/reports/pipeline`, `/api/crm/reports/lead-aging`, `/api/crm/reports/opportunity-aging`, `/api/crm/reports/export` |
| Reuse status | Reusable and active. Mandatory for new CRM reports and exports. |
## Governance Gaps And Duplication Risks