# 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
```
