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