This commit is contained in:
phaichayon
2026-06-25 16:26:14 +07:00
parent 69279fc341
commit 5a83040077
11 changed files with 547 additions and 64 deletions

305
plans/task-fixcrm.md Normal file
View File

@@ -0,0 +1,305 @@
# 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:
```txt
["crm-dashboard", {...}]
```
This task aligns dashboard, reports, query keys, imports, SQL, DTOs, and permissions with the new Opportunity domain.
---
## Error Context
Observed error:
```txt
A query that was dehydrated as pending ended up rejecting.
[["crm-dashboard", {...}]]: Error: API error: 500 Internal Server Error
```
Likely root cause:
```txt
Dashboard API still references old Enquiry domain after D.5.5.1 rename.
```
Examples of stale references:
```txt
crm_enquiries
crmEnquiries
enquiryId
Enquiry
enquiry-aging
crm.enquiry.*
```
---
## Mandatory Review
Review:
```txt
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:
```bash
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:
```txt
crmOpportunities
crm_opportunities
opportunityId
crm.opportunity.*
```
instead of:
```txt
crmEnquiries
crm_enquiries
enquiryId
crm.enquiry.*
```
Ensure all dashboard metrics still return successfully.
Required dashboard response areas to verify:
```txt
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:
```txt
crm_enquiries
crm_enquiry_followups
crm_enquiry_customers
enquiry_id
```
with:
```txt
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:
```txt
enquiryCount
enquiryPipeline
enquiryValue
enquiryAging
```
to:
```txt
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:
```txt
/api/crm/reports/opportunity-aging
/dashboard/crm/reports/opportunity-aging
```
Remove or replace active references to:
```txt
/api/crm/reports/enquiry-aging
/dashboard/crm/reports/enquiry-aging
```
Update nav config if needed.
---
## Scope 6: Permissions
Replace dashboard/report permission checks:
```txt
crm.enquiry.*
```
with:
```txt
crm.opportunity.*
```
Verify seed/config contains the required permissions:
```txt
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:
```txt
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:
```bash
npm exec tsc --noEmit
npm run build
```
Search validation:
```bash
rg "crmEnquir|crm_enquir|enquiry|Enquiry|enquiryId|crm\.enquiry|/crm/enquiries" src
```
Allowed only if:
```txt
historical docs
comments explicitly marked legacy
migration history
```
Manual verification:
```txt
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:
```txt
Dashboard Opportunity Rename Compatibility = Fixed
CRM Dashboard Runtime = Restored
Ready to continue Approval + Notification roadmap
```