4.2 KiB
4.2 KiB
Task D.3: Lead / Enquiry Ownership Refinement
1. Files Added
drizzle/0012_odd_fat_cobra.sqldocs/adr/0011-lead-enquiry-ownership-model.mddocs/implementation/task-d3-lead-enquiry-ownership-refinement.md
2. Files Modified
src/db/schema.tssrc/lib/auth/rbac.tssrc/features/users/components/user-form-sheet.tsxsrc/features/crm/enquiries/api/types.tssrc/features/crm/enquiries/server/service.tssrc/features/crm/quotations/server/service.tssrc/app/api/crm/enquiries/route.tssrc/app/api/crm/enquiries/[id]/route.tssrc/app/api/crm/enquiries/[id]/assign/route.tssrc/app/api/crm/enquiries/[id]/reassign/route.tssrc/app/api/crm/enquiries/[id]/customers/route.tssrc/app/api/crm/enquiries/[id]/followups/route.tssrc/app/api/crm/enquiries/[id]/followups/[followupId]/route.tssrc/app/api/crm/dashboard/route.tssrc/app/api/crm/dashboard/export/route.tssrc/app/dashboard/crm/enquiries/page.tsxsrc/app/dashboard/crm/enquiries/[id]/page.tsxsrc/config/nav-config.tssrc/features/crm/enquiries/components/enquiry-form-sheet.tsxsrc/features/crm/enquiries/components/enquiry-assignment-dialog.tsxsrc/features/crm/enquiries/components/enquiry-columns.tsxsrc/features/crm/enquiries/components/enquiry-detail.tsxsrc/features/crm/enquiries/components/enquiry-cell-action.tsxsrc/features/crm/dashboard/api/types.tssrc/features/crm/dashboard/server/service.tssrc/features/crm/dashboard/components/crm-dashboard.tsxsrc/features/crm/dashboard/components/dashboard-summary-cards.tsxsrc/features/crm/dashboard/components/dashboard-funnel.tsxsrc/features/crm/dashboard/components/dashboard-sales-ranking.tsxsrc/features/crm/dashboard/components/dashboard-followups.tsxsrc/features/crm/dashboard/components/dashboard-hot-projects.tsx
3. Pipeline Changes
- Added
crm_enquiries.pipeline_stage - Allowed values:
leadenquiryclosed_wonclosed_lost
- Backfilled legacy enquiry rows:
- assigned rows ->
enquiry - unassigned rows ->
lead - closed-lost/cancelled status rows ->
closed_lost
- assigned rows ->
- Assign flow now converts
lead -> enquiry - Quotation accepted/lost/rejected outcomes can synchronize linked enquiry lifecycle to won/lost stages
4. Ownership Changes
- Added business role
marketing - Marketing-created records default to
lead - Sales-created records default to
enquiry salesandsales_supportnow use server-enforced own-or-assigned enquiry visibility- managers, admins, and marketing retain broader monitoring visibility
5. Visibility Rules Added
- Marketing can read CRM lead/enquiry monitoring surfaces
- Marketing cannot see quotation pricing or approval analytics
- Enquiry detail hides related quotation links when the user lacks quotation read access
- CRM dashboard hides quotation, revenue, hot-enquiry, sales-ranking, and approval sections when the user lacks those permissions
6. KPI Changes
- Dashboard summary now uses
pipelineStagefor:- lead count
- enquiry count
- won count
- lost count
- User-facing KPI language changed from
OpportunitytoEnquiry - Funnel wording now follows lead -> enquiry -> quotation flow
- Follow-up and ownership labels now use
Enquiry Owner
7. ADR Added
- Added
docs/adr/0011-lead-enquiry-ownership-model.md - This freezes:
- lead ownership
- enquiry ownership
- assignment conversion behavior
- marketing visibility restriction boundaries
- won/lost lifecycle naming
8. Migration Notes
- Apply
drizzle/0012_odd_fat_cobra.sql - Existing
crm_enquiriesrows are backfilled in-place; no new lead table is introduced - Existing forms and APIs remain shared across lead and enquiry flows
- Existing quotation routes remain intact; only linked enquiry lifecycle sync was added
9. Remaining Risks
closed_wonstill has no dedicated timestamp field; lifecycle timing remains coarse- dashboard/export visibility now follows permission boundaries, but any future custom report endpoints must preserve the same commercial-data guardrails
- quotation-to-enquiry lifecycle sync currently depends on quotation status transitions and does not yet model reopen scenarios explicitly
Verification
npx tsc --noEmit