Add the Sales CRM service through collaboration, sync architecture/registry docs, expose crm.torbatyar.ir, and include a production deploy script. Co-authored-by: Cursor <cursoragent@cursor.com>
215 lines
7.5 KiB
Markdown
215 lines
7.5 KiB
Markdown
# Phase 6.2 — Enterprise Sales Process Engine
|
||
|
||
| Field | Value |
|
||
| --- | --- |
|
||
| Status | Complete |
|
||
| Module | crm |
|
||
| Version | 0.6.2.0 |
|
||
| Database | `crm_db` |
|
||
| Migration | `0003_phase_62_sales_engine` |
|
||
| Depends On | Phase 6.1 |
|
||
|
||
## Goal
|
||
|
||
Implement the Sales CRM **Enterprise Sales Process Engine** only: opportunities, pipelines, stages, playbooks, stage history, opportunity products/contacts/competitors, win/loss analysis, rule-based forecasts, goals, targets, and sales audit.
|
||
|
||
Out of scope: Workflow Platform, Automation, Customer360, Marketing, Communication, Helpdesk, Analytics, AI, Accounting / Restaurant / Marketplace integrations.
|
||
|
||
## Sales Architecture
|
||
|
||
```
|
||
API → Opportunity / Pipeline / Playbook / Forecast / Goal / Target / WinLoss / Audit Services
|
||
→ Validators (stage, pipeline, opportunity, playbook, forecast, goal, win/loss)
|
||
→ Repositories (tenant-scoped)
|
||
→ Models (independent aggregates, UUID refs)
|
||
→ Events (publish-only EventEnvelope)
|
||
```
|
||
|
||
- Unlimited pipelines per tenant (Retail, Enterprise, Restaurant, Marketplace, Government, Custom).
|
||
- Stage transitions validated (active pipeline/stage, stage∈pipeline).
|
||
- Closed opportunities immutable; won cannot reopen; lost requires reason.
|
||
- Forecasts are rule-based (pipeline / weighted / committed) — no ML.
|
||
- Products store `product_ref_id` only (`ProductServiceProvider` contract).
|
||
|
||
## Opportunity Model
|
||
|
||
| Field | Notes |
|
||
| --- | --- |
|
||
| opportunity_number | Unique per tenant |
|
||
| title / name | Synced on create/update |
|
||
| organization_id, contact_id, lead_id | UUID refs |
|
||
| pipeline_id, stage_id | Active + stage belongs to pipeline |
|
||
| expected_revenue, amount, currency_code | |
|
||
| probability, priority, owner_user_id | |
|
||
| expected_close_date, won_at, lost_at | |
|
||
| status | open / won / lost |
|
||
| Soft delete + actor audit | |
|
||
|
||
## Pipeline Model
|
||
|
||
| Field | Notes |
|
||
| --- | --- |
|
||
| name, code, description | code unique per tenant |
|
||
| sort_order, is_default, is_active, status | |
|
||
|
||
### Pipeline Stages
|
||
|
||
| Field | Notes |
|
||
| --- | --- |
|
||
| position, win_probability, color | |
|
||
| is_start_stage / is_won_stage / is_lost_stage / is_closed_stage | Only one start, one won, one lost |
|
||
| required_fields, exit_validation | JSON |
|
||
|
||
## Playbook Architecture
|
||
|
||
- `sales_playbooks` (versioned code+version unique)
|
||
- `sales_playbook_steps` (required/recommended/checklist/template)
|
||
- `sales_playbook_assignments` (pipeline or opportunity; completion tracking)
|
||
- Events: `crm.playbook.assigned`, `crm.playbook.completed`
|
||
|
||
## Forecast Model
|
||
|
||
Rule-based over open opportunities in period:
|
||
|
||
| Metric | Rule |
|
||
| --- | --- |
|
||
| pipeline_amount | Sum expected_revenue |
|
||
| weighted_amount | Sum revenue × probability/100 |
|
||
| committed_amount | Sum revenue where probability ≥ 80 |
|
||
|
||
Periods: monthly / quarterly / annual. Kinds: pipeline / weighted / committed.
|
||
|
||
## Goal Model
|
||
|
||
Scopes: individual / team / department. Metrics: revenue / opportunity_count.
|
||
|
||
## Target Model
|
||
|
||
Periods: monthly / quarterly / annual. Tracks `actual_value` and `achievement_percent`.
|
||
|
||
## Win/Loss Model
|
||
|
||
Immutable snapshot on close (`opportunity_win_loss.is_locked`):
|
||
|
||
- Categories + reasons (won/lost)
|
||
- Root cause, competitor, price/feature/timing/relationship/approval factors, custom reason
|
||
|
||
## ER Diagram
|
||
|
||
```mermaid
|
||
erDiagram
|
||
PIPELINE ||--o{ PIPELINE_STAGE : contains
|
||
PIPELINE ||--o{ OPPORTUNITY : routes
|
||
PIPELINE_STAGE ||--o{ OPPORTUNITY : current
|
||
OPPORTUNITY ||--o{ SALES_STAGE_HISTORY : history
|
||
OPPORTUNITY ||--o{ OPPORTUNITY_PRODUCT : lines
|
||
OPPORTUNITY ||--o{ OPPORTUNITY_CONTACT : roles
|
||
OPPORTUNITY ||--o{ OPPORTUNITY_COMPETITOR : rivals
|
||
OPPORTUNITY ||--o| OPPORTUNITY_WIN_LOSS : analysis
|
||
SALES_PLAYBOOK ||--o{ SALES_PLAYBOOK_STEP : steps
|
||
SALES_PLAYBOOK ||--o{ SALES_PLAYBOOK_ASSIGNMENT : assignments
|
||
OPPORTUNITY ||--o{ SALES_PLAYBOOK_ASSIGNMENT : assigned
|
||
WIN_LOSS_CATEGORY ||--o{ WIN_LOSS_REASON : categorizes
|
||
SALES_GOAL ||--o{ SALES_TARGET : measured
|
||
SALES_PROCESS }o--|| PIPELINE : optional
|
||
```
|
||
|
||
## Business Rules
|
||
|
||
1. Unique opportunity_number per tenant
|
||
2. Only active pipeline and active stage allowed
|
||
3. Stage must belong to selected pipeline
|
||
4. Only one start / won / lost stage per pipeline
|
||
5. Closed opportunities immutable
|
||
6. Won opportunities cannot reopen
|
||
7. Lost opportunities require reason_id or custom_reason
|
||
8. Win/Loss immutable after close (`is_locked`)
|
||
9. Playbook completion tracked; required steps supported
|
||
10. Forecast computed from open opportunities only
|
||
11. Everything tenant-aware and auditable (`sales_audit`)
|
||
|
||
## Validation Rules
|
||
|
||
| Validator | Covers |
|
||
| --- | --- |
|
||
| Opportunity | number, amount, currency, probability, mutability |
|
||
| Pipeline | active status, code uniqueness |
|
||
| Stage | flags mutual exclusion, duplicate start/won/lost |
|
||
| Playbook | version uniqueness, assignment target, step membership |
|
||
| Forecast | period dates, non-empty name |
|
||
| Goal / Target | non-negative values, achievement % |
|
||
| WinLoss | lost reason required, locked snapshot |
|
||
|
||
## Events
|
||
|
||
| Event | When |
|
||
| --- | --- |
|
||
| `crm.opportunity.created` | Opportunity created |
|
||
| `crm.opportunity.updated` | Opportunity updated |
|
||
| `crm.pipeline.changed` | Pipeline updated |
|
||
| `crm.stage.changed` | Opportunity stage changed |
|
||
| `crm.playbook.assigned` | Playbook assigned |
|
||
| `crm.playbook.completed` | Assignment 100% complete |
|
||
| `crm.opportunity.won` | Opportunity won |
|
||
| `crm.opportunity.lost` | Opportunity lost |
|
||
| `crm.forecast.updated` | Forecast computed |
|
||
|
||
## Permissions
|
||
|
||
- `crm.opportunities.*`
|
||
- `crm.pipelines.*`
|
||
- `crm.playbooks.*`
|
||
- `crm.forecasts.*`
|
||
- `crm.goals.*`
|
||
- `crm.targets.*`
|
||
|
||
## API Endpoints
|
||
|
||
| Method | Path |
|
||
| --- | --- |
|
||
| POST/GET/PATCH | `/api/v1/pipelines`, `/pipelines/{id}` |
|
||
| POST/GET/PATCH | `/api/v1/pipelines/stages`, `/pipelines/{id}/stages` |
|
||
| POST/GET/PATCH | `/api/v1/opportunities`, `/opportunities/{id}` |
|
||
| POST | `/api/v1/opportunities/{id}/stage` |
|
||
| GET | `/api/v1/opportunities/{id}/stage-history` |
|
||
| POST | `/api/v1/opportunities/{id}/win`, `/lose` |
|
||
| POST/GET | `/api/v1/sales-processes` |
|
||
| POST/GET | `/api/v1/playbooks`, steps, assignments, complete-step |
|
||
| POST/GET | `/api/v1/forecasts/compute`, `/forecasts` |
|
||
| POST/GET | `/api/v1/goals`, `/targets` |
|
||
| POST | `/api/v1/opportunity-products`, `opportunity-contacts`, `opportunity-competitors` |
|
||
| POST/GET | `/api/v1/win-loss/categories`, `reasons`, `opportunities/{id}` |
|
||
|
||
## Migration Summary
|
||
|
||
- Revision: `0003_phase_62_sales_engine` (down: `0002_phase_61_entities`)
|
||
- Creates sales engine tables via metadata `create_all`
|
||
- Opportunity / Pipeline / Stage columns expanded in models (greenfield / test recreate)
|
||
|
||
## Tests Executed
|
||
|
||
- Model / repository / service / API
|
||
- Pipeline & stage rules
|
||
- Playbook / forecast / win-loss / business rules
|
||
- Migration head `0003`
|
||
- Permissions / audit / tenant isolation / documentation
|
||
|
||
## Known Limitations
|
||
|
||
- Forecast is rule-based only (no predictive ML)
|
||
- Product lines reference Product Service by ID — no inventory sync
|
||
- Existing production DBs may need manual column alters if upgraded from pre-6.2 opportunity schema (phase migrations use additive `create_all`)
|
||
- Sales team / dashboard metadata deferred to later phase
|
||
|
||
## Next Phase
|
||
|
||
Phase 6.3 — Enterprise Sales Collaboration Platform.
|
||
|
||
## Related Documents
|
||
|
||
- [Progress](progress.md)
|
||
- [Phase 6.0](crm-phase-6-0.md)
|
||
- [Phase 6.1](crm-phase-6-1.md)
|
||
- [Phase 6.3](crm-phase-6-3.md)
|
||
- [Module Registry](module-registry.md#crm)
|