# 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, opportunity, 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 Foundation

| Field | Details |
| --- | --- |
| Purpose | Dedicated marketing-owned lead domain, including lead identity, awareness source, marketing follow-up status, lead outcome state, and future `1 lead -> N enquiries` linkage |
| Location | `src/db/schema.ts` (`crm_leads`), `drizzle/0020_lead_foundation_schema.sql`, `drizzle/0021_worried_nebula.sql`, `src/db/seeds/foundation.seed.ts`, `docs/adr/0018-lead-enquiry-domain-separation.md` |
| Related tasks | Task D.5, Task D.5.1 |
| Related ADRs | ADR-0018 |
| 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 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 / Opportunity Foundation

| Field | Details |
| --- | --- |
| 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 | `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_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 | `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

| 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 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 | `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 opportunity 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()`, `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

- `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
- CRM lead split-domain migration: Lead Foundation, Lead / Enquiry Foundation, Won / Lost Governance Foundation, Authorization Foundation, Reporting Foundation, Dashboard 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

## Date & Time Formatting Rules

- All date and time rendering must use the shared formatter in `src/lib/date-format.ts`.
- Never use `Date.prototype.toLocaleString()`, `toLocaleDateString()`, `toLocaleTimeString()`, or `Intl.DateTimeFormat()` directly inside React components.
- UI date display standard:
  - Date: `YYYY-MM-DD`
  - DateTime: `YYYY-MM-DD HH:mm:ss`
  - Time: `HH:mm:ss`
- API responses must remain ISO-8601 UTC.
- UI is responsible for formatting.
- Timezone is fixed to `Asia/Bangkok`.
- Calendar system must always use Gregorian (AD), never Buddhist Era (BE).
- All formatting must be deterministic to ensure identical SSR and Client rendering and prevent React hydration mismatches.
