# CRM Plan — CoreApp + CrmApp [v2]

> **Restructured 2026-05-06.** This file is the architecture index only.
> Implementation detail lives in the per-phase files below.

---

## Phase Index

| File | Scope |
|------|-------|
| [phases/phase0.md](phases/phase0.md) | Scaffolding — directories, PSR-4, Inertia glob, service providers |
| [phases/phase1.md](phases/phase1.md) | Engine Foundations + Seed-Based Configuration (1.1–1.15) |
| [phases/phase2.md](phases/phase2.md) | v1 CRM End-to-End — Lead, Deal, Pipeline, Contact, Activity (2.1–2.14) |
| [phases/phase3.md](phases/phase3.md) | Deferred Admin UIs (3.1–3.9) |

## Quick Navigation

| Category | Files |
|----------|-------|
| Status + orientation | [plan-summary.md](plan-summary.md) |
| **Phased module roadmap (v1 / v1.5 / v2)** | **[roadmap.md](roadmap.md)** |
| Global rules | [_core/architecture.md](_core/architecture.md) · [_core/database.md](_core/database.md) · [_core/risks.md](_core/risks.md) · [_core/conventions.md](_core/conventions.md) |
| Engine specs | [engines/field-engine.md](engines/field-engine.md) · [engines/pipeline-engine.md](engines/pipeline-engine.md) · [engines/activity-engine.md](engines/activity-engine.md) · [engines/workflow-engine.md](engines/workflow-engine.md) · [engines/entity-engine.md](engines/entity-engine.md) · [engines/label-engine.md](engines/label-engine.md) |
| Feature packs | [packs/overview.md](packs/overview.md) · [packs/default.md](packs/default.md) · [packs/education.md](packs/education.md) · [packs/real-estate.md](packs/real-estate.md) · [packs/pharma.md](packs/pharma.md) · [packs/garments.md](packs/garments.md) |
| Module specs | [modules/lead.md](modules/lead.md) · [modules/deal.md](modules/deal.md) · [modules/pipeline.md](modules/pipeline.md) · [modules/contact.md](modules/contact.md) · [modules/activity.md](modules/activity.md) |
| Provisioning | [setup.md](setup.md) |

---

## Main Rule

> **Don't maximize flexibility early — maximize stability.**

- **No abstraction before the second use case.**
- **No plug-in registries before the second plug-in.**
- **Defer management UI.** Every engine is headless until a user actually needs to click it.
- **Seed-driven configuration.** Pipelines, workflow rules, custom fields, domain maps — seeded from JSON packs. Admin UI is Phase 3.
- **Don't version-gate with feature flags.** A commented-out migration is acceptable; a runtime flag toggling half-built logic is not.
- **Don't build seams that aren't exercised.** AI seam = `score` column + `NullAiHook` only.
- **Ship the smallest thing that works end-to-end first.** Index → Create → Edit → Show before Board.

---

## What Ships Per Phase

### Phase 0 — Scaffolding (no business logic)
Directory tree, PSR-4 registration, `modules_statuses.json`, Inertia glob, service provider stubs.
→ [phases/phase0.md](phases/phase0.md)

### Phase 1 — Engine Foundations (headless, no Inertia pages)

| Component | Deliverable |
|-----------|-------------|
| CoreApp/FieldEngine | `custom_fields`, `custom_field_values`, `HasCustomFields`, `CustomFieldResolver` |
| CoreApp/PipelineEngine | `pipelines`, `pipeline_stages`, `pipeline_stage_transitions`, `HasPipeline` |
| CoreApp/ActivityEngine | `activity_logs`, `HasActivityTimeline` |
| CoreApp/WorkflowEngine | `workflow_rules`, `workflow_runs`, `WorkflowDispatcher`, 7 action classes, `FiresWorkflowEvents`, `AiHookInterface`, `NullAiHook` |
| CoreApp/EntityEngine | `entity_types`, `entity_relationships`, `EntityRegistry` |
| CoreApp/LabelEngine | `entity_domain_maps`, `LabelResolver`, `LabelContext`, `useLabel()` |
| CrmApp/Proposal scaffold | `proposal_templates`, `proposals`, `proposal_approvals`, `ProposalService` — data layer only |
| 5 feature packs (fully authored) | `default_crm_pack`, `education_pack`, `real_estate_pack`, `pharma_pack`, `garments_pack` |
| `FeaturePackSeeder` | Idempotent upsert of all pack data |
| `setup:crm` command | `--profile=`, `--tenant=`, `--dry-run` |
| 5 product profile PHP files | `feature_pack` + `domain_map` keys |
| Hybrid storage + status enums | Searchable columns in migrations; `LeadStatusEnum`/`DealStatusEnum` |

