5.4 KiB
Task Fix: CRM Dashboard Opportunity Rename Compatibility
Objective
Fix CRM Dashboard API/runtime errors after the force rename from Enquiry to Opportunity.
The current issue appears when the CRM dashboard query returns 500 Internal Server Error, causing TanStack Query hydration to reject:
["crm-dashboard", {...}]
This task aligns dashboard, reports, query keys, imports, SQL, DTOs, and permissions with the new Opportunity domain.
Error Context
Observed error:
A query that was dehydrated as pending ended up rejecting.
[["crm-dashboard", {...}]]: Error: API error: 500 Internal Server Error
Likely root cause:
Dashboard API still references old Enquiry domain after D.5.5.1 rename.
Examples of stale references:
crm_enquiries
crmEnquiries
enquiryId
Enquiry
enquiry-aging
crm.enquiry.*
Mandatory Review
Review:
src/features/crm/dashboard/**
src/app/api/crm/dashboard/**
src/app/dashboard/crm/**
src/app/api/crm/reports/**
src/app/dashboard/crm/reports/**
src/features/crm/reports/**
src/db/schema.ts
src/features/crm/opportunities/**
src/config/nav-config.ts
src/db/seeds/foundation.seed.ts
Scope 1: Identify Stale References
Run:
rg "crmEnquir|crm_enquir|enquiry|Enquiry|enquiryId|crm\.enquiry|/crm/enquiries" src/features/crm/dashboard src/app/api/crm/dashboard src/app/dashboard/crm src/features/crm/reports src/app/api/crm/reports src/app/dashboard/crm/reports
Expected action:
- Replace active application references with Opportunity terminology.
- Historical docs can remain unchanged.
- No active dashboard/report runtime code should depend on Enquiry naming.
Scope 2: Dashboard API Fix
Update dashboard API/service to use:
crmOpportunities
crm_opportunities
opportunityId
crm.opportunity.*
instead of:
crmEnquiries
crm_enquiries
enquiryId
crm.enquiry.*
Ensure all dashboard metrics still return successfully.
Required dashboard response areas to verify:
summary cards
pipeline counts
sales ranking
follow-up due / overdue
hot projects
quotation summary
won / lost summary
project party filters
Scope 3: SQL / Drizzle Query Fix
Fix all raw SQL and Drizzle queries that reference old table/column names.
Replace:
crm_enquiries
crm_enquiry_followups
crm_enquiry_customers
enquiry_id
with:
crm_opportunities
crm_opportunity_followups
crm_opportunity_customers
opportunity_id
If any remaining DB column intentionally keeps legacy naming, document it and map it at service boundary only.
Scope 4: Dashboard DTO / Mapper Fix
Update dashboard DTOs, mappers, and labels.
Rename:
enquiryCount
enquiryPipeline
enquiryValue
enquiryAging
to:
opportunityCount
opportunityPipeline
opportunityValue
opportunityAging
Rules:
- API response should use Opportunity naming.
- UI labels should use Opportunity naming.
- Do not expose Enquiry naming in active CRM dashboard.
Scope 5: Report Route Compatibility
Verify renamed routes:
/api/crm/reports/opportunity-aging
/dashboard/crm/reports/opportunity-aging
Remove or replace active references to:
/api/crm/reports/enquiry-aging
/dashboard/crm/reports/enquiry-aging
Update nav config if needed.
Scope 6: Permissions
Replace dashboard/report permission checks:
crm.enquiry.*
with:
crm.opportunity.*
Verify seed/config contains the required permissions:
crm.opportunity.read
crm.opportunity.create
crm.opportunity.update
crm.opportunity.delete
crm.opportunity.assign
crm.opportunity.followup.create
crm.opportunity.followup.update
crm.opportunity.followup.delete
crm.opportunity.lifecycle.update
crm.opportunity.lifecycle.reopen
Scope 7: Error Handling Improvement
Prevent dashboard SSR hydration from failing hard when API returns an error.
Improve dashboard query behavior:
- Server prefetch should catch API failure and return a safe empty dashboard model, or
- Client component should render an error state instead of causing hydration failure.
Do not hide backend errors in development logs.
Recommended:
dashboard API logs detailed server error
dashboard UI shows recoverable error message
query fallback uses empty dashboard model only when safe
Scope 8: Verification
Run:
npm exec tsc --noEmit
npm run build
Search validation:
rg "crmEnquir|crm_enquir|enquiry|Enquiry|enquiryId|crm\.enquiry|/crm/enquiries" src
Allowed only if:
historical docs
comments explicitly marked legacy
migration history
Manual verification:
Open CRM Dashboard
Dashboard API returns 200
No TanStack hydration rejection
Opportunity counts render
Quotation counts render
Won/Lost summary renders
Sales ranking renders
Follow-up widgets render
Hot project widgets render
Opportunity aging report opens
Navigation links use opportunity routes
Definition of Done
Task is complete when:
- CRM Dashboard no longer returns 500
- Dashboard no longer references active Enquiry domain
- Reports use Opportunity naming
- Permissions use
crm.opportunity.* - API response and UI labels use Opportunity terminology
- TanStack hydration error is gone
npm exec tsc --noEmitpassesnpm run buildpasses
Result:
Dashboard Opportunity Rename Compatibility = Fixed
CRM Dashboard Runtime = Restored
Ready to continue Approval + Notification roadmap