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