Files
alla-allaos-fullstack/plans/task-d.5.5.md
phaichayon f2c7156851 task-d.5.5
2026-06-25 08:27:20 +07:00

433 lines
7.8 KiB
Markdown

# Task D.5.5: Opportunity / Sales Workspace Refinement
## Status
Planned
## Objective
Refine the Sales workspace so enquiries created from leads are presented and operated as Sales Opportunities, while preserving existing enquiry, quotation, dashboard, report, and approval compatibility.
Business boundary:
```txt
Lead = Marketing-owned source record
Opportunity / Enquiry = Sales-owned execution workspace
```
This task does not replace `crm_enquiries`. It improves the sales-facing workspace around it.
---
## Mandatory Review
Review before implementation:
* `AGENTS.md`
* `docs/standards/project-foundations.md`
* `docs/standards/task-catalog.md`
* `docs/adr/0018-lead-enquiry-domain-separation.md`
* `docs/implementation/task-d5-lead-enquiry-domain-separation.md`
* `docs/implementation/task-d52-lead-domain-service-api-foundation.md`
* `docs/implementation/task-d53-lead-assignment-create-enquiry-foundation.md`
* `docs/implementation/task-d54-lead-enquiry-workspace-separation-ui-foundation.md`
* `docs/security/crm-authorization-boundaries.md`
* existing enquiry API/service/UI
* existing quotation conversion flow
---
## Current Foundation
Already available:
```txt
crm_leads
crm_enquiries
crm_enquiries.lead_id
Lead UI
Enquiry UI
Lead Assignment API
Lead -> Enquiry creation
Source Lead display in Enquiry detail
```
Do not recreate:
```txt
tables
migrations
lead assignment service
lead APIs
enquiry APIs
quotation APIs
```
---
## Business Rule
After a Lead is assigned:
```txt
Lead
-> creates / reuses Enquiry
-> Enquiry becomes Sales Opportunity workspace
```
The DB object remains:
```txt
crm_enquiries
```
The sales-facing business wording may display as:
```txt
Opportunity
```
where appropriate.
---
## Scope D5.5.1 Sales Workspace Wording
Refine enquiry UI labels for sales-facing pages.
Recommended display naming:
```txt
Menu: Enquiries or Opportunities
Page title: Opportunities
Detail title: Opportunity Detail
Source label: Source Lead
```
Rules:
* Do not rename database tables
* Do not rename API paths in this task
* Do not break existing `/api/crm/enquiries`
* Avoid global find/replace that may break compatibility
* Keep technical names in code where already established unless safely isolated
---
## Scope D5.5.2 Opportunity List Refinement
Update existing enquiry list to better support Sales workflow.
Recommended columns:
```txt
Enquiry / Opportunity Code
Source Lead
Customer
Project Name
Product Type
Sales Owner
Status
Estimated Value
Chance %
Expected Close Date
Last Follow-up
Next Follow-up
Created Date
```
Recommended filters:
```txt
Sales Owner
Product Type
Status
Customer
Source Lead
Expected Close Date
```
Rules:
* Use existing enquiry API where possible
* Add only non-breaking response fields if needed
* Do not change dashboard/report query contracts
* Preserve current enquiry list behavior for records without `lead_id`
---
## Scope D5.5.3 Opportunity Detail Refinement
Update existing enquiry detail page to make sales execution clearer.
Sections:
```txt
Opportunity Summary
Source Lead
Customer / Contact
Requirement
Sales Qualification
Follow-up Timeline
Quotation Readiness
Linked Quotations
```
Actions:
```txt
Edit Opportunity
Create Follow-up
Create Quotation
Open Source Lead
```
Rules:
* `Source Lead` is read-only
* Marketing users may not get broader enquiry access from this block
* Quotation creation behavior must remain unchanged
* Enquiry records without `lead_id` must still render normally
---
## Scope D5.5.4 Sales Qualification Fields
Use existing enquiry fields:
```txt
requirement
estimatedValue
chancePercent
expectedCloseDate
competitor
priority
status
```
Refine UI grouping only.
Rules:
* Do not add new fields unless already present in schema
* Do not create migration
* Keep validation compatible with existing enquiry service
* Avoid changing required fields that could break legacy creation
---
## Scope D5.5.5 Source Lead Read Model
Enhance enquiry detail read model if needed to include minimal source lead data:
```ts
sourceLead?: {
id: string;
code: string;
projectName?: string | null;
status?: string | null;
awareness?: string | null;
}
```
Rules:
* Only expose source lead if current user can access the enquiry
* Do not widen Lead permission from Enquiry page
* Do not make extra client-side calls if server-side enrichment already exists
---
## Scope D5.5.6 Follow-up Continuity
Keep existing enquiry follow-up architecture.
Rules:
* Sales follow-ups belong to enquiry/opportunity
* Lead follow-ups remain audit-backed from D.5.2 until future persistence decision
* Do not merge lead follow-up and enquiry follow-up timelines in this task
* Optional: show Source Lead activity as read-only if already available and safe
---
## Scope D5.5.7 Quotation Readiness Panel
Add a lightweight readiness panel on Opportunity detail.
Suggested checks:
```txt
Customer selected
Contact selected
Project name present
Product type present
Requirement present
Estimated value present
```
Output:
```txt
Ready to create quotation
Missing required information
```
Rules:
* Informational only
* Do not block quotation creation unless existing service already blocks it
* Do not change quotation service validation
---
## Scope D5.5.8 Permission Handling
Use existing enquiry permissions and CRM access boundaries.
Examples:
```txt
crm.enquiry.read
crm.enquiry.update
crm.enquiry.followup.create
crm.quotation.create
```
Rules:
* Do not check role strings directly
* Hide unauthorized actions
* Handle 403 gracefully
* Backend remains the source of truth
---
## Scope D5.5.9 Documentation
Create:
```txt
docs/implementation/task-d55-opportunity-sales-workspace-refinement.md
```
Document:
```txt
UI wording decisions
routes changed
components changed
API fields added
compatibility notes
known limitations
```
---
## Deliverables
Updated:
```txt
src/app/**/crm/enquiries/page.tsx
src/app/**/crm/enquiries/[id]/page.tsx
```
Updated or added components:
```txt
src/features/crm/enquiries/components/enquiry-list.tsx
src/features/crm/enquiries/components/enquiries-table.tsx
src/features/crm/enquiries/components/enquiry-detail.tsx
src/features/crm/enquiries/components/source-lead-card.tsx
src/features/crm/enquiries/components/quotation-readiness-panel.tsx
```
Optional updated API/read model:
```txt
src/features/crm/enquiries/api/types.ts
src/features/crm/enquiries/server/service.ts
```
Documentation:
```txt
docs/implementation/task-d55-opportunity-sales-workspace-refinement.md
```
---
## Explicit Non-Scope
Do not:
* create new tables
* create migrations
* rename `crm_enquiries`
* rename `/api/crm/enquiries`
* rewrite quotation conversion
* change approval workflow
* change dashboard datasets
* change reports
* implement won/lost synchronization
* migrate legacy enquiry records
* merge lead and enquiry follow-up persistence
* remove `crm_enquiries.pipeline_stage`
These belong to later phases.
---
## Verification
Run:
```txt
npm exec tsc --noEmit
```
Optional:
```txt
npm run lint
npm run build
```
Manual verification:
```txt
Opportunity/Enquiry list still loads
Records with lead_id show Source Lead
Records without lead_id still work
Opportunity detail shows sales execution sections
Create quotation still works
Existing enquiry follow-ups still work
Lead page still opens linked enquiry
Quotation page still works
Dashboard still works
Reports still work
```
---
## Definition of Done
Task is complete when:
* Sales workspace clearly represents assigned enquiries as opportunities
* Existing enquiry API compatibility remains intact
* Source Lead is visible from Opportunity detail
* Quotation readiness is visible but non-blocking
* Existing quotation, dashboard, report, and approval behavior remains unchanged
Result:
```txt
Opportunity Workspace = Refined
Sales Execution UX = Clarified
Lead / Enquiry Boundary = Preserved
Ready for D.5.6 Won / Lost Lifecycle Alignment
```