→ [phases/phase1.md](phases/phase1.md)

### Phase 2 — v1 CRM Application

| Component | Deliverable |
|-----------|-------------|
| CrmApp/Lead | Full CRUD + bulk + convert + `FiresWorkflowEvents` |
| CrmApp/Deal | Full CRUD + Kanban board |
| CrmApp/Pipeline | Read-only JSON endpoint |
| CrmApp/Contact | CRM view at `/crm/contacts` |
| CrmApp/Activity | Timeline widget + global feed |
| Round-robin auto-assign | Via WorkflowEngine seeded rule — not hardcoded in controller |
| DB-backed label rebranding | `LabelResolver` + `useLabel()` |
| Authorization | `LeadPolicy`, `DealPolicy` |
| Registry wiring + sidebar | `CoreApp.php`, `CrmApp.php`, `AppRegistry.php`, menu items |
| 9 feature tests | CI gate |
| 5 user journeys | End-to-end validation per profile |

→ [phases/phase2.md](phases/phase2.md)

### Phase 3 — Deferred Admin UIs

WorkflowEngine rule builder, EntityEngine CRUD, Pipeline management UI, Proposal UI,
Contact Segments, Feature Pack import/export, Stub-profile content refinement,
AI pipeline (LLM), Observability panel.

→ [phases/phase3.md](phases/phase3.md)

---

## Architecture (Three-Tier)

```
┌──────────────────────────────────────────────────────────────────────────┐
│ TIER 0 — PRODUCT PROFILES                                                │
│  config/product-profiles/taskco-crm-{general,education,                  │
│                                       realstate,pharma,garments}.php     │
│  Activated via AdminApp → Settings → Product Profile  or  setup:crm CLI  │
└───────────────────────────┬──────────────────────────────────────────────┘
                            │ enables apps + seeds feature pack
                            ▼
┌──────────────────────────────────────────────────────────────────────────┐
│ TIER 1 — CoreApp (one nwidart module, headless — no sidebar, no pages)   │
│                                                                          │
│  FieldEngine     PipelineEngine    ActivityEngine   WorkflowEngine        │
│  LabelEngine     EntityEngine      Proposal scaffold                     │
│  (one ServiceProvider, one migrations/ folder, one composer.json)        │
└───────────────────────────┬──────────────────────────────────────────────┘
                            │ provides DB tables, models, services, traits
                            ▼
┌──────────────────────────────────────────────────────────────────────────┐
│ TIER 2 — CrmApp (application modules with Inertia pages + CRUD)          │
│  Lead · Deal · Pipeline · Contact · Activity · Proposal (Phase 3)        │
│  ↓ uses FiresWorkflowEvents → WorkflowDispatcher fires seeded rules      │
│  ↓ labels rebranded via LabelResolver + useLabel()                       │
└──────────────────────────────────────────────────────────────────────────┘
```

**CoreApp is one nwidart module** — not six modules. All engines share one `ServiceProvider`,
one `migrations/` folder, one `composer.json`.

**WorkflowEngine is headless and seed-driven.** Rules live in `workflow_rules`, seeded from
pack JSON. Admin UI for managing rules is Phase 3.1.

**LabelEngine uses the database** (`entity_domain_maps`, `LabelResolver`, per-request cache).
Labels are NOT config-based.

---

## DB Migration Scope

### Central DB (`AdminApp/database/migrations/`) — NO new migrations
CoreApp + CrmApp app/module/feature rows are **seeded**, not migrated.
Existing tables (`app_managements`, `module_managements`, `feature_managements`,
`packages`, `subscriptions`) are reused as-is.

### Tenant DB — 16 new tables

