Files
alla-allaos-fullstack/plans/task-fixcrm.md
phaichayon 5a83040077 task-fix
2026-06-25 16:26:14 +07:00

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 --noEmit passes
  • npm run build passes

Result:

Dashboard Opportunity Rename Compatibility = Fixed
CRM Dashboard Runtime = Restored
Ready to continue Approval + Notification roadmap