task-b.1
complere
This commit is contained in:
phaichayon
2026-06-15 11:19:31 +07:00
parent 89b39cad38
commit b8cd39eaa4
55 changed files with 4295 additions and 1848 deletions

View 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

View 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