| Module | Tables |
|--------|--------|
| CoreApp/FieldEngine | `custom_fields`, `custom_field_values` |
| CoreApp/PipelineEngine | `pipelines`, `pipeline_stages`, `pipeline_stage_transitions` |
| CoreApp/ActivityEngine | `activity_logs` |
| CoreApp/WorkflowEngine | `workflow_rules`, `workflow_runs` |
| CoreApp/EntityEngine | `entity_types`, `entity_relationships` |
| CoreApp/LabelEngine | `entity_domain_maps` |
| CrmApp/Lead | `leads` |
| CrmApp/Deal | `deals` |
| CrmApp/Proposal scaffold | `proposal_templates`, `proposals`, `proposal_approvals` |
| CrmApp/Contact | *(no new tables — CRM view over existing `contacts`)* |
| CrmApp/Pipeline | *(no tables — reads PipelineEngine)* |
| CrmApp/Activity | *(no tables — reads ActivityEngine + Productivity)* |

---

## Risk Register

> Full mitigation specs live in the phase files where each risk is addressed.

| Risk | Addressed in |
|------|-------------|
| R1 — Custom field query performance (hybrid storage) | Phase 1.9 |
| R2 — Tenant job consistency (`setup:crm` idempotency) | Phase 1.13 |
| R3 — Lead conversion transaction safety | Phase 2.1 |
| R4 — Feature pack conflicts (additive-only seeder) | Phase 1.12 |
| R5 — WorkflowEngine loop guard | Phase 1.4 |

---

## Seeder Scope

| Seeder | DB target | Trigger |
|--------|-----------|---------|
| `FeatureManagement/CoreApp.php` | Central | `db:seed` on admin |
| `FeatureManagement/CrmApp.php` | Central | `db:seed` on admin |
| `CrmEntityTypeSeeder` | Tenant | `setup:crm` or provisioning hook |
| `FeaturePackSeeder` | Tenant | `setup:crm` or `ProductProfileSeeder` hook |

Both tenant seeders run **synchronously inside tenant context** — not queued.

---

## Critical Files (all paths relative to `app/`)

### Modified
| File | Change |
|------|--------|
| `composer.json` | PSR-4 + merge-plugin for CoreApp, CrmApp |
| `modules_statuses.json` | Enable all new modules |
| `resources/js/app.tsx` | Globs for CoreApp, CrmApp |
| `AdminApp/database/seeders/FeatureManagement/Contracts/AppRegistry.php` | Register CoreApp + CrmApp |
| `AdminApp/database/seeders/FeatureManagement/CrmApp.php` | Replace stub with full definition |
| `resources/js/components/menuItems/menuLists/application-menu-items.tsx` | CRM menu group |
| `AdminApp/database/seeders/ProductProfileSeeder.php` | domain_map upsert + feature_pack seeder call |
| `app/Http/Middleware/HandleInertiaRequests.php` | Share `labels` via `LabelResolver` |

### Created (new)
```
CoreApp/{FieldEngine,PipelineEngine,ActivityEngine,WorkflowEngine,EntityEngine,LabelEngine}/
CrmApp/{Lead,Deal,Pipeline,Contact,Activity,Proposal}/
AdminApp/database/seeders/FeatureManagement/CoreApp.php
AdminApp/database/seeders/CrmEntityTypeSeeder.php
AdminApp/database/seeders/FeaturePackSeeder.php
AdminApp/app/Console/Commands/SetupCrmCommand.php
AdminApp/config/product-profiles/taskco-crm-{general,education,realstate,pharma,garments}.php
AdminApp/data/crm/entity_types.json
AdminApp/data/crm/feature-packs/{default_crm_pack,education_pack,real_estate_pack,pharma_pack,garments_pack}.json
resources/js/contexts/label-context.tsx
resources/js/components/crm/dynamic-fields.tsx
```

### Reused (no change)
- Existing `contacts` + `contact_*` tables and `Contact` model
- Productivity `Task`, `Note`, `Reminder`, `Event` modules
- `App\ModelFilters\CommonFilter`, `simple_pagination_meta()`, `StatisticsCard`, `DataTable`, `BulkStatusEditModal`
