commit
This commit is contained in:
364
docs/standards/project-foundations.md
Normal file
364
docs/standards/project-foundations.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# Project Foundations
|
||||
|
||||
This registry is the single source of truth for reusable foundations in ALLA OS.
|
||||
|
||||
Review this file before creating new services, routes, exports, scopes, approvals, PDFs, reports, dashboard analytics, CRM follow-up flows, or authorization logic.
|
||||
|
||||
If a requested behavior fits one of the foundations below, extend that foundation first. Creating a parallel implementation path requires an explicit rationale in the task contract.
|
||||
|
||||
## How To Use This Registry
|
||||
|
||||
Review order for non-trivial work:
|
||||
|
||||
1. `AGENTS.md`
|
||||
2. `docs/standards/architecture-rules.md`
|
||||
3. `docs/standards/ui-ux-rules.md`
|
||||
4. relevant `docs/adr/**`
|
||||
5. relevant `docs/business/**`
|
||||
6. the reusable foundations in this registry
|
||||
7. existing feature implementations and route handlers that already consume the foundation
|
||||
|
||||
For each candidate foundation, answer:
|
||||
|
||||
1. Is it reusable for the requested task?
|
||||
2. Is it actively used by production CRM routes or pages?
|
||||
3. Is similar logic duplicated elsewhere?
|
||||
4. Is it governed by one or more ADRs?
|
||||
5. Will a future AI agent discover it easily from this registry?
|
||||
|
||||
If ADR coverage is incomplete, this registry marks the gap explicitly.
|
||||
|
||||
## Registry Inventory
|
||||
|
||||
### Auth Context Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Normalize current-user access to app-owned user and session context before downstream foundation or feature logic runs |
|
||||
| Location | `src/features/foundation/auth-context/**`, `src/lib/auth/session.ts`, `src/auth.ts` |
|
||||
| Related tasks | Task B, Task D.1, Task L |
|
||||
| Related ADRs | None dedicated. Governance gap: still governed mainly by `AGENTS.md`, `architecture-rules.md`, and the Auth.js app-owned auth model rather than a dedicated ADR. |
|
||||
| Reusable services | `getCurrentUser()`, `requireCurrentUser()`, `getCurrentUserContext()` |
|
||||
| Reusable APIs | No standalone API. Reused by downstream route handlers and services. |
|
||||
| Reuse status | Reusable and active. Foundation-safe helper layer. |
|
||||
|
||||
### Organization Context Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Resolve active organization and enforce organization-scoped access for app-owned multi-tenant flows |
|
||||
| Location | `src/features/foundation/organization-context/**`, `src/lib/auth/session.ts` |
|
||||
| Related tasks | Task B lineage, Tasks C-L |
|
||||
| Related ADRs | None dedicated. Governance gap: core organization-context rules are implementation-backed but not frozen in a dedicated ADR. |
|
||||
| Reusable services | `getCurrentOrganization()`, `getActiveOrganizationId()`, `requireOrganizationAccess()` |
|
||||
| Reusable APIs | No standalone API. Reused by nearly all CRM route handlers. |
|
||||
| Reuse status | Reusable and active. Mandatory for organization-scoped server work. |
|
||||
|
||||
### Permission Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Shared permission and compatibility role checks outside CRM resolved-access unions |
|
||||
| Location | `src/features/foundation/permission/**`, `src/lib/auth/rbac.ts` |
|
||||
| Related tasks | Task B lineage, Task L, Task J.1 |
|
||||
| Related ADRs | ADR-0014 is related for CRM permissions, but there is no dedicated ADR for the lower-level permission helper layer itself. |
|
||||
| Reusable services | `hasPermission()`, `requirePermission()`, `hasBusinessRole()` |
|
||||
| Reusable APIs | No standalone API. Consumed by route handlers and settings surfaces. |
|
||||
| Reuse status | Reusable and active. Do not replace with route-local permission helpers. |
|
||||
|
||||
### Branch Scope Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Shared branch lookup and branch access validation while branch remains option-backed rather than a first-class domain table |
|
||||
| Location | `src/features/foundation/branch-scope/**`, `docs/adr/ADR-0006-branch-domain-model.md` |
|
||||
| Related tasks | Task B, Task B.1, Tasks D-L |
|
||||
| Related ADRs | ADR-0006 |
|
||||
| Reusable services | `getUserBranches()`, `getActiveBranch()`, `validateBranchAccess()` |
|
||||
| Reusable APIs | No standalone API. Used by CRM services and sequence generation flows. |
|
||||
| Reuse status | Reusable and active. Governance note: branch is still abstraction-backed, so future branch-domain work must preserve compatibility. |
|
||||
|
||||
### Audit Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Central audit persistence and naming pattern for create, update, delete, action, export, and security-denial events |
|
||||
| Location | `src/features/foundation/audit-log/**`, `tr_audit_logs`, `drizzle/0001_orange_mandarin.sql` |
|
||||
| Related tasks | Task B lineage and all downstream CRM tasks |
|
||||
| Related ADRs | None dedicated. Governance gap: audit behavior is widely reused but still lacks a dedicated ADR. |
|
||||
| Reusable services | `auditAction()`, `auditCreate()`, `auditUpdate()`, `auditDelete()`, `listAuditLogs()` |
|
||||
| Reusable APIs | No standalone public audit API required for reuse. Consumed from route handlers and service layers. |
|
||||
| Reuse status | Reusable and active. Mandatory for new CRM mutations, exports, and security denials. |
|
||||
|
||||
### Master Data Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Centralized option and category management for CRM labels, statuses, branches, lost reasons, job titles, project-party roles, report categories, and other governed select data |
|
||||
| Location | `src/features/foundation/master-options/**`, `src/app/api/foundation/master-options/route.ts`, `ms_options`, `src/db/seeds/foundation.seed.ts` |
|
||||
| Related tasks | Task B, Task B.1, Hotfix 1, Task D, Task D.4, Task J.1, Task K.1 |
|
||||
| Related ADRs | ADR-0006, ADR-0012, ADR-0016, ADR-0017 |
|
||||
| Reusable services | `listMasterOptions()`, `getOptionsByCategory()`, `getActiveOptionsByCategory()` |
|
||||
| Reusable APIs | `/api/foundation/master-options` |
|
||||
| Reuse status | Reusable and active. Option hierarchy is already live through `parentId` and is required for categories such as `crm_customer_group` -> `crm_customer_sub_group`. |
|
||||
| Governed examples | `crm_customer_group`, `crm_customer_sub_group`, `crm_lost_reason`, `crm_job_title`, `crm_project_party_role`, `crm_quotation_type`, `crm_report_category` |
|
||||
|
||||
### Document Sequence Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Centralized document numbering across CRM entities, including preview, reset, branch-aware period scoping, and organization scoping |
|
||||
| Location | `src/features/foundation/document-sequence/**`, `document_sequences`, `src/app/api/crm/settings/document-sequences/**` |
|
||||
| Related tasks | Task B, Task B.1, Task D, Task E, Task F, Task J.1 |
|
||||
| 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. |
|
||||
|
||||
### Document Template Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Template metadata, versioning, placeholder mapping, table-column mapping, document resolution, and activation flow for governed document rendering |
|
||||
| Location | `src/features/foundation/document-template/**`, `src/app/api/crm/document-templates/**`, `src/app/api/crm/settings/document-templates/**`, `crm_document_templates*` tables |
|
||||
| Related tasks | Task G, Task H, Task H.3, Task H.5, Task J.1 |
|
||||
| Related ADRs | ADR-0012, ADR-0013 |
|
||||
| Reusable services | `listDocumentTemplates()`, `getDocumentTemplate()`, `listDocumentTemplateVersions()`, `createDocumentTemplate()`, `updateDocumentTemplate()`, `createDocumentTemplateVersion()`, `updateDocumentTemplateVersion()`, `setDocumentTemplateVersionActive()`, `createDocumentTemplateMapping()`, `updateDocumentTemplateMapping()`, `deleteDocumentTemplateMapping()`, `resolveTemplateForDocument()`, `resolveTemplateMappings()`, `mapDocumentDataToTemplateInput()` |
|
||||
| Reusable APIs | `/api/crm/document-templates`, `/api/crm/document-templates/[id]`, `/api/crm/document-templates/[id]/versions`, `/api/crm/settings/document-templates`, `/api/crm/settings/document-templates/[id]`, `/api/crm/settings/document-templates/[id]/versions`, `/api/crm/settings/document-templates/versions/[id]`, `/api/crm/settings/document-templates/versions/[id]/mappings`, `/api/crm/settings/document-templates/mappings/[id]` |
|
||||
| Reuse status | Reusable and active. This is the only approved path for template versions, template mappings, and version activation. |
|
||||
|
||||
### Approval Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Shared approval workflow, step handling, current-actor resolution, request history, and document lifecycle integration |
|
||||
| Location | `src/features/foundation/approval/**`, `src/app/api/crm/approvals/**`, `src/app/api/crm/settings/approval-workflows/**` |
|
||||
| Related tasks | Task F, Task H.3, Task J.1, Task L.3, Task L.3.1 |
|
||||
| Related ADRs | ADR-0007, ADR-0012, ADR-0014 |
|
||||
| Reusable services | `listApprovalWorkflows()`, `getApprovalWorkflow()`, `createApprovalWorkflow()`, `updateApprovalWorkflow()`, `replaceApprovalWorkflowSteps()`, `listApprovalRequests()`, `getApprovalRequest()`, `getApprovalTimeline()`, `getCurrentApprovalStep()`, `submitForApproval()`, `approveApproval()`, `rejectApproval()`, `returnApproval()`, `cancelApproval()` |
|
||||
| Reusable APIs | `/api/crm/approvals`, `/api/crm/approvals/[id]`, `/api/crm/approvals/[id]/approve`, `/api/crm/approvals/[id]/reject`, `/api/crm/approvals/[id]/return`, `/api/crm/quotations/[id]/submit-approval`, `/api/crm/settings/approval-workflows`, `/api/crm/settings/approval-workflows/[id]`, `/api/crm/settings/approval-workflows/[id]/steps` |
|
||||
| Reuse status | Reusable and active. Mandatory for approval workflows and approval analytics. |
|
||||
|
||||
### Storage Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Provider abstraction for local versus S3-compatible object storage plus organization-safe storage key building |
|
||||
| Location | `src/features/foundation/storage/**`, ADR-0008, ADR-0009 |
|
||||
| Related tasks | Task I |
|
||||
| Related ADRs | ADR-0008, ADR-0009 |
|
||||
| Reusable services | `getStorageProvider()`, `buildOrganizationStorageKey()`, local and S3 provider implementations under `server/` |
|
||||
| Reusable APIs | No standalone direct upload API yet. Reused through artifact and PDF foundations. |
|
||||
| Reuse status | Reusable and active. Required for approved-document binary storage. |
|
||||
|
||||
### Document Artifact Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Database-backed artifact metadata, locking, voiding, checksum tracking, and secure download behavior |
|
||||
| Location | `src/features/foundation/document-artifact/**`, `src/app/api/crm/document-artifacts/[id]/download/route.ts`, `crm_document_artifacts` |
|
||||
| Related tasks | Task I |
|
||||
| Related ADRs | ADR-0009 |
|
||||
| Reusable services | `createArtifact()`, `getArtifact()`, `getActiveArtifactForEntity()`, `lockArtifact()`, `voidArtifact()`, `deleteArtifactMetadataOnly()`, `downloadArtifact()` |
|
||||
| Reusable APIs | `/api/crm/document-artifacts/[id]/download` |
|
||||
| Reuse status | Reusable and active. Required for immutable approved-document delivery. |
|
||||
|
||||
### PDF Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Shared PDF generation, preview payload building, dynamic topic expansion, signature resolution, approved snapshot preparation, and approved PDF persistence handoff |
|
||||
| Location | `src/features/foundation/pdf-generator/**`, `src/features/crm/quotations/document/**`, `docs/business/pdf-mapping-registry.md`, `docs/business/pdf-placeholder-registry.md` |
|
||||
| Related tasks | Task G, Task H, Task H.1, Task H.2, Task H.3, Task H.5, Task I |
|
||||
| Related ADRs | ADR-0009, ADR-0012, ADR-0013 |
|
||||
| Reusable services | `buildQuotationDocumentData()`, `getQuotationDocumentPreviewData()`, `prepareApprovedQuotationSnapshot()`, `resolveQuotationSignatures()`, `getSignaturePositionLookup()`, `generateQuotationPdf()`, `generateApprovedQuotationPdf()`, `getStoredApprovedQuotationPdf()` |
|
||||
| Reusable APIs | `/api/crm/quotations/[id]/document-data`, `/api/crm/quotations/[id]/document-preview`, `/api/crm/quotations/[id]/pdf-preview`, `/api/crm/quotations/[id]/pdf-download`, `/api/crm/quotations/[id]/approved-pdf` |
|
||||
| Reuse status | Reusable and active. This is the only approved rendering path for quotation PDFs. |
|
||||
|
||||
### Role Management Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | CRM role-profile management, permission matrices, approval authority, scope defaults, and effective-access design-time governance |
|
||||
| Location | `src/features/foundation/role-management/**`, `src/app/api/crm/settings/roles/**`, `src/lib/auth/rbac.ts` |
|
||||
| Related tasks | Task L, Task L.2 |
|
||||
| Related ADRs | ADR-0014 |
|
||||
| Reusable services | `ensureCrmRoleProfiles()`, `listCrmRoleProfiles()`, `getCrmRoleProfileByCode()`, `updateCrmRoleProfile()`, `cloneCrmRoleProfile()` |
|
||||
| Reusable APIs | `/api/crm/settings/roles`, `/api/crm/settings/roles/[code]`, `/api/crm/settings/roles/[code]/clone` |
|
||||
| Reuse status | Reusable and active. Must be extended instead of inventing feature-local permission systems. |
|
||||
|
||||
### CRM Role Assignment Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Multi-role assignment persistence, compatibility backfill, user-level scope unioning, and assignment reference data |
|
||||
| Location | `src/features/foundation/crm-role-assignments/**`, `src/app/api/crm/settings/user-role-assignments/**`, `src/app/api/users/crm-role-assignment-reference/route.ts` |
|
||||
| Related tasks | Task L.1, Task L.2 |
|
||||
| Related ADRs | ADR-0014 |
|
||||
| Reusable services | `ensureCrmRoleAssignmentsBackfillForMembership()`, `ensureCrmRoleAssignmentsBackfillForOrganization()`, `listResolvedCrmRoleAssignments()`, `createCrmUserRoleAssignment()`, `updateCrmUserRoleAssignment()`, `deleteCrmUserRoleAssignment()`, `listCrmRoleAssignmentsForUser()`, `getRoleAssignmentReferenceSummaries()` |
|
||||
| Reusable APIs | `/api/crm/settings/user-role-assignments`, `/api/crm/settings/user-role-assignments/[id]`, `/api/users/crm-role-assignment-reference`, `/api/users/[id]/effective-access-preview` |
|
||||
| Reuse status | Reusable and active. Treat this as part of the authorization foundation, not as a separate ad hoc admin feature. |
|
||||
|
||||
### Authorization Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Resolve CRM permissions, branch scope, product scope, ownership scope, pricing visibility, and approval authority from membership plus CRM role assignments |
|
||||
| Location | `src/lib/auth/crm-access.ts`, `src/lib/auth/session.ts`, `src/features/crm/security/**`, `docs/security/**` |
|
||||
| Related tasks | Task L, Task L.1, Task L.2, Task L.3, Task L.3.1 |
|
||||
| Related ADRs | ADR-0014, ADR-0015, ADR-0017 |
|
||||
| Reusable services | `resolveCrmMembershipAccess()`, `resolveCrmAccess()`, `buildCrmSecurityContext()`, `canViewQuotationPricing()`, `canAccessScopedCrmRecord()`, `canAccessCustomer()`, `canAccessContact()`, `auditCrmSecurityEvent()` |
|
||||
| Reusable APIs | Authorization is enforced across CRM route handlers rather than through a standalone API |
|
||||
| Reuse status | Reusable and active. Mandatory for CRM scope-sensitive server work. |
|
||||
|
||||
### Customer Ownership Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Persistent customer owner assignment, owner history, owner-aware visibility, and owner-based lead suggestion |
|
||||
| Location | `src/features/crm/customers/**`, `src/app/api/crm/customers/**`, `docs/adr/0015-customer-ownership-contact-sharing.md` |
|
||||
| Related tasks | Task C, Task C.1, Task L.3.1 |
|
||||
| Related ADRs | ADR-0015 |
|
||||
| Reusable services | customer services under `src/features/crm/customers/server/service.ts`, especially owner-aware customer detail, owner mutation, and related customer visibility helpers |
|
||||
| Reusable APIs | `/api/crm/customers`, `/api/crm/customers/[id]`, `/api/crm/customers/[id]/owner` |
|
||||
| Reuse status | Reusable and active. Use this before inventing territory or manual owner mirrors. |
|
||||
|
||||
### Contact Sharing Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Persistent contact-level sharing and share-aware contact visibility without mock/demo fallbacks |
|
||||
| Location | `src/features/crm/customers/**`, `src/app/api/crm/customers/[id]/contacts/[contactId]/shares/**`, `docs/security/crm-authorization-boundaries.md` |
|
||||
| Related tasks | Task C.1, Task L.3.1 |
|
||||
| Related ADRs | ADR-0015 |
|
||||
| Reusable services | contact visibility logic in `src/features/crm/customers/server/service.ts`, `canAccessContact()`, and contact share mutation flows with audit integration |
|
||||
| Reusable APIs | `/api/crm/customers/[id]/contacts`, `/api/crm/customers/[id]/contacts/[contactId]/shares`, `/api/crm/customers/[id]/contacts/[contactId]/shares/[shareId]` |
|
||||
| Reuse status | Reusable and active. |
|
||||
| Governance note | `docs/implementation/task-l31-customer-contact-approval-visibility.md` contains an outdated limitation stating persisted contact sharing does not exist. Treat ADR-0015 and Task C.1 as the current source of truth. |
|
||||
|
||||
### Lead / Enquiry 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` |
|
||||
| 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. |
|
||||
|
||||
### 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` |
|
||||
| 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` |
|
||||
| Reuse status | Reusable and active. Mandatory for outcome transitions and outcome-driven KPI/report work. |
|
||||
|
||||
### Quotation Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Production quotation CRUD, revision, pricing, item/customer/topic/follow-up child resources, document preview entry points, and approval integration |
|
||||
| Location | `src/features/crm/quotations/**`, `src/app/api/crm/quotations/**` |
|
||||
| Related tasks | Task E, Task E.1, Task F, Task G, Task H, Task I |
|
||||
| Related ADRs | ADR-0007, ADR-0008, ADR-0012, ADR-0013 |
|
||||
| Reusable services | quotation services under `src/features/crm/quotations/server/service.ts`, quotation document services under `src/features/crm/quotations/document/server/service.ts` |
|
||||
| Reusable APIs | `/api/crm/quotations`, `/api/crm/quotations/[id]`, `/items`, `/customers`, `/topics`, `/followups`, `/attachments`, `/revisions`, `/submit-approval`, document and PDF child routes |
|
||||
| Reuse status | Reusable and active. Extend this foundation instead of creating quotation-adjacent custom flows. |
|
||||
|
||||
### Revenue Attribution Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Freeze revenue-owner attribution and project-party analytics so dashboard, reports, and exports share one rule set |
|
||||
| Location | `src/features/crm/reporting/**`, `src/features/crm/shared/project-party.ts`, dashboard and report services |
|
||||
| Related tasks | Task D.2, Task D.2.1, Task J, Task K |
|
||||
| Related ADRs | ADR-0010 |
|
||||
| Reusable services | `getRevenueByEndCustomer()`, `getRevenueByBillingCustomer()`, `getRevenueByContractor()`, `getRevenueByConsultant()`, `getWonRevenue()`, `getLostRevenue()`, `getLostByReason()`, `getLostByCompetitor()`, `getWinRate()` |
|
||||
| Reusable APIs | No standalone direct API. Reused by `/api/crm/dashboard`, `/api/crm/dashboard/export`, and `/api/crm/reports/**` routes. |
|
||||
| Reuse status | Reusable and active. |
|
||||
| Governance note | The helper layer currently lives under `src/features/crm/reporting/**` while the formal report foundation lives under `src/features/crm/reports/**`. This is a discoverability risk, not a reason to duplicate the analytics logic. |
|
||||
|
||||
### Dashboard Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Operational KPI monitoring, approval widgets, follow-up analytics, sales ranking, revenue analytics, and dashboard export behavior |
|
||||
| Location | `src/features/crm/dashboard/**`, `src/app/api/crm/dashboard/**` |
|
||||
| Related tasks | Task J, Task UX.1, Task L.3 |
|
||||
| Related ADRs | ADR-0010, ADR-0011, ADR-0016 |
|
||||
| Reusable services | `getCrmDashboardData()` plus its reuse of revenue attribution helpers, approval listing, follow-up aggregation, and pricing-visibility enforcement |
|
||||
| Reusable APIs | `/api/crm/dashboard`, `/api/crm/dashboard/export` |
|
||||
| Reuse status | Reusable and active. This is the approved dashboard KPI foundation. |
|
||||
|
||||
### CRM Form Design Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Shared CRM form controls, field wrappers, date and numeric formatting behavior, select trigger sizing, textarea sizing, and filter-bar consistency across CRM pages and dialogs |
|
||||
| Location | `src/features/crm/components/crm-form-controls.tsx`, `src/features/crm/shared/formats.ts`, `src/components/forms/fields/**`, `src/components/ui/select.tsx`, `src/features/crm/dashboard/components/dashboard-filters.tsx`, `src/features/crm/reports/components/report-filter-bar.tsx` |
|
||||
| Related tasks | Task UX.1, Task UX.2 |
|
||||
| Related ADRs | None dedicated. Governance gap: form-system behavior is currently standardized by task lineage and this registry rather than a dedicated ADR. |
|
||||
| Reusable services | `formatCrmDate()`, `formatCrmNumber()`, `sanitizeDecimalInput()` |
|
||||
| Reusable components | `CrmDateInput`, `CrmNumberInput`, `CrmCurrencyInput`, `CrmPercentageInput`, `CrmTextarea`, `FormDatePickerField`, `FormCurrencyField`, `FormPercentageField`, `FormTextareaField` |
|
||||
| Reusable APIs | No standalone API. Reused by CRM forms, dialogs, and filter bars. |
|
||||
| Reuse status | Reusable and active. Extend this foundation before creating route-local date, number, currency, percentage, textarea, or select-trigger behavior. |
|
||||
|
||||
### Follow-Up Foundation
|
||||
|
||||
| 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` |
|
||||
| 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` |
|
||||
| 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. |
|
||||
|
||||
### Reporting Foundation
|
||||
|
||||
| Field | Details |
|
||||
| --- | --- |
|
||||
| Purpose | Shared report registry, filter metadata, resolved report context, dataset layer, builder layer, and export helpers |
|
||||
| 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` |
|
||||
| Reuse status | Reusable and active. Mandatory for new CRM reports and exports. |
|
||||
|
||||
## Governance Gaps And Duplication Risks
|
||||
|
||||
- `master-options`, `document-sequence`, `document-template`, `dashboard`, and `follow-up` were present in code but missing from the old registry. This document now treats them as first-class foundations.
|
||||
- The low-level access helpers (`auth-context`, `organization-context`, `permission`, `audit-log`) are production foundations but still lack dedicated ADR coverage.
|
||||
- `src/features/crm/reporting/**` and `src/features/crm/reports/**` are complementary, but their names are easy to confuse:
|
||||
- `reporting/**` is the reusable analytics helper layer.
|
||||
- `reports/**` is the governed report platform and API layer.
|
||||
- Follow-up behavior is reusable, but the implementation is fragmented across enquiry and quotation modules. Do not create another follow-up subsystem.
|
||||
- `docs/implementation/task-l31-customer-contact-approval-visibility.md` contains a superseded note about missing persisted contact sharing. Current truth is ADR-0015 plus Task C.1.
|
||||
- `crm settings` APIs for document templates and sequences are permission-gated, but `docs/security/crm-access-enforcement-inventory.md` still marks them as only partially audited against the full scope matrix.
|
||||
|
||||
## Foundations That Must Be Checked By Topic
|
||||
|
||||
- Approvals: Approval Foundation, Authorization Foundation, Audit Foundation, PDF Foundation
|
||||
- CRM leads and enquiries: Lead / Enquiry Foundation, Won / Lost Governance Foundation, Follow-Up Foundation, Authorization Foundation
|
||||
- Customers and contacts: Customer Ownership Foundation, Contact Sharing Foundation, Authorization Foundation
|
||||
- Dashboard analytics: Dashboard Foundation, Revenue Attribution Foundation, Follow-Up Foundation, Reporting Foundation
|
||||
- Forms and filters: CRM Form Design Foundation, Master Data Foundation
|
||||
- PDFs and documents: Document Template Foundation, PDF Foundation, Storage Foundation, Document Artifact Foundation
|
||||
- Reports and exports: Reporting Foundation, Revenue Attribution Foundation, Authorization Foundation, Audit Foundation
|
||||
- Settings and admin configuration: Master Data Foundation, Document Sequence Foundation, Document Template Foundation, Approval Foundation, Role Management Foundation, CRM Role Assignment Foundation
|
||||
|
||||
## Registry Outcome
|
||||
|
||||
- ALLA OS Foundation Registry = COMPLETE
|
||||
- ALLA OS Reuse Discovery = READY
|
||||
- ALLA OS Governance Quality = IMPROVED
|
||||
Reference in New Issue
Block a user