task-b
task-b.1 complere
This commit is contained in:
8
docs/adr/ADR-0006-branch-domain-model.md
Normal file
8
docs/adr/ADR-0006-branch-domain-model.md
Normal file
@@ -0,0 +1,8 @@
|
||||
Current:
|
||||
branch stored in ms_options
|
||||
|
||||
Future:
|
||||
organization_branches table
|
||||
|
||||
Reason:
|
||||
branch will contain business metadata and workflow configuration
|
||||
337
docs/implementation/task-b-template-audit.md
Normal file
337
docs/implementation/task-b-template-audit.md
Normal file
@@ -0,0 +1,337 @@
|
||||
# Task B Template Audit
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
Task B implemented the shared foundation layer for ALLA OS CRM vNext without introducing CRM business modules such as Customer, Contact, Enquiry, Quotation, Approval, KPI, Report, or PDF generation.
|
||||
|
||||
The foundation now provides:
|
||||
|
||||
- Current user context helpers
|
||||
- Organization context helpers
|
||||
- Permission helpers
|
||||
- Branch scope abstraction
|
||||
- Master options service and API
|
||||
- Document sequence service
|
||||
- Audit log helper
|
||||
|
||||
This work follows the Task A convention freeze:
|
||||
|
||||
- `organizationId` remains the tenant boundary
|
||||
- membership and permissions remain organization-scoped
|
||||
- `branchId` is treated as business sub-scope only
|
||||
- existing Auth.js and shared auth helpers are reused rather than replaced
|
||||
|
||||
## 2. Files Added
|
||||
|
||||
### Documentation
|
||||
|
||||
- `docs/implementation/task-b-template-audit.md`
|
||||
|
||||
### Schema / Migration
|
||||
|
||||
- `drizzle/0001_orange_mandarin.sql`
|
||||
- `drizzle/meta/0001_snapshot.json`
|
||||
|
||||
### Foundation Helpers and Services
|
||||
|
||||
- `src/features/foundation/auth-context/types.ts`
|
||||
- `src/features/foundation/auth-context/service.ts`
|
||||
- `src/features/foundation/organization-context/service.ts`
|
||||
- `src/features/foundation/permission/service.ts`
|
||||
- `src/features/foundation/branch-scope/types.ts`
|
||||
- `src/features/foundation/branch-scope/service.ts`
|
||||
- `src/features/foundation/master-options/types.ts`
|
||||
- `src/features/foundation/master-options/service.ts`
|
||||
- `src/features/foundation/master-options/api/types.ts`
|
||||
- `src/features/foundation/master-options/api/service.ts`
|
||||
- `src/features/foundation/master-options/api/queries.ts`
|
||||
- `src/features/foundation/master-options/api/mutations.ts`
|
||||
- `src/features/foundation/master-options/components/columns.tsx`
|
||||
- `src/features/foundation/master-options/components/master-options-table.tsx`
|
||||
- `src/features/foundation/master-options/components/master-options-listing.tsx`
|
||||
- `src/features/foundation/document-sequence/types.ts`
|
||||
- `src/features/foundation/document-sequence/service.ts`
|
||||
- `src/features/foundation/audit-log/types.ts`
|
||||
- `src/features/foundation/audit-log/service.ts`
|
||||
|
||||
### API Route
|
||||
|
||||
- `src/app/api/foundation/master-options/route.ts`
|
||||
|
||||
## 3. Files Modified
|
||||
|
||||
- `src/db/schema.ts`
|
||||
- `src/app/dashboard/crm/settings/master-options/page.tsx`
|
||||
- `drizzle/meta/_journal.json`
|
||||
- `drizzle/meta/0000_snapshot.json`
|
||||
|
||||
## 4. Current User Context Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/auth-context/service.ts`
|
||||
|
||||
Helpers added:
|
||||
|
||||
- `getCurrentUser()`
|
||||
- `requireCurrentUser()`
|
||||
- `getCurrentUserContext()`
|
||||
|
||||
Returned context shape:
|
||||
|
||||
- `user`
|
||||
- `activeOrganization`
|
||||
- `membership`
|
||||
- `permissions`
|
||||
- `businessRole`
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Reuses `auth()` from `src/auth.ts`
|
||||
- Reuses `requireSession()` from `src/lib/auth/session.ts`
|
||||
- Does not duplicate sign-in or session enrichment logic
|
||||
|
||||
## 5. Organization Context Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/organization-context/service.ts`
|
||||
|
||||
Helpers added:
|
||||
|
||||
- `getCurrentOrganization()`
|
||||
- `getActiveOrganizationId()`
|
||||
- `requireOrganizationAccess()`
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Re-exports the existing shared `requireOrganizationAccess()` helper
|
||||
- Reuses current Auth.js active organization state
|
||||
- Preserves `organizationId` as the only tenant boundary
|
||||
|
||||
## 6. Permission Layer Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/permission/service.ts`
|
||||
|
||||
Helpers added:
|
||||
|
||||
- `hasPermission(permission)`
|
||||
- `requirePermission(permission)`
|
||||
- `hasBusinessRole(role)`
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Reuses `memberships.permissions`
|
||||
- Reuses `activeBusinessRole`
|
||||
- Gives `super_admin` a bypass through existing session semantics
|
||||
- Does not introduce a second RBAC model
|
||||
|
||||
## 7. Branch Scope Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/branch-scope/service.ts`
|
||||
|
||||
Helpers added:
|
||||
|
||||
- `getUserBranches()`
|
||||
- `getActiveBranch()`
|
||||
- `validateBranchAccess()`
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- Branches are currently abstracted through master options category `crm_branch`
|
||||
- No CRM branch UI was added
|
||||
- No direct schema migration for a full branch domain model was added
|
||||
- Branch remains a business scope, not a tenant model
|
||||
|
||||
## 8. Master Options Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/master-options/service.ts`
|
||||
- `src/features/foundation/master-options/api/**`
|
||||
- `src/app/api/foundation/master-options/route.ts`
|
||||
|
||||
Schema added in:
|
||||
|
||||
- `src/db/schema.ts` as `msOptions`
|
||||
|
||||
Helpers and services added:
|
||||
|
||||
- `listMasterOptions()`
|
||||
- `getOptionsByCategory()`
|
||||
- `getActiveOptionsByCategory()`
|
||||
|
||||
Supported characteristics:
|
||||
|
||||
- organization-scoped option records
|
||||
- category-based lookup
|
||||
- parent / child option structure
|
||||
- active / inactive state
|
||||
- soft delete via `deletedAt`
|
||||
- reusable query layer for future CRM modules
|
||||
|
||||
Supported category constants:
|
||||
|
||||
- `crm_branch`
|
||||
- `crm_customer_status`
|
||||
- `crm_customer_type`
|
||||
- `crm_enquiry_status`
|
||||
- `crm_quotation_status`
|
||||
- `crm_product_type`
|
||||
- `crm_currency`
|
||||
- `crm_payment_term`
|
||||
- `crm_priority`
|
||||
- `crm_lead_channel`
|
||||
|
||||
## 9. Document Sequence Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/document-sequence/service.ts`
|
||||
|
||||
Schema added in:
|
||||
|
||||
- `src/db/schema.ts` as `documentSequences`
|
||||
|
||||
Helpers added:
|
||||
|
||||
- `previewNextDocumentCode()`
|
||||
- `generateNextDocumentCode()`
|
||||
|
||||
Implementation notes:
|
||||
|
||||
- `preview` does not increment
|
||||
- `generate` increments
|
||||
- generation uses transaction plus row lock behavior
|
||||
- code generation stays on the server
|
||||
|
||||
Current default prefixes:
|
||||
|
||||
- `customer -> CUS`
|
||||
- `contact -> CON`
|
||||
- `enquiry -> ENQ`
|
||||
- `quotation -> QT`
|
||||
- `approval -> APV`
|
||||
|
||||
## 10. Audit Log Output
|
||||
|
||||
Implemented in:
|
||||
|
||||
- `src/features/foundation/audit-log/service.ts`
|
||||
|
||||
Schema added in:
|
||||
|
||||
- `src/db/schema.ts` as `trAuditLogs`
|
||||
|
||||
Helpers added:
|
||||
|
||||
- `auditCreate()`
|
||||
- `auditUpdate()`
|
||||
- `auditDelete()`
|
||||
- `auditAction()`
|
||||
|
||||
Supported fields:
|
||||
|
||||
- `beforeData`
|
||||
- `afterData`
|
||||
- `requestId`
|
||||
- `organizationId`
|
||||
- `branchId`
|
||||
- `userId`
|
||||
- `entityType`
|
||||
- `entityId`
|
||||
- `action`
|
||||
|
||||
## 11. UI Output
|
||||
|
||||
Task B only touched the allowed foundation testing page:
|
||||
|
||||
- `src/app/dashboard/crm/settings/master-options/page.tsx`
|
||||
|
||||
What changed:
|
||||
|
||||
- the page no longer points at the old CRM mock reference query
|
||||
- it now uses the new foundation master options listing flow
|
||||
- it keeps the existing dashboard shell and `PageContainer` pattern
|
||||
- it keeps the existing React Query plus DataTable pattern
|
||||
|
||||
What was intentionally not added:
|
||||
|
||||
- no new dashboard shell
|
||||
- no new design system
|
||||
- no CRM business forms or CRUD screens
|
||||
|
||||
## 12. Reuse From Template / Existing Repo
|
||||
|
||||
Reused foundation from the current repo:
|
||||
|
||||
- `src/auth.ts`
|
||||
- `src/lib/auth/session.ts`
|
||||
- `src/lib/auth/rbac.ts`
|
||||
- `src/lib/api-client.ts`
|
||||
- `src/lib/query-client.ts`
|
||||
- `src/lib/searchparams.ts`
|
||||
- `PageContainer`
|
||||
- existing DataTable primitives
|
||||
- existing React Query hydration pattern
|
||||
- existing Auth.js session enrichment
|
||||
|
||||
Production reference patterns reused:
|
||||
|
||||
- `src/features/products/**`
|
||||
- `src/features/users/**`
|
||||
|
||||
## 13. Migration Still Needed
|
||||
|
||||
Future work still required after Task B:
|
||||
|
||||
- seed data or admin flows for `ms_options`
|
||||
- seed or setup flows for `document_sequences`
|
||||
- actual CRM entity tables and route handlers
|
||||
- mutation-level integration that calls `auditCreate`, `auditUpdate`, `auditDelete`
|
||||
- branch-to-user assignment model if the product needs something stricter than option-based abstraction
|
||||
- replacement of remaining CRM mock services and pages under `src/features/crm/**`
|
||||
|
||||
## 14. Risks
|
||||
|
||||
Known risks after Task B:
|
||||
|
||||
- the foundation tables exist in schema and migration, but runtime depends on applying the migration
|
||||
- branch scope is still abstraction-only and not yet backed by a dedicated operational model
|
||||
- master options page is migrated, but the rest of CRM still points at mock data
|
||||
- some compile errors still exist in legacy CRM mock files outside the Task B foundation scope
|
||||
|
||||
## 15. Verification Notes
|
||||
|
||||
Completed during Task B:
|
||||
|
||||
- generated Drizzle migration for the new foundation tables
|
||||
- formatted the new and changed files
|
||||
- checked TypeScript compilation
|
||||
|
||||
Compilation note:
|
||||
|
||||
- foundation-layer code added for Task B was cleaned up against its own type issues
|
||||
- project-wide `tsc --noEmit` still reports existing errors in legacy CRM mock files outside the new foundation path
|
||||
|
||||
## 16. Task C Readiness
|
||||
|
||||
Task C can now start on top of this foundation with the following ready:
|
||||
|
||||
- shared user and organization context helpers
|
||||
- permission guard helpers
|
||||
- branch access abstraction
|
||||
- option lookup abstraction for statuses and enumerations
|
||||
- server-side document code generation
|
||||
- shared audit logging helper
|
||||
|
||||
Recommended Task C direction:
|
||||
|
||||
- build `Customer` and `Contact` on top of the new foundation services
|
||||
- keep `organizationId` mandatory on all new CRM entities
|
||||
- use `branchId` only as business sub-scope where needed
|
||||
- wire all mutations through sequence and audit helpers where relevant
|
||||
279
docs/implementation/task-b1-foundation-stabilization.md
Normal file
279
docs/implementation/task-b1-foundation-stabilization.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# Task B.1 Foundation Stabilization
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
Task B.1 completed two goals:
|
||||
|
||||
1. Foundation Stabilization
|
||||
2. Production Isolation
|
||||
|
||||
The foundation layer from Task B is now safer to use for Task C because:
|
||||
|
||||
- foundation seed data now exists for master options and document sequences
|
||||
- production CRM routes no longer import legacy CRM mock services
|
||||
- legacy CRM demo code has been isolated under dedicated `crm-demo` paths
|
||||
- TypeScript compilation passes after the route and module isolation changes
|
||||
|
||||
No Customer, Contact, Enquiry, Quotation, Approval, KPI, Report, PDF, or Notification production module was added in this task.
|
||||
|
||||
## 2. Foundation Review
|
||||
|
||||
### 2.1 Schema Review
|
||||
|
||||
Reviewed tables introduced in Task B:
|
||||
|
||||
- `ms_options`
|
||||
- `document_sequences`
|
||||
- `tr_audit_logs`
|
||||
|
||||
Current strengths:
|
||||
|
||||
- all three tables consistently use `organization_id`
|
||||
- `ms_options` supports soft delete through `deleted_at`
|
||||
- `ms_options` has a unique constraint on `(organization_id, category, code)`
|
||||
- `document_sequences` has a unique constraint on `(organization_id, document_type, period, branch_id)`
|
||||
- `tr_audit_logs` supports `before_data`, `after_data`, and `request_id`
|
||||
|
||||
Current migration notes:
|
||||
|
||||
- `ms_options` does not yet enforce a foreign key from `parent_id` back to `ms_options.id`
|
||||
- `document_sequences` does not yet enforce a foreign key to a branch model because branch is still abstraction-only
|
||||
- `tr_audit_logs` does not yet enforce foreign keys to `organizations` or `users`
|
||||
- `tr_audit_logs` could benefit from future read-oriented indexes such as `(organization_id, entity_type, entity_id)` once audit queries are introduced
|
||||
|
||||
Decision:
|
||||
|
||||
- no schema change was made in Task B.1 for the above notes because the task explicitly asked not to change schema unless necessary
|
||||
|
||||
### 2.2 Service Review
|
||||
|
||||
Reviewed foundation services:
|
||||
|
||||
- `auth-context`
|
||||
- `organization-context`
|
||||
- `permission`
|
||||
- `branch-scope`
|
||||
- `master-options`
|
||||
- `document-sequence`
|
||||
- `audit-log`
|
||||
|
||||
Review summary:
|
||||
|
||||
- naming is consistent with Task B expectations
|
||||
- return shapes are now stable enough for Task C
|
||||
- organization-first design is preserved across helpers
|
||||
- error handling is explicit in permission, organization, branch, and seed flows
|
||||
|
||||
Implementation adjustments made in Task B.1:
|
||||
|
||||
- `searchParams` was extended so isolated demo routes no longer break type checks
|
||||
- `crm-demo` compile issues were cleaned up without changing its business behavior
|
||||
- production CRM route tree now uses placeholder or foundation-safe pages only
|
||||
|
||||
## 3. Seed Review
|
||||
|
||||
### 3.1 Foundation Seed Added
|
||||
|
||||
Seed script added:
|
||||
|
||||
- `src/db/seeds/foundation.seed.ts`
|
||||
|
||||
Package scripts updated:
|
||||
|
||||
- `seed:foundation`
|
||||
- `setup:db` now includes `seed:foundation`
|
||||
|
||||
Seed behavior:
|
||||
|
||||
- loads `DATABASE_URL` from `.env.local` or `.env`
|
||||
- reads `organizations` from the database
|
||||
- throws a clear error if no organizations exist
|
||||
- seeds foundation data for every organization found
|
||||
|
||||
### 3.2 Master Options Seeded
|
||||
|
||||
Seeded categories:
|
||||
|
||||
- `crm_branch`
|
||||
- `crm_customer_status`
|
||||
- `crm_customer_type`
|
||||
- `crm_enquiry_status`
|
||||
- `crm_quotation_status`
|
||||
- `crm_product_type`
|
||||
- `crm_currency`
|
||||
- `crm_payment_term`
|
||||
- `crm_priority`
|
||||
- `crm_lead_channel`
|
||||
|
||||
Important notes:
|
||||
|
||||
- seeding is idempotent via `on conflict`
|
||||
- `crm_branch` options are seeded first and reused by document sequence seed
|
||||
- no organization id is hardcoded
|
||||
|
||||
### 3.3 Document Sequence Seeded
|
||||
|
||||
Seeded sequence types:
|
||||
|
||||
- `customer -> CUS`
|
||||
- `contact -> CON`
|
||||
- `enquiry -> ENQ`
|
||||
- `quotation -> QT`
|
||||
- `approval -> APV`
|
||||
|
||||
Behavior:
|
||||
|
||||
- seeded per organization
|
||||
- seeded per seeded branch option
|
||||
- idempotent via `on conflict`
|
||||
- uses the current `YYMM` period
|
||||
- throws clearly if required organization or branch data is unavailable
|
||||
|
||||
## 4. Production Isolation Review
|
||||
|
||||
### 4.1 Production-Ready Path
|
||||
|
||||
Production-safe CRM route path now lives under:
|
||||
|
||||
- `src/app/dashboard/crm/**`
|
||||
|
||||
Current production-safe routes:
|
||||
|
||||
- `/dashboard/crm`
|
||||
- `/dashboard/crm/customers`
|
||||
- `/dashboard/crm/customers/[id]`
|
||||
- `/dashboard/crm/enquiries`
|
||||
- `/dashboard/crm/enquiries/[id]`
|
||||
- `/dashboard/crm/quotations`
|
||||
- `/dashboard/crm/quotations/[id]`
|
||||
- `/dashboard/crm/approvals`
|
||||
- `/dashboard/crm/settings/document-sequences`
|
||||
- `/dashboard/crm/settings/templates`
|
||||
- `/dashboard/crm/settings/master-options`
|
||||
|
||||
Production-safe behavior:
|
||||
|
||||
- no route above imports `@/features/crm-demo/**`
|
||||
- no route above imports mock query/service layers
|
||||
- `master-options` remains connected to the real foundation path
|
||||
- all other CRM production routes are explicit placeholders until Task C and later tasks build real modules
|
||||
|
||||
### 4.2 Legacy Mock Path
|
||||
|
||||
Legacy CRM mock module was moved to:
|
||||
|
||||
- `src/features/crm-demo/**`
|
||||
|
||||
Legacy demo route tree was moved to:
|
||||
|
||||
- `src/app/dashboard/crm-demo/**`
|
||||
|
||||
The old mock flow is still preserved for reference and manual comparison, but it is no longer the production path.
|
||||
|
||||
### 4.3 Route Separation
|
||||
|
||||
Production route:
|
||||
|
||||
- `/dashboard/crm`
|
||||
|
||||
Demo route:
|
||||
|
||||
- `/dashboard/crm-demo`
|
||||
|
||||
Separation achieved:
|
||||
|
||||
- production route tree does not import demo services
|
||||
- demo route tree imports `@/features/crm-demo/**`
|
||||
- demo links inside the moved module now point to `/dashboard/crm-demo/**`
|
||||
|
||||
## 5. Mock Modules Moved
|
||||
|
||||
Moved feature module:
|
||||
|
||||
- `src/features/crm` -> `src/features/crm-demo`
|
||||
|
||||
Moved route tree:
|
||||
|
||||
- `src/app/dashboard/crm` legacy implementation -> `src/app/dashboard/crm-demo`
|
||||
|
||||
Then recreated:
|
||||
|
||||
- `src/app/dashboard/crm/**` as production-safe placeholder/foundation routes
|
||||
|
||||
## 6. Files Added
|
||||
|
||||
### Documentation
|
||||
|
||||
- `docs/implementation/task-b1-foundation-stabilization.md`
|
||||
|
||||
### Foundation Seed
|
||||
|
||||
- `src/db/seeds/foundation.seed.ts`
|
||||
|
||||
### Production CRM Placeholder Support
|
||||
|
||||
- `src/features/foundation/components/crm-production-placeholder.tsx`
|
||||
|
||||
### Production CRM Routes
|
||||
|
||||
- `src/app/dashboard/crm/page.tsx`
|
||||
- `src/app/dashboard/crm/customers/page.tsx`
|
||||
- `src/app/dashboard/crm/customers/[id]/page.tsx`
|
||||
- `src/app/dashboard/crm/enquiries/page.tsx`
|
||||
- `src/app/dashboard/crm/enquiries/[id]/page.tsx`
|
||||
- `src/app/dashboard/crm/quotations/page.tsx`
|
||||
- `src/app/dashboard/crm/quotations/[id]/page.tsx`
|
||||
- `src/app/dashboard/crm/approvals/page.tsx`
|
||||
- `src/app/dashboard/crm/settings/document-sequences/page.tsx`
|
||||
- `src/app/dashboard/crm/settings/templates/page.tsx`
|
||||
- `src/app/dashboard/crm/settings/master-options/page.tsx`
|
||||
|
||||
### Demo Route / Feature Path Created By Move
|
||||
|
||||
- `src/app/dashboard/crm-demo/**`
|
||||
- `src/features/crm-demo/**`
|
||||
|
||||
## 7. Files Modified
|
||||
|
||||
- `package.json`
|
||||
- `src/lib/searchparams.ts`
|
||||
- `src/features/crm-demo/api/service.ts`
|
||||
- `src/features/crm-demo/components/customers-table.tsx`
|
||||
- `src/features/crm-demo/components/enquiries-table.tsx`
|
||||
- `src/features/crm-demo/components/quotations-table.tsx`
|
||||
|
||||
## 8. Production Routes Verified
|
||||
|
||||
Verification result:
|
||||
|
||||
- production `/dashboard/crm/**` no longer depends on legacy CRM mock service imports
|
||||
- `master-options` is the only CRM route currently wired to a real foundation-backed data path
|
||||
- all remaining production CRM routes are intentionally placeholders so Task C can start cleanly
|
||||
|
||||
## 9. Remaining Risks
|
||||
|
||||
- production CRM modules still need real tables and route handlers before the placeholders can be replaced
|
||||
- `tr_audit_logs` has no foreign keys or query indexes yet
|
||||
- branch scope is still option-based abstraction and not a dedicated branch domain model
|
||||
- document sequences are seeded by branch option id, so future branch modeling must preserve or migrate that relationship carefully
|
||||
- `crm-demo` still contains legacy mock business logic by design, even though it is isolated from the production path
|
||||
|
||||
## 10. Task C Readiness
|
||||
|
||||
Task C can begin safely now because:
|
||||
|
||||
- production route tree is no longer tied to mock CRM state
|
||||
- foundation seed data can be created repeatably
|
||||
- document sequences can be initialized for real organizations
|
||||
- production CRM paths are reserved for organization-first implementation
|
||||
- TypeScript compilation passes after the isolation work
|
||||
|
||||
Recommended Task C entry point:
|
||||
|
||||
- build `Customer` and `Contact` on top of:
|
||||
- organization context
|
||||
- permission helpers
|
||||
- branch abstraction
|
||||
- master options
|
||||
- document sequence helper
|
||||
- audit log helper
|
||||
Reference in New Issue
Block a user