diff --git a/AGENTS.md b/AGENTS.md index 79eaa02..ea36711 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,6 +34,127 @@ Current migration status: --- +## Governance Layer + +This repository now treats governance documentation as implementation input, not optional background reading. + +Before any task that changes behavior, architecture, permissions, reporting, exports, PDFs, approvals, or CRM workflow, agents must review the relevant standards and foundations first. + +Primary governance documents: + +- `AGENTS.md` +- `docs/standards/task-contract-template.md` +- `docs/standards/task-catalog.md` +- `docs/standards/project-foundations.md` +- `docs/standards/architecture-rules.md` +- `docs/standards/ui-ux-rules.md` +- `docs/standards/task-review-checklist.md` +- `docs/adr/**` +- `docs/business/**` +- `docs/security/**` +- `docs/implementation/**` for the related feature lineage + +### Task Execution Rules + +All tasks follow these rules: + +- review first; implementation without review is prohibited +- reuse existing foundations before creating new modules, helpers, or flows +- extend existing services before creating duplicate services +- extend existing route groups before creating duplicate APIs +- extend existing permission models before creating duplicate permission systems +- extend existing export/report foundations before creating duplicate export flows +- keep business logic in feature service layers, not in route handlers or client components +- document any exception when an existing foundation cannot be reused + +Required review order for non-trivial work: + +1. `AGENTS.md` +2. `docs/standards/**` +3. relevant `docs/adr/**` +4. relevant `docs/business/**` +5. related completed tasks from `docs/standards/task-catalog.md` and `docs/implementation/**` +6. existing foundations under `src/features/foundation/**` +7. existing feature implementations under `src/features/**` +8. existing APIs under `src/app/api/**` +9. permission and access enforcement under `src/lib/auth/**`, `src/features/crm/security/**`, and `docs/security/**` +10. existing audit patterns under `src/features/foundation/audit-log/**` + +### Historical Knowledge Rule + +Before implementing any feature: + +1. review related foundations +2. review related ADRs +3. review related completed tasks from `docs/standards/task-catalog.md` +4. reuse before creating + +Implementation without historical review is prohibited. + +### Required Foundations + +The following reusable foundations are mandatory whenever the task touches their area: + +- Audit Foundation: `src/features/foundation/audit-log/**` +- Approval Foundation: `src/features/foundation/approval/**` +- Storage Foundation: `src/features/foundation/storage/**` and `src/features/foundation/document-artifact/**` +- PDF Foundation: `src/features/foundation/pdf-generator/**` and `src/features/crm/quotations/document/**` +- Report Foundation: `src/features/crm/reports/**`, `docs/adr/0017-report-foundation.md` +- CRM Authorization Foundation: `src/lib/auth/crm-access.ts`, `src/features/crm/security/**`, `docs/security/**` +- Customer Ownership Foundation: `docs/adr/0015-customer-ownership-contact-sharing.md`, `src/features/crm/customers/**` +- Contact Sharing Foundation: `docs/adr/0015-customer-ownership-contact-sharing.md`, `src/app/api/crm/customers/[id]/contacts/[contactId]/shares/**` + +If a task touches CRM leads, enquiries, quotations, approvals, reports, exports, storage, or PDFs, agents must explicitly check whether one of these foundations already solves part of the problem. + +### Architecture Constraints + +Frontend constraints: + +- Next.js App Router only +- server components first +- `PageContainer` for dashboard page headers +- shadcn/ui primitives and existing app UI wrappers +- TanStack React Query with server prefetch + `HydrationBoundary` + client `useSuspenseQuery()` for data-heavy app pages +- TanStack Form + Zod for forms +- `nuqs` for URL state +- existing CRM terminology helpers and Thai labels for business-facing CRM UI + +Backend constraints: + +- Route Handlers are the main HTTP boundary +- feature service layer owns business logic +- Drizzle ORM owns database access +- auth and organization access go through `@/auth` and `src/lib/auth/session.ts` +- CRM scope resolution goes through resolved-access helpers, not direct role-string branching +- audit logging goes through `src/features/foundation/audit-log/service.ts` + +Forbidden patterns: + +- Redux for new application state +- SWR for new server-state fetching +- React Hook Form for new forms in this repo +- direct database access from client components +- business logic inside route handlers +- new Clerk usage +- direct role-string authorization such as `if (role === 'sales')` +- report-specific export systems that bypass `src/features/crm/reports/server/exports/service.ts` + +### Mandatory Task Review + +Before implementation, every non-trivial task must review: + +- reusable foundations +- relevant ADRs +- related completed tasks from `docs/standards/task-catalog.md` +- related existing APIs +- permission and scope enforcement +- audit events and existing entity/action naming +- duplication risk across services, routes, exports, datasets, and UI shells + +Implementation without this review is prohibited. + +--- + ## Technology Stack Details ### Core Runtime @@ -516,3 +637,17 @@ Ensure these are set: 17. When deleting entities, remove stale detail queries with `removeQueries` in addition to invalidating lists. 18. If a component overrides `useMutation` callbacks on top of a shared mutation config, preserve or explicitly call the shared invalidation behavior before closing UI. 19. After successful create/update/delete, sheets, dialogs, and destructive modals must close only after cache invalidation has been triggered and the UI can refresh from fresh data. +20. Review `docs/standards/**`, relevant `docs/adr/**`, `docs/business/**`, and `docs/security/**` before implementing non-trivial changes. +21. Review related completed task notes in `docs/standards/task-catalog.md` and `docs/implementation/**` before implementing non-trivial changes. +22. Reuse foundations under `src/features/foundation/**` and `src/features/crm/**` before introducing new services, routes, permissions, exports, or datasets. +23. Do not create duplicate report/export/PDF/approval/security plumbing when a project foundation already exists. +24. CRM authorization must flow through resolved access helpers such as `resolveCrmMembershipAccess()`, `buildCrmSecurityContext()`, or report-context builders; do not authorize with raw role strings alone. + +Before implementing any task, review: +- AGENTS.md +- docs/standards/* +- docs/standards/task-catalog.md +- related ADRs +- related completed task documents + +Implementation without review is prohibited. diff --git a/docs/implementation/task-ux2-crm-form-design-system-standardization.md b/docs/implementation/task-ux2-crm-form-design-system-standardization.md new file mode 100644 index 0000000..b9a7b57 --- /dev/null +++ b/docs/implementation/task-ux2-crm-form-design-system-standardization.md @@ -0,0 +1,85 @@ +# Task UX.2: CRM Form Design System Standardization + +## Objective + +Establish one reusable CRM form design foundation for shared controls, field behaviors, filter bars, textarea sizing, and select trigger stability across the CRM surface. + +## Files Added + +- `docs/implementation/task-ux2-crm-form-design-system-standardization.md` +- `src/features/crm/shared/formats.ts` +- `src/features/crm/components/crm-form-controls.tsx` +- `src/components/forms/fields/currency-field.tsx` +- `src/components/forms/fields/percentage-field.tsx` + +## Files Modified + +- `docs/standards/project-foundations.md` +- `src/components/forms/fields/date-picker-field.tsx` +- `src/components/forms/fields/index.tsx` +- `src/components/forms/fields/textarea-field.tsx` +- `src/components/ui/select.tsx` +- `src/components/ui/tanstack-form.tsx` +- `src/features/crm/customers/components/contact-form-sheet.tsx` +- `src/features/crm/customers/components/contact-share-sheet.tsx` +- `src/features/crm/customers/components/customer-form-sheet.tsx` +- `src/features/crm/customers/components/customer-owner-card.tsx` +- `src/features/crm/dashboard/components/dashboard-filters.tsx` +- `src/features/crm/enquiries/components/enquiry-form-sheet.tsx` +- `src/features/crm/enquiries/components/enquiry-outcome-card.tsx` +- `src/features/crm/enquiries/components/followup-form-sheet.tsx` +- `src/features/crm/quotations/components/quotation-approval-tab.tsx` +- `src/features/crm/quotations/components/quotation-detail.tsx` +- `src/features/crm/quotations/components/quotation-form-sheet.tsx` +- `src/features/crm/reports/components/report-filter-bar.tsx` + +## Drift Inventory + +Before this task, CRM forms and filters had multiple inconsistent patterns: + +- raw `type="date"` inputs mixed with a calendar button pattern +- numeric commercial fields implemented as generic text or bare number inputs +- long select values stretching trigger width in customer and project-party flows +- arbitrary textarea heights across dialogs, forms, and approval panels +- report and dashboard filters using different control families from CRM forms +- manual quotation dialogs bypassing the shared TanStack field wrappers + +## Foundation Created + +New reusable CRM form foundation now standardizes: + +- date input behavior through `CrmDateInput` +- number, currency, and percentage behavior through `CrmNumberInput`, `CrmCurrencyInput`, and `CrmPercentageInput` +- textarea sizes through `CrmTextarea` with `sm | md | lg` +- display formatting helpers through `formatCrmDate()` and `formatCrmNumber()` +- TanStack form wrappers through `FormCurrencyField` and `FormPercentageField` +- select trigger width stability through the shared `SelectTrigger` primitive + +## Module Coverage + +The standardization was applied where CRM already had production form or filter surfaces: + +- Customers: customer form, contact form, owner assignment dialog, contact sharing dialog +- Enquiries and leads: enquiry form, follow-up form, outcome dialogs +- Quotations: quotation header form, approval submit panel, item/topic/follow-up/attachment dialogs +- Reports and dashboard: shared date filter behavior for dashboard and report filter bars + +## UX Decisions Frozen + +- Date selection uses a calendar picker +- User-facing date display uses `DD/MM/YYYY` +- Select triggers stay `w-full max-w-full` and truncate long selected labels +- Desktop CRM form layout remains primarily `md:grid-cols-2` +- Textareas use named sizes instead of arbitrary heights +- Report and dashboard filters reuse the same CRM date control family +- Required field display continues to use the existing label `*` indicator pattern + +## Verification + +- Ran `npm exec tsc --noEmit` +- Verified no remaining raw CRM `type="date"` or ad hoc textarea usage outside the shared CRM controls file itself + +## Remaining Notes + +- Some older dialogs still use direct `Input` for plain text fields, which is acceptable because the drift for this task was primarily around date, numeric, textarea, and select behavior. +- Several legacy files still contain mojibake in Thai strings. This task avoided rewriting business copy unless required for control standardization. diff --git a/docs/standards/architecture-rules.md b/docs/standards/architecture-rules.md new file mode 100644 index 0000000..4dc910a --- /dev/null +++ b/docs/standards/architecture-rules.md @@ -0,0 +1,160 @@ +# Architecture Rules + +These rules describe the approved implementation patterns for ALLA OS. + +New work should extend these patterns instead of inventing parallel architecture. + +## Frontend Architecture + +- Use Next.js App Router. +- Prefer server components by default. +- Use client components only for interactivity, browser APIs, or client-side state/query hooks. +- Use `PageContainer` for dashboard page headers and top-level content framing. +- Keep business-facing CRM UI aligned with `docs/business/crm-terminology.md` and `src/features/crm/shared/terminology.ts`. + +### Data Loading Pattern + +- For data-heavy dashboard/app pages, prefer server prefetch plus `HydrationBoundary`. +- Client tables and detail panes should consume prefetched data with `useSuspenseQuery()`. +- Define query options and query keys in `src/features//api/queries.ts`. +- Keep filters in URL state with `nuqs` when the page supports shareable filtering. + +Reference examples: + +- `src/features/users/components/user-listing.tsx` +- `src/features/crm/customers/components/customer-listing.tsx` +- `src/app/dashboard/crm/settings/user-role-assignments/page.tsx` + +### UI Composition Rules + +- Reuse shadcn/ui primitives from `src/components/ui/**`. +- Reuse table shell components from `src/components/ui/table/**`. +- Reuse `useDataTable` for table state orchestration. +- Reuse TanStack Form wrappers from `@/components/ui/tanstack-form` and field components from `@/components/forms/fields`. +- Do not create a parallel CRM design system or terminology layer. + +## Backend Architecture + +- Use Route Handlers under `src/app/api/**` as the HTTP boundary. +- Keep route handlers thin: auth, validation, service call, response mapping, and audit. +- Put business logic in feature or foundation service layers under `src/features/**`. +- Use Drizzle ORM for database access. +- Keep direct database access out of client components. + +### Route Structure Pattern + +Approved structure: + +1. `requireOrganizationAccess()` or another shared auth helper +2. request parsing and schema validation +3. build resolved access/security context when the feature is scope-sensitive +4. call feature/foundation service +5. emit audit/security events through shared audit services +6. return typed JSON/stream response + +Reference examples: + +- `src/app/api/crm/quotations/route.ts` +- `src/app/api/crm/approvals/route.ts` +- `src/app/api/crm/reports/pipeline/route.ts` +- `src/app/api/crm/reports/export/route.ts` + +## Module Structure + +Preferred feature layout: + +```text +src/features// + api/ + types.ts + service.ts + queries.ts + mutations.ts + components/ + schemas/ + server/ +``` + +Rules: + +- components import contracts from `api/types.ts` +- UI calls query options from `api/queries.ts` +- UI mutations reuse shared mutation configs from `api/mutations.ts` +- services in `api/service.ts` call route handlers through `src/lib/api-client.ts` +- server business logic stays under feature/foundation server services + +## Service Layer Pattern + +- Services own business rules, persistence orchestration, and reusable data shaping. +- Services may call other services when extending an existing foundation. +- Services should not depend on UI concerns. +- Report services must use dataset/builders/filter layers instead of embedding ad hoc SQL in routes. +- PDF flows must use the PDF and artifact foundations instead of custom rendering paths. + +Reference services: + +- `src/features/crm/reports/server/service.ts` +- `src/features/foundation/approval/server/service.ts` +- `src/features/foundation/pdf-generator/server/service.ts` +- `src/features/foundation/storage/service.ts` + +## Query Pattern + +- Define centralized query key factories in each feature's `api/queries.ts`. +- Keys should group into `all`, `lists()`, `list(filters)`, `details()`, `detail(id)`, and child-resource keys where applicable. +- Server pages prefetch query options and dehydrate. +- Clients read the same keys with `useSuspenseQuery()`. + +Reference examples: + +- `src/features/products/api/queries.ts` +- `src/features/users/api/queries.ts` +- `src/features/crm/reports/api/queries.ts` + +## Mutation Pattern + +- Centralize mutation configs in `api/mutations.ts`. +- Shared mutation configs must retain cache invalidation. +- After create: invalidate list-level keys. +- After update: invalidate list and detail keys. +- After delete: invalidate lists and remove stale detail queries. +- Refresh related tabs, counts, previews, and approval panels when they depend on the changed entity. + +## Audit Pattern + +- Use `auditCreate()`, `auditUpdate()`, `auditDelete()`, or `auditAction()` from `src/features/foundation/audit-log/service.ts`. +- Reuse existing entity types and action naming where possible. +- Security-sensitive denials use `crm_security_access` through `auditCrmSecurityEvent()`. +- Report view/export events use `crm_report`. + +Reference examples: + +- `src/features/foundation/audit-log/service.ts` +- `src/features/crm/security/server/service.ts` +- `src/features/crm/reports/server/exports/service.ts` + +## Security Pattern + +- Organization access starts with `requireOrganizationAccess()`. +- CRM authorization must use resolved access, not raw role strings. +- Use `resolveCrmMembershipAccess()` for effective permission/scope unions. +- Use `buildCrmSecurityContext()` for scope-aware CRM services. +- Use `resolveCrmAccess()` / report-context builders for report routes. +- Scope checks must enforce branch, product, ownership, and pricing visibility server-side. + +Reference docs: + +- `docs/security/crm-authorization-boundaries.md` +- `docs/security/crm-access-enforcement-inventory.md` +- `docs/security/team-scope-limitations.md` + +## Explicitly Forbidden + +- business logic in route handlers +- client-side only authorization +- direct role-string CRM authorization +- direct DB access from client code +- duplicate export/report/PDF/approval/security foundations +- new Clerk integration +- new SWR or Redux data architecture for app-owned features +- new React Hook Form usage in this repo diff --git a/docs/standards/project-foundations.md b/docs/standards/project-foundations.md new file mode 100644 index 0000000..a9ef675 --- /dev/null +++ b/docs/standards/project-foundations.md @@ -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 diff --git a/docs/standards/task-catalog.md b/docs/standards/task-catalog.md new file mode 100644 index 0000000..545cc6f --- /dev/null +++ b/docs/standards/task-catalog.md @@ -0,0 +1,622 @@ +# Task Catalog + +This catalog is the official index of completed ALLA OS task history. + +Use it to answer these questions before implementation: + +- Which task created this feature or foundation? +- Which ADR governs this area? +- Which foundation was created or modified? +- Which implementation note should be reviewed first? + +This file complements: + +- `AGENTS.md` +- `docs/standards/project-foundations.md` +- `docs/standards/architecture-rules.md` +- `docs/standards/ui-ux-rules.md` +- `docs/standards/task-review-checklist.md` +- `docs/adr/**` +- `docs/business/**` + +## How To Use This Catalog + +Before changing any feature, foundation, report, PDF flow, or authorization behavior: + +1. Identify the related foundation in `project-foundations.md`. +2. Find the creating and modifying tasks in this catalog. +3. Review the linked ADRs. +4. Review the listed implementation notes before coding. +5. Reuse the established pattern before creating a new one. + +## Foundation -> Task Map + +| Foundation | Created By | Key Follow-up Tasks | +| --- | --- | --- | +| Auth Context Foundation | Task B | Task B.1, Task D.1 | +| Organization Context Foundation | Task B | Task B.1 | +| Permission Foundation | Task B | Task L, Task J.1 | +| Branch Scope Foundation | Task B | Task B.1, Task L, Task L.3 | +| Audit Foundation | Task B | Tasks C-I, K.1, K.2, L.3 | +| Master Data Foundation | Task B | Task B.1, Task D.4, Task J.1, Task K.1, Hotfix 1 | +| Document Sequence Foundation | Task B | Task B.1, Task D, Task E, Task J.1 | +| Customer Ownership Foundation | Task C.1 | Task L.3.1 | +| Contact Sharing Foundation | Task C.1 | Task L.3.1 | +| Approval Foundation | Task F | Task H.3, Task J.1, Task L.3, Task L.3.1 | +| Document Template Foundation | Task G | Task H.2, Task H.3, Task H.5, Task H.5.3, Task J.1 | +| PDF Foundation | Task H | Task H.1, Task H.2, Task H.3, Task H.5, Task H.5.1, Task H.5.3, Task I | +| Document Artifact Foundation | Task I | Task L.3 | +| Storage Foundation | Task I | Task L.3 | +| Dashboard Foundation | Task J | Task D.3, Task D.4, Task J.0, Task L.3, UX.1 | +| Reporting Foundation | Task K.1 | Task K.2 | +| Role Management Foundation | Task L | Task L.1, Task L.2 | +| CRM Role Assignment Foundation | Task L.1 | Task L.2 | +| Authorization Foundation | Task L | Task L.1, Task L.2, Task L.3, Task L.3.1 | +| Follow-Up Foundation | Task D plus Task E | Task J, Task K.2 | +| Revenue Attribution Foundation | Task D.2.1 | Task J, Task K.1, Task K.2 | + +## ADR -> Task Map + +| ADR | Related Tasks | +| --- | --- | +| ADR-0006 Branch Domain Model | Task B, Task B.1, Task J.1 | +| ADR-0007 Quotation Revision Strategy | Task E.1, Task F | +| ADR-0008 Attachment Storage Strategy | Task E.1, Task I | +| ADR-0009 Approved Document Storage Lifecycle | Task H.1, Task I | +| ADR-0010 Revenue Attribution Governance | Task D.2.1, Task J, Task K.1, Task K.2 | +| ADR-0011 Lead and Enquiry Ownership Model | Task D.3, Task D.3.1, Task J, Task K.2 | +| ADR-0012 Approval Signature Strategy | Task H.3, Task J.1 | +| ADR-0013 PDF Visual Parity Strategy | Task H.5, Task H.5.1, Task H.5.3 | +| ADR-0014 CRM Multi-Role User Assignment | Task L, Task L.1, Task L.2, Task L.3 | +| ADR-0015 Customer Ownership and Contact Sharing | Task C.1, Task L.3.1 | +| ADR-0016 Won / Lost Lifecycle Governance | Task D.4, Task J, Task K.2 | +| ADR-0017 CRM Report Foundation | Task K.1, Task K.2 | + +## Task Dependency Map + +- Task B depends on: Task A +- Task B.1 depends on: Task B +- Task C depends on: Task B, Task B.1 +- Task C.1 depends on: Task C, Task L.3 context for later security hardening +- Task D depends on: Task B, Task B.1, Task C +- Task D.1 depends on: Task D, Task B foundations +- Task D.2 depends on: Task D, Task E +- Task D.2.1 depends on: Task D.2, Task J.0 +- Task D.3 depends on: Task D, Task D.1 +- Task D.3.1 depends on: Task D.3 +- Task D.4 depends on: Task D, Task D.3 +- Task E depends on: Task D, Task B foundations +- Task E.1 depends on: Task E +- Task F depends on: Task E, Task E.1 +- Task G depends on: Task E, Task F +- Task H depends on: Task G, Task F +- Task H.1 depends on: Task H +- Task H.2 depends on: Task H, Task H.1 +- Task H.3 depends on: Task F, Task H.2 +- Task H.5 depends on: Task H.2, Task H.3 +- Task H.5.1 depends on: Task H.5 +- Task H.5.2 depends on: historical record missing +- Task H.5.3 depends on: Task H.5, Task H.5.1 +- Task I depends on: Task H, Task H.1 +- Task J.0 depends on: Task D.2 +- Task J depends on: Task J.0, Task D.2.1, Task D.3, Task D.4, Task F +- Task J.1 depends on: Task B, Task F, Task G +- Task K.1 depends on: Task J, Task L foundations +- Task K.2 depends on: Task K.1, Task D.3, Task D.4, Task L.3 +- Task L depends on: Task D.1, Task J +- Task L.1 depends on: Task L +- Task L.2 depends on: Task L.1, users foundation +- Task L.3 depends on: Task L, Task L.1, Task I, Task J +- Task L.3.1 depends on: Task C.1, Task L.3, Task F +- Task UX.1 depends on: Task D.3, Task J +- Hotfix 1 depends on: Task C, Task B master options + +## Task Entries + +### Task A + +- Task ID: `Task A` +- Task Name: `Template Audit` +- Status: `Completed` +- Objective: Freeze the initial project conventions and identify which repo areas were app-owned versus template/demo seams before CRM production work began. +- Related ADRs: `None dedicated` +- Foundations Created: `None` +- Foundations Modified: `None` +- Major Deliverables: project structure audit, tenant-boundary freeze, module-pattern guidance, `Layout.md` usage guidance, migrated-pattern references. +- Key Files: `docs/implementation/task-a-template-audit.md` +- Read Before Modify: `task-a-template-audit.md`, `AGENTS.md`, `architecture-rules.md` + +### Task B + +- Task ID: `Task B` +- Task Name: `Template Audit` +- Status: `Completed` +- Objective: Create the shared foundation layer without introducing CRM business modules. +- Related ADRs: `None dedicated` +- Foundations Created: `Auth Context Foundation`, `Organization Context Foundation`, `Permission Foundation`, `Branch Scope Foundation`, `Master Data Foundation`, `Document Sequence Foundation`, `Audit Foundation` +- Foundations Modified: `None` +- Major Deliverables: schema and migration for early foundations, master-options API, shared helpers, audit helper, initial master-options UI path. +- Key Files: `docs/implementation/task-b-template-audit.md`, `src/features/foundation/**`, `src/app/api/foundation/master-options/route.ts` +- Read Before Modify: `task-b-template-audit.md`, `project-foundations.md`, `task-b1-foundation-stabilization.md` + +### Task B.1 + +- Task ID: `Task B.1` +- Task Name: `Foundation Stabilization` +- Status: `Completed` +- Objective: Stabilize foundation seed data and isolate production CRM routes from demo seams. +- Related ADRs: `ADR-0006` +- Foundations Created: `None` +- Foundations Modified: `Master Data Foundation`, `Document Sequence Foundation`, `Branch Scope Foundation`, `Auth Context Foundation`, `Organization Context Foundation`, `Permission Foundation` +- Major Deliverables: repeatable foundation seed, production-safe CRM routes, demo isolation, schema and service review notes. +- Key Files: `docs/implementation/task-b1-foundation-stabilization.md`, `src/db/seeds/foundation.seed.ts`, `src/app/dashboard/crm/**` +- Read Before Modify: `task-b1-foundation-stabilization.md`, `task-b-template-audit.md`, `project-foundations.md` + +### Task C + +- Task ID: `Task C` +- Task Name: `Customer + Contact Production Module` +- Status: `Completed` +- Objective: Deliver the first production customer and contact CRUD module on top of the shared foundations. +- Related ADRs: `None dedicated` +- Foundations Created: `None dedicated` +- Foundations Modified: `Audit Foundation`, `Master Data Foundation`, `Document Sequence Foundation` +- Major Deliverables: `crm_customers`, `crm_customer_contacts`, customer and contact APIs, production list/detail UI, audit integration, search/filter plumbing. +- Key Files: `docs/implementation/task-c-customer-contact.md`, `src/features/crm/customers/**`, `src/app/api/crm/customers/**` +- Read Before Modify: `task-c-customer-contact.md`, `project-foundations.md`, `task-c1-customer-ownership-contact-sharing-governance.md`, `task-l31-customer-contact-approval-visibility.md` + +### Task C.1 + +- Task ID: `Task C.1` +- Task Name: `Customer Ownership and Contact Sharing Governance` +- Status: `Completed` +- Objective: Add persistent customer ownership and persistent contact sharing to close CRM visibility and routing gaps. +- Related ADRs: `ADR-0015` +- Foundations Created: `Customer Ownership Foundation`, `Contact Sharing Foundation` +- Foundations Modified: `Authorization Foundation`, `Lead / Enquiry Foundation` +- Major Deliverables: owner fields and history, `crm_contact_shares`, owner/share APIs, owner UI, contact sharing UI, lead owner suggestion behavior, audit events. +- Key Files: `docs/implementation/task-c1-customer-ownership-contact-sharing-governance.md`, `docs/adr/0015-customer-ownership-contact-sharing.md`, `src/app/api/crm/customers/[id]/owner/route.ts`, `src/app/api/crm/customers/[id]/contacts/[contactId]/shares/**` +- Read Before Modify: `0015-customer-ownership-contact-sharing.md`, `task-c1-customer-ownership-contact-sharing-governance.md`, `project-foundations.md`, `crm-authorization-boundaries.md` + +### Task D + +- Task ID: `Task D` +- Task Name: `Enquiry Production Module` +- Status: `Completed` +- Objective: Deliver the production enquiry module and the first live follow-up flows. +- Related ADRs: `None dedicated` +- Foundations Created: `Follow-Up Foundation` (enquiry slice) +- Foundations Modified: `Document Sequence Foundation`, `Audit Foundation`, `Master Data Foundation` +- Major Deliverables: `crm_enquiries`, `crm_enquiry_followups`, enquiry CRUD APIs, follow-up APIs, enquiry detail UI, customer integration, sequence generation. +- Key Files: `docs/implementation/task-d-enquiry-production.md`, `src/features/crm/enquiries/**`, `src/app/api/crm/enquiries/**` +- Read Before Modify: `task-d-enquiry-production.md`, `project-foundations.md`, `task-d1-enquiry-assignment-role-stabilization.md`, `task-d3-lead-enquiry-ownership-refinement.md`, `task-d4-won-lost-lifecycle-governance.md` + +### Task D.1 + +- Task ID: `Task D.1` +- Task Name: `Enquiry Assignment and CRM Role Stabilization` +- Status: `Completed` +- Objective: Stabilize assignment behavior and early CRM role handling around enquiries. +- Related ADRs: `None dedicated` +- Foundations Created: `None` +- Foundations Modified: `Auth Context Foundation`, `Permission Foundation`, early `Authorization Foundation` lineage +- Major Deliverables: assignment routes, assignment permissions, auth-context refinements, UI assignment support, audit integration. +- Key Files: `docs/implementation/task-d1-enquiry-assignment-role-stabilization.md`, `src/features/foundation/auth-context/service.ts`, `src/app/api/crm/enquiries/[id]/assign/route.ts` +- Read Before Modify: `task-d1-enquiry-assignment-role-stabilization.md`, `task-d-enquiry-production.md`, `task-l-crm-permission-role-management.md` + +### Task D.2 + +- Task ID: `Task D.2` +- Task Name: `Billing Customer + Project Parties` +- Status: `Completed` +- Objective: Freeze separate billing-customer and project-party modeling for enquiries and quotations. +- Related ADRs: `None dedicated` +- Foundations Created: `None dedicated` +- Foundations Modified: `Revenue Attribution Foundation` lineage, `Master Data Foundation`, CRM shared project-party usage +- Major Deliverables: `crm_enquiry_customers`, quotation party remark support, shared `crm_project_party_role` sourcing, synchronized project-party UI. +- Key Files: `docs/implementation/task-d2-billing-customer-project-parties.md`, `src/features/crm/components/project-parties-editor.tsx`, `src/features/crm/shared/project-party.ts` +- Read Before Modify: `task-d2-billing-customer-project-parties.md`, `task-d21-revenue-attribution-governance.md`, `task-j0-kpi-definition-freeze.md` + +### Task D.2.1 + +- Task ID: `Task D.2.1` +- Task Name: `Revenue Attribution and Party Governance` +- Status: `Completed` +- Objective: Freeze revenue-owner attribution and relationship analytics before dashboard and report expansion. +- Related ADRs: `ADR-0010` +- Foundations Created: `Revenue Attribution Foundation` +- Foundations Modified: `Dashboard Foundation`, `Reporting Foundation` lineage +- Major Deliverables: grouped revenue helpers, project-party governance, fallback rules, ADR freeze for reporting attribution. +- Key Files: `docs/implementation/task-d21-revenue-attribution-governance.md`, `docs/adr/0010-revenue-attribution-governance.md`, `src/features/crm/reporting/server/service.ts` +- Read Before Modify: `0010-revenue-attribution-governance.md`, `task-d21-revenue-attribution-governance.md`, `task-j-crm-dashboard-kpi.md`, `task-k1-report-foundation.md` + +### Task D.3 + +- Task ID: `Task D.3` +- Task Name: `Lead / Enquiry Ownership Refinement` +- Status: `Completed` +- Objective: Freeze the single-record lead/enquiry lifecycle, ownership, visibility, and KPI language. +- Related ADRs: `ADR-0011` +- Foundations Created: `Lead / Enquiry Foundation` +- Foundations Modified: `Dashboard Foundation`, `Authorization Foundation` +- Major Deliverables: `pipelineStage`, marketing role, lead/enquiry visibility rules, KPI wording changes, ADR freeze. +- Key Files: `docs/implementation/task-d3-lead-enquiry-ownership-refinement.md`, `docs/adr/0011-lead-enquiry-ownership-model.md`, `src/features/crm/enquiries/server/service.ts` +- Read Before Modify: `0011-lead-enquiry-ownership-model.md`, `task-d3-lead-enquiry-ownership-refinement.md`, `task-d31-leads-enquiries-navigation-separation.md`, `task-k2-pipeline-reports.md` + +### Task D.3.1 + +- Task ID: `Task D.3.1` +- Task Name: `Leads / Enquiries Navigation Separation` +- Status: `Completed` +- Objective: Split lead and enquiry into separate UX workspaces while preserving one shared backend model. +- Related ADRs: `ADR-0011` +- Foundations Created: `None` +- Foundations Modified: `Lead / Enquiry Foundation`, `Dashboard Foundation` +- Major Deliverables: `/dashboard/crm/leads`, workspace-specific query invalidation, lead permissions, ADR clarification for navigation separation. +- Key Files: `docs/implementation/task-d31-leads-enquiries-navigation-separation.md`, `src/app/dashboard/crm/leads/**`, `src/features/crm/enquiries/**` +- Read Before Modify: `0011-lead-enquiry-ownership-model.md`, `task-d31-leads-enquiries-navigation-separation.md`, `task-d3-lead-enquiry-ownership-refinement.md` + +### Task D.4 + +- Task ID: `Task D.4` +- Task Name: `Won / Lost Lifecycle Governance` +- Status: `Completed` +- Objective: Freeze official won/lost outcome behavior on enquiries rather than deriving it from quotation status. +- Related ADRs: `ADR-0016` +- Foundations Created: `Won / Lost Governance Foundation` +- Foundations Modified: `Dashboard Foundation`, `Reporting Foundation`, `Master Data Foundation` +- Major Deliverables: won/lost outcome fields, PO attachments, lost reason master data, mark-won/mark-lost/reopen APIs, outcome card, reporting helpers. +- Key Files: `docs/implementation/task-d4-won-lost-lifecycle-governance.md`, `docs/adr/0016-won-lost-lifecycle-governance.md`, `src/app/api/crm/enquiries/[id]/mark-won/route.ts` +- Read Before Modify: `0016-won-lost-lifecycle-governance.md`, `task-d4-won-lost-lifecycle-governance.md`, `task-j-crm-dashboard-kpi.md`, `task-k2-pipeline-reports.md` + +### Task E + +- Task ID: `Task E` +- Task Name: `Quotation Production Module` +- Status: `Completed` +- Objective: Deliver the production quotation module and its core child-resource model. +- Related ADRs: `None dedicated at creation time` +- Foundations Created: `Quotation Foundation` +- Foundations Modified: `Document Sequence Foundation`, `Audit Foundation`, `Follow-Up Foundation` +- Major Deliverables: quotation CRUD, items, customers/project parties, topics, follow-ups, attachments metadata, revisions, detail UI, customer/enquiry linkage. +- Key Files: `docs/implementation/task-e-quotation-production.md`, `src/features/crm/quotations/**`, `src/app/api/crm/quotations/**` +- Read Before Modify: `task-e-quotation-production.md`, `task-e1-quotation-stabilization.md`, `0007-quotation-revision-strategy.md`, `0008-attachment-storage-strategy.md` + +### Task E.1 + +- Task ID: `Task E.1` +- Task Name: `Quotation Stabilization Before Approval` +- Status: `Completed` +- Objective: Freeze quotation revision and attachment assumptions before approval work begins. +- Related ADRs: `ADR-0007`, `ADR-0008` +- Foundations Created: `None` +- Foundations Modified: `Quotation Foundation`, `Master Data Foundation` +- Major Deliverables: status vocabulary expansion, revision guard, quotation-related master options, approval readiness rules, ADRs for revision and attachment strategy. +- Key Files: `docs/implementation/task-e1-quotation-stabilization.md`, `docs/adr/0007-quotation-revision-strategy.md`, `docs/adr/0008-attachment-storage-strategy.md` +- Read Before Modify: `task-e1-quotation-stabilization.md`, `0007-quotation-revision-strategy.md`, `0008-attachment-storage-strategy.md`, `task-f-approval-production.md` + +### Task F + +- Task ID: `Task F` +- Task Name: `Approval Production` +- Status: `Completed` +- Objective: Introduce the first production approval workflow on top of quotation flows and keep it generic for future documents. +- Related ADRs: `ADR-0007` +- Foundations Created: `Approval Foundation` +- Foundations Modified: `Quotation Foundation`, `Audit Foundation` +- Major Deliverables: approval persistence, approval APIs, approval UI, quotation approval submission, seeded workflow steps, approval permissions. +- Key Files: `docs/implementation/task-f-approval-production.md`, `src/features/foundation/approval/**`, `src/app/api/crm/approvals/**` +- Read Before Modify: `task-f-approval-production.md`, `project-foundations.md`, `task-h3-approval-signature-strategy.md`, `task-l31-customer-contact-approval-visibility.md` + +### Task G + +- Task ID: `Task G` +- Task Name: `Quotation Document Preview Foundation` +- Status: `Completed` +- Objective: Add governed document templates and a production document-preview path before binary PDF generation. +- Related ADRs: `None dedicated at creation time` +- Foundations Created: `Document Template Foundation` +- Foundations Modified: `Quotation Foundation` +- Major Deliverables: template schema tables, template APIs, template settings UI, mapping resolver, preview APIs, approved snapshot preparation. +- Key Files: `docs/implementation/task-g-document-preview-foundation.md`, `src/features/foundation/document-template/**`, `src/features/crm/quotations/document/**` +- Read Before Modify: `task-g-document-preview-foundation.md`, `task-h-pdf-generation-persistence.md`, `task-h53-pdf-template-version-remap.md` + +### Task H + +- Task ID: `Task H` +- Task Name: `PDF Generation and Approved Document Persistence` +- Status: `Completed` +- Objective: Add server-side PDF generation and the first approved-document persistence path. +- Related ADRs: `None dedicated at creation time` +- Foundations Created: `PDF Foundation` +- Foundations Modified: `Quotation Foundation`, `Approval Foundation` +- Major Deliverables: pdfme generation service, preview/download/approved PDF APIs, approved snapshot fields, local-file persistence, PDF permissions. +- Key Files: `docs/implementation/task-h-pdf-generation-persistence.md`, `src/features/foundation/pdf-generator/server/service.ts`, `src/app/api/crm/quotations/[id]/pdf-preview/route.ts` +- Read Before Modify: `task-h-pdf-generation-persistence.md`, `task-h1-pdf-generation-stabilization.md`, `task-i-storage-artifact-lifecycle.md` + +### Task H.1 + +- Task ID: `Task H.1` +- Task Name: `PDF Generation Stabilization` +- Status: `Completed` +- Objective: Validate and harden the Task H PDF flow with fixtures, verification scripts, and storage-lifecycle clarification. +- Related ADRs: `ADR-0009` +- Foundations Created: `None` +- Foundations Modified: `PDF Foundation` +- Major Deliverables: repeatable fixture data, verification script, persistence checks, lifecycle ADR, debt documentation. +- Key Files: `docs/implementation/task-h1-pdf-generation-stabilization.md`, `docs/adr/0009-approved-document-storage-lifecycle.md`, `scripts/verify-task-h1.js` +- Read Before Modify: `task-h1-pdf-generation-stabilization.md`, `0009-approved-document-storage-lifecycle.md`, `task-i-storage-artifact-lifecycle.md` + +### Task H.2 + +- Task ID: `Task H.2` +- Task Name: `PDFME Dynamic Topic Engine + Mapping Hotfix` +- Status: `Completed` +- Objective: Replace brittle static topic mappings with a dynamic runtime topic engine and fix PDF data transforms. +- Related ADRs: `None dedicated` +- Foundations Created: `Dynamic topic engine within PDF Foundation` +- Foundations Modified: `PDF Foundation`, `Document Template Foundation` +- Major Deliverables: runtime topic engine, PDF transforms, product-topic mapping, mapping cleanup, preview payload hardening. +- Key Files: `docs/implementation/task-h2-pdfme-mapping-transform-hotfix.md`, `src/features/crm/quotations/document/server/pdf-topic-engine.ts`, `src/features/crm/quotations/document/server/pdfme-transforms.ts` +- Read Before Modify: `task-h2-pdfme-mapping-transform-hotfix.md`, `task-h5-pdf-mapping-audit-visual-parity.md`, `pdf-mapping-registry.md`, `pdf-placeholder-registry.md` + +### Task H.3 + +- Task ID: `Task H.3` +- Task Name: `Approval Signature Strategy` +- Status: `Completed` +- Objective: Resolve prepared-by, approved-by, and authorized-by signatures from live approval and membership data. +- Related ADRs: `ADR-0012` +- Foundations Created: `Signature strategy within PDF Foundation` +- Foundations Modified: `PDF Foundation`, `Approval Foundation`, `Master Data Foundation` +- Major Deliverables: signature resolver, position lookup, mapping updates for `app1/app2/app3`, snapshot signature persistence, preview signature section. +- Key Files: `docs/implementation/task-h3-approval-signature-strategy.md`, `docs/adr/0012-approval-signature-strategy.md`, `src/features/crm/quotations/document/server/signature-resolver.ts` +- Read Before Modify: `0012-approval-signature-strategy.md`, `task-h3-approval-signature-strategy.md`, `pdf-mapping-registry.md` + +### Task H.5 + +- Task ID: `Task H.5` +- Task Name: `PDF Mapping Audit & Visual Parity` +- Status: `Completed` +- Objective: Establish an auditable PDF mapping and parity review process for runtime payloads and templates. +- Related ADRs: `ADR-0013` +- Foundations Created: `PDF audit layer within PDF Foundation` +- Foundations Modified: `PDF Foundation`, `Document Template Foundation` +- Major Deliverables: audit scripts, fixture strategy, parity checklist, mapping registry, visual parity ADR. +- Key Files: `docs/implementation/task-h5-pdf-mapping-audit-visual-parity.md`, `docs/adr/0013-pdf-visual-parity-strategy.md`, `docs/implementation/pdf-parity-checklist.md` +- Read Before Modify: `0013-pdf-visual-parity-strategy.md`, `task-h5-pdf-mapping-audit-visual-parity.md`, `pdf-mapping-registry.md`, `pdf-placeholder-registry.md` + +### Task H.5.1 + +- Task ID: `Task H.5.1` +- Task Name: `PDF Integrity Audit & Payload Parity` +- Status: `Completed` +- Objective: Extend H.5 into integrity checks for active versions, placeholders, payload hashes, and approved snapshot parity. +- Related ADRs: `ADR-0013` +- Foundations Created: `None` +- Foundations Modified: `PDF Foundation`, `Document Template Foundation` +- Major Deliverables: integrity audit scripts, placeholder registry, parity hash checks, audit artifact generation, stricter integrity gating. +- Key Files: `docs/implementation/task-h51-pdf-integrity-audit.md`, `docs/business/pdf-placeholder-registry.md`, `scripts/audit-approved-snapshot-parity.ts` +- Read Before Modify: `task-h51-pdf-integrity-audit.md`, `task-h5-pdf-mapping-audit-visual-parity.md`, `task-h53-pdf-template-version-remap.md` + +### Task H.5.2 + +- Task ID: `Task H.5.2` +- Task Name: `Historical Record Missing` +- Status: `Missing historical record` +- Objective: No dedicated completed implementation document was found for `Task H.5.2` in `docs/implementation/**`. +- Related ADRs: `Not confirmed` +- Foundations Created: `Unknown` +- Foundations Modified: `Unknown` +- Major Deliverables: no task note found; review adjacent H.5, H.5.1, H.5.3, `pdf-audit-report.md`, and `pdf-audit-report.json` for continuity. +- Key Files: `docs/implementation/task-h5-pdf-mapping-audit-visual-parity.md`, `docs/implementation/task-h51-pdf-integrity-audit.md`, `docs/implementation/task-h53-pdf-template-version-remap.md`, `docs/implementation/pdf-audit-report.md` +- Read Before Modify: `task-h5-pdf-mapping-audit-visual-parity.md`, `task-h51-pdf-integrity-audit.md`, `task-h53-pdf-template-version-remap.md` + +### Task H.5.3 + +- Task ID: `Task H.5.3` +- Task Name: `PDF Template Version Remap + Static Labels` +- Status: `Completed` +- Objective: Move active templates to remapped versioned records and restore runtime-managed static labels. +- Related ADRs: `ADR-0013` +- Foundations Created: `Template remap workflow within Document Template Foundation` +- Foundations Modified: `Document Template Foundation`, `PDF Foundation` +- Major Deliverables: active `1.1` template versions, remap workflow, retained inactive historical versions, restored static labels, passing audit suite. +- Key Files: `docs/implementation/task-h53-pdf-template-version-remap.md`, `src/pdfme_template/*.json`, `docs/business/pdf-mapping-registry.md` +- Read Before Modify: `task-h53-pdf-template-version-remap.md`, `task-h51-pdf-integrity-audit.md`, `pdf-mapping-registry.md`, `pdf-placeholder-registry.md` + +### Task I + +- Task ID: `Task I` +- Task Name: `Storage Abstraction and Approved Artifact Lifecycle` +- Status: `Completed` +- Objective: Replace raw public-file assumptions with a storage provider and artifact lifecycle foundation. +- Related ADRs: `ADR-0008`, `ADR-0009` +- Foundations Created: `Storage Foundation`, `Document Artifact Foundation` +- Foundations Modified: `PDF Foundation`, `Approval Foundation` +- Major Deliverables: storage provider abstraction, artifact schema, secure download route, checksum support, approved-artifact locking, compatibility migration path. +- Key Files: `docs/implementation/task-i-storage-artifact-lifecycle.md`, `src/features/foundation/storage/**`, `src/features/foundation/document-artifact/**` +- Read Before Modify: `task-i-storage-artifact-lifecycle.md`, `0009-approved-document-storage-lifecycle.md`, `task-l3-full-crm-scope-enforcement.md` + +### Task J.0 + +- Task ID: `Task J.0` +- Task Name: `KPI Definition Freeze` +- Status: `Completed` +- Objective: Freeze KPI semantics, party terminology, and revenue rules before dashboard implementation. +- Related ADRs: `Pre-ADR governance freeze; later intersected by ADR-0010, ADR-0011, ADR-0016` +- Foundations Created: `None` +- Foundations Modified: `Dashboard Foundation` lineage, `Revenue Attribution Foundation` lineage +- Major Deliverables: KPI definitions, pipeline semantics, party terminology freeze, governance rule that later KPI changes require an ADR. +- Key Files: `docs/implementation/task-j0-kpi-definition-freeze.md` +- Read Before Modify: `task-j0-kpi-definition-freeze.md`, `task-j-crm-dashboard-kpi.md`, `0010-revenue-attribution-governance.md`, `0011-lead-enquiry-ownership-model.md` + +### Task J + +- Task ID: `Task J` +- Task Name: `CRM Dashboard KPI and Sales Analytics` +- Status: `Completed` +- Objective: Deliver the live CRM dashboard and operational KPI surfaces on top of frozen governance rules. +- Related ADRs: `ADR-0010`, `ADR-0011`, `ADR-0016` +- Foundations Created: `Dashboard Foundation` +- Foundations Modified: `Revenue Attribution Foundation`, `Follow-Up Foundation`, `Approval Foundation` +- Major Deliverables: dashboard APIs, summary/funnel/revenue/sales/follow-up/approval widgets, export support, dashboard permissions. +- Key Files: `docs/implementation/task-j-crm-dashboard-kpi.md`, `src/features/crm/dashboard/**`, `src/app/api/crm/dashboard/**` +- Read Before Modify: `task-j-crm-dashboard-kpi.md`, `task-j0-kpi-definition-freeze.md`, `task-d21-revenue-attribution-governance.md`, `task-d4-won-lost-lifecycle-governance.md` + +### Task J.1 + +- Task ID: `Task J.1` +- Task Name: `CRM Admin Configuration Center` +- Status: `Completed` +- Objective: Expose settings foundations through organization-scoped admin routes and usable production UI. +- Related ADRs: `ADR-0006`, `ADR-0012` +- Foundations Created: `None` +- Foundations Modified: `Approval Foundation`, `Document Sequence Foundation`, `Document Template Foundation`, `Master Data Foundation` +- Major Deliverables: approval-workflow settings UI and APIs, document-sequence settings UI and APIs, template edit/version/mapping UI and APIs, settings navigation. +- Key Files: `docs/implementation/task-j1-crm-admin-configuration-center.md`, `src/app/api/crm/settings/**`, `src/app/dashboard/crm/settings/**` +- Read Before Modify: `task-j1-crm-admin-configuration-center.md`, `project-foundations.md`, `task-g-document-preview-foundation.md`, `task-f-approval-production.md` + +### Task K.1 + +- Task ID: `Task K.1` +- Task Name: `Report Foundation` +- Status: `Completed` +- Objective: Establish the shared CRM report platform before business report execution pages are added. +- Related ADRs: `ADR-0017` +- Foundations Created: `Reporting Foundation` +- Foundations Modified: `Master Data Foundation`, `Authorization Foundation`, `Audit Foundation` +- Major Deliverables: report registry, report category seed, report discovery APIs, dataset/builder/filter/export layers, report landing page. +- Key Files: `docs/implementation/task-k1-report-foundation.md`, `docs/adr/0017-report-foundation.md`, `src/features/crm/reports/**` +- Read Before Modify: `0017-report-foundation.md`, `task-k1-report-foundation.md`, `task-k2-pipeline-reports.md`, `project-foundations.md` + +### Task K.2 + +- Task ID: `Task K.2` +- Task Name: `Pipeline Reports` +- Status: `Completed` +- Objective: Deliver the first production report suite on top of the shared report foundation. +- Related ADRs: `ADR-0010`, `ADR-0011`, `ADR-0016`, `ADR-0017` +- Foundations Created: `None` +- Foundations Modified: `Reporting Foundation`, `Follow-Up Foundation`, `Authorization Foundation` +- Major Deliverables: pipeline, lead-aging, and enquiry-aging reports; export route; dataset layer; scoped security enforcement; report navigation. +- Key Files: `docs/implementation/task-k2-pipeline-reports.md`, `src/app/api/crm/reports/**`, `src/features/crm/reports/server/datasets/pipeline-report.dataset.ts` +- Read Before Modify: `task-k2-pipeline-reports.md`, `task-k1-report-foundation.md`, `0017-report-foundation.md`, `task-d3-lead-enquiry-ownership-refinement.md`, `task-d4-won-lost-lifecycle-governance.md` + +### Task L + +- Task ID: `Task L` +- Task Name: `CRM Permission & Role Management` +- Status: `Completed` +- Objective: Replace template-era authorization behavior with app-owned CRM role profiles, permissions, and scope-aware access resolution. +- Related ADRs: `ADR-0014` +- Foundations Created: `Role Management Foundation`, `Authorization Foundation` +- Foundations Modified: `Dashboard Foundation`, `Permission Foundation` +- Major Deliverables: role profiles, permissions for pricing and admin settings, resolved CRM access helper, roles page and APIs, early server-side scope enforcement. +- Key Files: `docs/implementation/task-l-crm-permission-role-management.md`, `src/features/foundation/role-management/**`, `src/lib/auth/crm-access.ts` +- Read Before Modify: `task-l-crm-permission-role-management.md`, `0014-crm-multi-role-user-assignment.md`, `crm-authorization-boundaries.md`, `crm-access-enforcement-inventory.md` + +### Task L.1 + +- Task ID: `Task L.1` +- Task Name: `CRM Multi-Role User Assignment` +- Status: `Completed` +- Objective: Move CRM authorization from one business role per membership to multi-role assignment rows. +- Related ADRs: `ADR-0014` +- Foundations Created: `CRM Role Assignment Foundation` +- Foundations Modified: `Authorization Foundation`, `Role Management Foundation` +- Major Deliverables: `crm_user_role_assignments`, assignment permissions, assignment APIs, compatibility backfill, union-based resolved access. +- Key Files: `docs/implementation/task-l1-crm-multi-role-user-assignment.md`, `docs/adr/0014-crm-multi-role-user-assignment.md`, `src/features/foundation/crm-role-assignments/**` +- Read Before Modify: `0014-crm-multi-role-user-assignment.md`, `task-l1-crm-multi-role-user-assignment.md`, `task-l2-user-management-integration.md` + +### Task L.2 + +- Task ID: `Task L.2` +- Task Name: `User Management Integration` +- Status: `Completed` +- Objective: Make user management the primary operational surface for CRM role assignments. +- Related ADRs: `ADR-0014` +- Foundations Created: `None` +- Foundations Modified: `CRM Role Assignment Foundation`, `Authorization Foundation`, users feature integration +- Major Deliverables: user create/edit payload changes, CRM role assignment editing in user form, effective-access preview, reference endpoints, migration utility. +- Key Files: `docs/implementation/task-l2-user-management-integration.md`, `src/app/api/users/_lib.ts`, `src/app/api/users/[id]/effective-access-preview/route.ts` +- Read Before Modify: `task-l2-user-management-integration.md`, `task-l1-crm-multi-role-user-assignment.md`, `0014-crm-multi-role-user-assignment.md` + +### Task L.3 + +- Task ID: `Task L.3` +- Task Name: `Full CRM Scope Enforcement` +- Status: `Completed` +- Objective: Harden scope and pricing visibility enforcement around resolved CRM access. +- Related ADRs: `ADR-0014` +- Foundations Created: `Security enforcement layer within Authorization Foundation` +- Foundations Modified: `Authorization Foundation`, `Document Artifact Foundation`, `Dashboard Foundation`, `Quotation Foundation` +- Major Deliverables: security helpers, pricing guards for quotation outputs, dashboard export restriction, quotation scope enforcement, security inventory docs, verification script. +- Key Files: `docs/implementation/task-l3-full-crm-scope-enforcement.md`, `src/features/crm/security/server/service.ts`, `docs/security/crm-authorization-boundaries.md` +- Read Before Modify: `task-l3-full-crm-scope-enforcement.md`, `crm-authorization-boundaries.md`, `crm-access-enforcement-inventory.md`, `team-scope-limitations.md` + +### Task L.3.1 + +- Task ID: `Task L.3.1` +- Task Name: `Customer, Contact & Approval Visibility Hardening` +- Status: `Completed` +- Objective: Extend resolved-access enforcement to customer, contact, and approval visibility. +- Related ADRs: `ADR-0015` +- Foundations Created: `None` +- Foundations Modified: `Customer Ownership Foundation`, `Contact Sharing Foundation`, `Approval Foundation`, `Authorization Foundation`, `Dashboard Foundation` +- Major Deliverables: customer visibility filters, contact visibility inheritance, approval visibility narrowing, dashboard approval reuse, extra security audit actions. +- Key Files: `docs/implementation/task-l31-customer-contact-approval-visibility.md`, `src/features/crm/customers/server/service.ts`, `src/features/foundation/approval/server/service.ts` +- Read Before Modify: `task-l31-customer-contact-approval-visibility.md`, `0015-customer-ownership-contact-sharing.md`, `crm-authorization-boundaries.md`, `task-c1-customer-ownership-contact-sharing-governance.md` + +### Task UX.1 + +- Task ID: `Task UX.1` +- Task Name: `Thai CRM Terminology Standardization` +- Status: `Completed` +- Objective: Freeze Thai business-facing CRM terminology while keeping internal codes stable. +- Related ADRs: `None dedicated` +- Foundations Created: `Terminology registry support for UI governance` +- Foundations Modified: `Dashboard Foundation`, `Lead / Enquiry Foundation`, `PDF Foundation` +- Major Deliverables: terminology registry, shared terminology helper, menu copy updates, dashboard/report/PDF copy updates. +- Key Files: `docs/implementation/task-ux1-thai-crm-terminology-standardization.md`, `docs/business/crm-terminology.md`, `src/features/crm/shared/terminology.ts` +- Read Before Modify: `task-ux1-thai-crm-terminology-standardization.md`, `crm-terminology.md`, `ui-ux-rules.md` + +### Hotfix 1 + +- Task ID: `Hotfix 1` +- Task Name: `Customer Sub Group` +- Status: `Completed` +- Objective: Add customer subgroup hierarchy without creating a parallel category system. +- Related ADRs: `None dedicated` +- Foundations Created: `None` +- Foundations Modified: `Master Data Foundation`, `Customer module` +- Major Deliverables: `customerSubGroup` field, seeded `crm_customer_group` and `crm_customer_sub_group`, parent/child validation, filtered customer form behavior. +- Key Files: `docs/implementation/hotfix-1-customer-sub-group.md`, `src/db/seeds/foundation.seed.ts`, `src/features/crm/customers/server/service.ts` +- Read Before Modify: `hotfix-1-customer-sub-group.md`, `project-foundations.md`, `task-c-customer-contact.md` + +## Supporting Historical Records + +These are not primary task IDs, but they remain valuable historical review documents: + +- `docs/implementation/pdfme-legacy-audit.md` +- `docs/implementation/pdfme-runtime-audit.md` +- `docs/implementation/pdf-parity-checklist.md` +- `docs/implementation/pdf-audit-report.md` +- `docs/implementation/pdf-audit-report.json` +- `docs/implementation/technical-debt.md` + +## Missing Historical Records + +- `Task H.5.2` has no dedicated implementation note in `docs/implementation/**`. +- No standalone ADR was found for the low-level early foundations created in Task B: + - `Auth Context Foundation` + - `Organization Context Foundation` + - `Permission Foundation` + - `Audit Foundation` + - `Document Sequence Foundation` + +## Catalog Outcome + +- ALLA OS Historical Knowledge Base = ESTABLISHED +- ALLA OS Task Discovery = READY +- ALLA OS AI Context Retention = IMPROVED diff --git a/docs/standards/task-contract-template.md b/docs/standards/task-contract-template.md new file mode 100644 index 0000000..18a46b9 --- /dev/null +++ b/docs/standards/task-contract-template.md @@ -0,0 +1,148 @@ +# Task Contract Template + +Use this template for every future task before implementation starts. + +The contract exists to force review-first execution, foundation reuse, and explicit scope control. + +--- + +## Task Information + +- Task ID: +- Title: +- Owner: +- Requested by: +- Date: +- Related ticket / plan: + +## Objective + +- Describe the business outcome, not just the code change. + +## Business Context + +- Relevant domain background: +- Why this task exists now: +- Related ADRs: +- Related business docs: + +## Required Skills & Context + +- `AGENTS.md` +- `docs/standards/task-catalog.md` +- `docs/standards/project-foundations.md` +- `docs/standards/architecture-rules.md` +- `docs/standards/ui-ux-rules.md` +- `docs/standards/task-review-checklist.md` +- Relevant `docs/adr/**` +- Relevant `docs/business/**` +- Relevant `docs/security/**` +- Existing feature and API references: +- Historical task documents reviewed: + +## Architecture Constraints + +- Frontend constraints: +- Backend constraints: +- Security constraints: +- Reuse constraints: +- Forbidden patterns: + +## Reuse Existing Foundations + +- Foundations reviewed: +- Existing services to extend: +- Existing APIs to extend: +- Existing query/mutation patterns to reuse: +- Existing UI shells/components to reuse: +- Existing audit patterns to reuse: +- Why a new foundation is not required: + +## Data Model Changes + +- Schema changes required: +- Existing tables impacted: +- Migration required: +- Explicit non-changes: + +## API Requirements + +- Route handlers involved: +- Request/response contracts: +- Service layer functions: +- Validation rules: +- Existing APIs reused or extended: + +## UI Requirements + +- Routes / screens: +- Page shell pattern: +- Form / table / filter patterns: +- Terminology requirements: +- Empty / loading / error states: + +## Report / Export Rules + +- Report foundation reviewed: +- Shared filters reused: +- Dataset layer reused: +- Export path reused: +- Revenue/pricing visibility rule: + +## Permission Requirements + +- Required permissions: +- Scope enforcement requirements: +- Resolved access helper to use: +- Server-side protection points: + +## Audit Requirements + +- Entity type: +- Actions: +- Required payload: +- Existing audit naming reused: + +## Scope + +- In scope: + +## Explicit Non-Scope + +- Out of scope: + +## Security Verification Matrix + +| Scenario | Expected access | Enforcement point | +| --- | --- | --- | +| Admin | | | +| Scoped user | | | +| Unauthorized user | | | +| Pricing-restricted user | | | + +## Deliverables + +- Documentation deliverables: +- Code deliverables: +- Verification deliverables: + +## Verification + +- Typecheck: +- Lint: +- Targeted tests: +- Manual scenarios: + +## Documentation + +- Docs to update: +- ADR needed: +- Task implementation note: + +## Definition of Done + +- Review completed before implementation +- Existing foundations reused or extension rationale documented +- Security and audit requirements verified +- Documentation updated +- Verification evidence recorded diff --git a/docs/standards/task-review-checklist.md b/docs/standards/task-review-checklist.md new file mode 100644 index 0000000..1cf7965 --- /dev/null +++ b/docs/standards/task-review-checklist.md @@ -0,0 +1,82 @@ +# Task Review Checklist + +Complete this checklist before implementation starts. + +## Foundation Review + +- [ ] Reviewed `AGENTS.md` +- [ ] Reviewed `docs/standards/project-foundations.md` +- [ ] Reviewed the relevant reusable foundations under `src/features/foundation/**` +- [ ] Reviewed the relevant CRM feature foundations under `src/features/crm/**` +- [ ] Confirmed whether the task extends an existing service before creating a new one + +## ADR Review + +- [ ] Reviewed relevant `docs/adr/**` +- [ ] Confirmed whether the requested behavior conflicts with an accepted ADR +- [ ] Documented if a new ADR is required + +## Historical Task Review + +- [ ] Identified related foundations in `docs/standards/project-foundations.md` +- [ ] Identified related ADRs +- [ ] Identified the tasks that created or changed those foundations in `docs/standards/task-catalog.md` +- [ ] Reviewed the related completed task documents in `docs/implementation/**` +- [ ] Documented historical findings before implementation + +Implementation without historical review is prohibited. + +## Business Context Review + +- [ ] Reviewed relevant `docs/business/**` +- [ ] Confirmed business terminology and scope +- [ ] Checked whether Thai CRM terminology rules apply + +## API Review + +- [ ] Reviewed existing route handlers under the affected `src/app/api/**` area +- [ ] Confirmed whether an existing API can be extended instead of duplicated +- [ ] Confirmed request/response contracts and validation approach + +## Permission Review + +- [ ] Reviewed `src/lib/auth/session.ts` +- [ ] Reviewed `src/lib/auth/crm-access.ts` if CRM scope is involved +- [ ] Reviewed `src/features/crm/security/server/service.ts` if CRM security is involved +- [ ] Reviewed relevant `docs/security/**` +- [ ] Confirmed server-side enforcement points + +## Audit Review + +- [ ] Reviewed `src/features/foundation/audit-log/service.ts` +- [ ] Checked existing entity/action names for the affected module +- [ ] Confirmed whether security-denial auditing is required +- [ ] Confirmed audit payload expectations + +## Duplication Review + +- [ ] No duplicate services +- [ ] No duplicate APIs +- [ ] No duplicate permissions or role models +- [ ] No duplicate export/report systems +- [ ] No duplicate PDF rendering path +- [ ] No duplicate approval workflow logic + +## Security Review + +- [ ] Direct role-string authorization is not used +- [ ] Scope enforcement is server-side +- [ ] Branch/product/ownership/pricing visibility is enforced where applicable +- [ ] Client-side visibility is treated as UX-only, not as security + +## UI / UX Review + +- [ ] Reviewed `docs/standards/ui-ux-rules.md` +- [ ] Reused `PageContainer`, table, filter, and form patterns where applicable +- [ ] Confirmed terminology consistency with `docs/business/crm-terminology.md` + +## Verification Review + +- [ ] Defined typecheck/lint/test verification +- [ ] Defined manual scenarios for scope/security-sensitive work +- [ ] Recorded known risks and follow-up items diff --git a/docs/standards/ui-ux-rules.md b/docs/standards/ui-ux-rules.md new file mode 100644 index 0000000..4ea7efb --- /dev/null +++ b/docs/standards/ui-ux-rules.md @@ -0,0 +1,111 @@ +# UI / UX Rules + +These rules freeze the approved UI behavior for ALLA OS and CRM-facing work. + +Future UI should reuse existing dashboard patterns rather than introducing a parallel visual system. + +## UX.1 Thai CRM Terminology + +- `docs/business/crm-terminology.md` is the source of truth for CRM business labels. +- Use `src/features/crm/shared/terminology.ts` when CRM UI needs shared stage or role labels. +- Keep `CRM` and `Dashboard` in English where the existing product already does so. +- Do not rename schema fields, API routes, or internal codes just to match UI wording. + +## Dashboard Layout Standards + +- Use `PageContainer` for dashboard page framing and page headers. +- Keep pages inside the existing dashboard shell; do not build a separate CRM shell. +- Prefer small, composable sections instead of one oversized page component. +- Use cards, tables, and filter bars consistent with existing CRM dashboard and report pages. + +Reference files: + +- `src/components/layout/page-container.tsx` +- `src/features/crm/dashboard/components/crm-dashboard.tsx` +- `src/features/crm/reports/components/pipeline-report-view.tsx` + +## Bento Grid Guidelines + +- Reuse the existing dashboard-card rhythm: summary cards first, then charts/tables/detail sections. +- Keep KPI modules visually scannable with clear grouping and limited density per row. +- Avoid creating a radically different grid language inside CRM pages. +- Match existing spacing, border radius, and card hierarchy from current dashboard/report pages. + +## Form Standards + +- Use TanStack Form via `@/components/ui/tanstack-form`. +- Use Zod for submit validation. +- Reuse field components from `@/components/forms/fields`. +- Keep labels and helper text business-readable. +- Use ` - - - { - field.handleChange(date ? date.toISOString() : ''); - field.handleBlur(); - }} - disabled={disabled} - initialFocus - /> - - + { + field.handleChange(nextValue); + field.handleBlur(); + }} + /> {description && {description}} diff --git a/src/components/forms/fields/index.tsx b/src/components/forms/fields/index.tsx index 4df4963..d27215b 100644 --- a/src/components/forms/fields/index.tsx +++ b/src/components/forms/fields/index.tsx @@ -8,6 +8,8 @@ export { RadioGroupField } from './radio-group-field'; export { SliderField } from './slider-field'; export { FileUploadField } from './file-upload-field'; export { DatePickerField } from './date-picker-field'; +export { CurrencyField } from './currency-field'; +export { PercentageField } from './percentage-field'; // Composed (standalone, for direct use in forms) export { FormTextField } from './text-field'; @@ -19,3 +21,5 @@ export { FormRadioGroupField } from './radio-group-field'; export { FormSliderField } from './slider-field'; export { FormFileUploadField } from './file-upload-field'; export { FormDatePickerField } from './date-picker-field'; +export { FormCurrencyField } from './currency-field'; +export { FormPercentageField } from './percentage-field'; diff --git a/src/components/forms/fields/percentage-field.tsx b/src/components/forms/fields/percentage-field.tsx new file mode 100644 index 0000000..a446744 --- /dev/null +++ b/src/components/forms/fields/percentage-field.tsx @@ -0,0 +1,52 @@ +'use client'; + +import { useStore } from '@tanstack/react-form'; +import { FieldDescription, FieldLabel } from '@/components/ui/field'; +import { + useFieldContext, + FormFieldSet, + FormField, + FormFieldError, + createFormField +} from '@/components/ui/form-context'; +import { CrmPercentageInput } from '@/features/crm/components/crm-form-controls'; + +interface PercentageFieldProps { + label: string; + description?: string; + required?: boolean; + placeholder?: string; +} + +export function PercentageField({ + label, + description, + required, + placeholder +}: PercentageFieldProps) { + const field = useFieldContext(); + const isTouched = useStore(field.store, (s) => s.meta.isTouched); + const isValid = useStore(field.store, (s) => s.meta.isValid); + const value = useStore(field.store, (s) => s.value) as string | number | undefined; + + return ( + + + + {label} + {required && ' *'} + + field.handleChange(nextValue === '' ? '' : Number(nextValue))} + placeholder={placeholder} + className={isTouched && !isValid ? 'border-destructive' : undefined} + /> + {description && {description}} + + + + ); +} + +export const FormPercentageField = createFormField(PercentageField); diff --git a/src/components/forms/fields/textarea-field.tsx b/src/components/forms/fields/textarea-field.tsx index 2b820c0..548db6d 100644 --- a/src/components/forms/fields/textarea-field.tsx +++ b/src/components/forms/fields/textarea-field.tsx @@ -1,7 +1,6 @@ 'use client'; import { useStore } from '@tanstack/react-form'; -import { Textarea } from '@/components/ui/textarea'; import { FieldDescription, FieldLabel } from '@/components/ui/field'; import { useFieldContext, @@ -10,6 +9,7 @@ import { FormFieldError, createFormField } from '@/components/ui/form-context'; +import { CrmTextarea } from '@/features/crm/components/crm-form-controls'; interface TextareaFieldProps extends Omit< React.ComponentProps<'textarea'>, @@ -20,6 +20,7 @@ interface TextareaFieldProps extends Omit< required?: boolean; maxLength?: number; showCount?: boolean; + size?: 'sm' | 'md' | 'lg'; } export function TextareaField({ @@ -28,6 +29,7 @@ export function TextareaField({ required, maxLength, showCount = !!maxLength, + size = 'md', className, ...textareaProps }: TextareaFieldProps) { @@ -43,8 +45,9 @@ export function TextareaField({ {label} {required && ' *'} -