# Architecture

## Three-Tier System

```
┌───────────────────────────────────────────────────────────┐
│ TIER 0 — PRODUCT PROFILES                                 │
│  config/product-profiles/taskco-crm-{general,education,   │
│                            realstate,pharma,garments}.php │
│  Activated via AdminApp UI or `setup:crm` CLI             │
└─────────────────────┬─────────────────────────────────────┘
                      │ enables apps + seeds feature pack
                      ▼
┌───────────────────────────────────────────────────────────┐
│ TIER 1 — CoreApp (one nwidart module, headless)           │
│  FieldEngine · PipelineEngine · ActivityEngine            │
│  WorkflowEngine · EntityEngine · LabelEngine              │
│  Proposal scaffold                                        │
│  One ServiceProvider · One migrations/ folder             │
│  NO sidebar entries · NO Inertia pages                    │
└─────────────────────┬─────────────────────────────────────┘
                      │ provides DB tables, models, services, traits
                      ▼
┌───────────────────────────────────────────────────────────┐
│ TIER 2 — CrmApp (separate nwidart module)                 │
│  Lead · Deal · Pipeline · Contact · Activity · Proposal   │
│  Full CRUD + Inertia pages + policies                     │
│  Uses FiresWorkflowEvents → WorkflowDispatcher            │
│  Labels rebranded via LabelResolver + useLabel()          │
└───────────────────────────────────────────────────────────┘
```

## Key Architectural Constraints

| Rule | Detail |
|------|--------|
| CoreApp = headless | No routes, no controllers, no Inertia pages |
| One ServiceProvider | `CoreApp\Providers\CoreAppServiceProvider` boots all 6 engines |
| Seed-driven config | Pipelines, workflow rules, custom fields seeded from JSON packs — Admin UI is Phase 3 |
| WorkflowEngine = headless | Rules in `workflow_rules` table, seeded. Admin UI = Phase 3.1 |
| LabelEngine = DB-backed | `entity_domain_maps` table + `LabelResolver`. NOT config-based |
| Round-robin = WorkflowEngine | Seeded `AssignToUser` rule in pack JSON — NOT hardcoded in controller |
| AI seam = minimal | `score` column + `NullAiHook::computeScore()` returns null. LLM = Phase 3.8 |
| Mutations = redirect() | Never `response()->json()` from Inertia-consumed routes |

## Module Relationship

```
CoreApp
 └── app/
      ├── Providers/CoreAppServiceProvider.php    ← single entry point
      ├── Services/{Engine}/                      ← service classes
      ├── Models/{Engine}/                        ← Eloquent models
      ├── Traits/                                 ← HasCustomFields, HasPipeline, etc.
      └── Contracts/AiHookInterface.php
 └── database/migrations/                        ← all 14 CoreApp migrations

CrmApp/{Module}/
 └── app/
      ├── Http/Controllers/{Module}Controller.php
      ├── Models/{Module}.php                     ← uses CoreApp traits
      ├── ModelFilters/{Module}Filter.php         ← extends CommonFilter
      ├── Services/{Module}Service.php
      ├── Http/Resources/{Module}Resource.php
      └── Policies/{Module}Policy.php
 └── database/migrations/
 └── resources/assets/js/pages/{Module}/
 └── routes/tenant.php
```

## API Surface — v1 Decision

v1 has no public REST API. All CRM data flows through Inertia (server-side rendered props).
The only external surface is the `FireWebhook` action in WorkflowEngine.

**Versioning deferred to Phase 3.** When a mobile app or external integration requires a
public API, add a versioned route group under a new `CrmApp/Api/` module:
```php
// Phase 3 only — do NOT add to existing Inertia controllers
Route::prefix('api/v1/crm')->middleware('auth:sanctum')->group(...);
```

---

## Existing Infrastructure (Reused As-Is)

- `contacts` + `contact_*` tables and `Contact` model — CrmApp/Contact is a CRM *view* over this
- Productivity modules (`Task`, `Note`, `Reminder`, `Event`) — polymorphic links to leads/deals
- `App\ModelFilters\CommonFilter` — provides `status()`, `sortBy()`, date range methods
- `simple_pagination_meta()`, `StatisticsCard`, `DataTable`, `BulkStatusEditModal`
- AdminApp product profile system (`app_managements`, `subscriptions`, etc.)
