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>
7.5 KiB
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_idonly (ProductServiceProvidercontract).
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
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
- Unique opportunity_number per tenant
- Only active pipeline and active stage allowed
- Stage must belong to selected pipeline
- Only one start / won / lost stage per pipeline
- Closed opportunities immutable
- Won opportunities cannot reopen
- Lost opportunities require reason_id or custom_reason
- Win/Loss immutable after close (
is_locked) - Playbook completion tracked; required steps supported
- Forecast computed from open opportunities only
- 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.