# PLG Suite — Technical Architecture

**The engineering blueprint the playbook deliberately isn't.** This is how the five
products (AiCare, AiCode, AiGuide, AiReview, Gazal) get built as *one platform
instantiated five times*, not five separate builds.

> Status: v0.1 — foundation scaffolded. The `plg_core` engine is real, runnable and
> tested (`python3 scripts/verify.py`); everything else here is the target design.

---

## 1. The one-sentence thesis

> An **inference engine** (Gazal) + a **PLG control plane** (`plg_core`) + **thin
> product apps** (config-driven) = the whole suite. Build the shared parts once;
> each new product is a config file plus a thin app.

This is why "make every part happen" is tractable. The expensive, reusable machinery
is built and maintained once.

---

## 2. System architecture

```
                        ┌──────────────────────────────────────────────┐
                        │                 PRODUCT APPS                   │
                        │  AiCare   AiCode   AiGuide   AiReview   (UI)   │
                        │  (thin; each reads products/<name>.json)       │
                        └───────────────┬───────────────┬───────────────┘
                                        │               │
                  ┌─────────────────────▼───────────────▼───────────────┐
                  │              PLG CONTROL PLANE  (plg_core)            │
                  │  config · events · pql(score) · roi · lifecycle ·    │
                  │  billing(Stripe+M-Pesa) · compliance(audit) ·        │
                  │  lifecycle-email · admin/CS dashboard                 │
                  └───────┬───────────────────────────┬──────────────────┘
                          │                           │
            ┌─────────────▼─────────────┐   ┌─────────▼──────────────────┐
            │   GAZAL — inference engine │   │  DATA & INFRA (per region) │
            │  OpenAI-compatible API,    │   │  Postgres · object store · │
            │  formulary-aware, in-region│   │  event stream · cache ·    │
            │  (also a standalone product)│  │  immutable audit log       │
            └────────────────────────────┘   └────────────────────────────┘
```

**Key move:** AiCare and AiGuide call **Gazal** for AI — in-region — instead of an
external LLM. That single decision resolves the data-residency contradiction across
the suite (no PHI leaves the boundary).

---

## 3. Components

### 3.1 `plg_core` — the control plane (built; this repo)
| Module | Responsibility | State |
|---|---|---|
| `config` | Load per-product Configuration Block | ✅ done |
| `pql` | Health/PQL score (0–100, normalized, capped) | ✅ done + tested |
| `roi` | Value-realized engine (savings / recovery / usage) | ✅ done + tested |
| `lifecycle` | Account state machine (Convert before Expand) | ✅ done + tested |
| `events` | Event taxonomy + ingestion interface | 🔧 interface stub |
| `billing` | Stripe + M-Pesa adapters (subscriptions, dunning, proration) | 🔧 interface stub |
| `compliance` | Immutable audit log, breach hooks, report generation | 🔧 interface stub |

### 3.2 Gazal — the inference engine
OpenAI-compatible REST (`/v1/messages`), healthcare-tuned, formulary-aware, hosted
in-region. Standalone developer product **and** the AI backend for AiCare/AiGuide.

### 3.3 Product apps
Thin front-ends + product-specific domain logic (e.g. AiCare's patient record, AiCode's
chart→code review). Everything growth-related (trial, activation, scoring, billing,
compliance) comes from `plg_core`.

---

## 4. Per-product instantiation

Adding/operating a product = **one JSON file** in `/products`. The engine reads:
`value_metric`, `activation_event`, `pricing`, `pql.components`, `roi`, `regions`,
`compliance_regime`, `ai_inference_mode`. No engine code changes. (Proven: `verify.py`
runs all five off their configs today.)

---

## 5. Data model (core entities)

```
Account ─┬─ Workspace (region-pinned) ─┬─ Users (roles)
         │                             ├─ DomainData (patients/charts/claims/…)
         │                             └─ Integrations (EHR/labs/claims feed)
         ├─ Subscription (plan, seats, billing rail, status)
         ├─ Events (append-only product-analytics stream)
         ├─ PQLSnapshot (score + breakdown, every 6h)
         ├─ ROISnapshot (value realized, for the Day-14 trigger)
         └─ AuditLog (immutable; who/what/when/why + confidence for AI)
```

Region pinning is at the Workspace level → data residency is enforced by construction.

---

## 6. Core data flows

- **Activation:** app emits events → `events` → `pql.score` recomputes → crosses
  `threshold_activated` → lifecycle → activation nudges.
- **Day-14 ROI:** scheduled job runs `roi.compute` per account → if value ≥ threshold
  **and** PQL ≥ activated → send ROI message → track open/click/convert.
- **Convert → Expand:** first paid action → `billing` → `lifecycle` → CONVERTED;
  only then can PQL ≥ expansion move to EXPANDING (enforced in `lifecycle.next_state`).
- **AI call (AiCare/AiGuide):** app → `plg_core` policy (minimize/de-identify) → Gazal
  in-region → response + audit-log entry (reason/confidence).

---

## 7. Data, privacy & AI governance

- **Residency by construction:** workspace pinned to region; primary data + inference
  stay in-region (Gazal) or use a zero-retention endpoint under DPA/BAA.
- **No training on customer data** without explicit consent.
- **Per-market regulators (config-driven):** KE ODPC/PPB · EG PDPL/EDA · AE PDPL/MOHAP ·
  US HIPAA(OCR) · MENA PDPL/SFDA. Breach notification windows per market (KE 72h, US OCR rule).
- **Clinical safety:** AiCare/AiGuide AI is decision-support, human-in-the-loop, with
  override logging; confirm SaMD classification per market before launch.

---

## 8. Recommended tech stack

| Layer | Choice (recommended) | Why |
|---|---|---|
| Control-plane services | Python (FastAPI) | matches `plg_core`; fast to build |
| Product app UIs | Next.js / React + TypeScript | PLG-grade web UX, in-app guidance |
| Data | Postgres (per region) + object store | residency, audit |
| Events/analytics | product-analytics SDK + warehouse | funnel/PQL inputs |
| Inference | Gazal (vLLM/triton behind FastAPI gateway) | in-region, OpenAI-compatible |
| Billing | Stripe + M-Pesa (Daraja API) | global + local rails |
| Infra | Azure (Africa + Middle East regions) | residency the suite needs |
| In-app guidance | Pendo/Appcues (or in-house overlays) | learn-by-doing onboarding |

---

## 9. Build sequence (waves)

- **Wave 0 (now):** architecture + `plg_core` engine (✅) + demo + backlog.
- **Wave 1:** Gazal (engine + standalone dev product) on the control plane.
- **Wave 2:** AiGuide (thin, on Gazal) + AiCare onboarding.
- **Wave 3:** AiCode + AiReview (revenue-cycle, enterprise motion).

Each wave: build → instrument → test funnel vs playbook targets → iterate.

---

## 10. Repo layout

```
platform/
  products/            # per-product Configuration Blocks (JSON) — the source of truth
  packages/plg_core/   # the shared control-plane engine (pql, roi, lifecycle, …)
  services/gazal/      # the inference engine / API gateway
  apps/                # thin product apps (one per product)
  demo/                # static clickable journey demo (no build step)
  scripts/verify.py    # runs the engine across all products
  tests/               # engine tests (reproduce the spec numbers)
  docs/                # deeper design notes
```

---

## 11. What's real today vs next

- **Real & tested now:** the config system + `pql` + `roi` + `lifecycle`, verified to
  reproduce every spec number; the demo; this architecture.
- **Next:** flesh out `events`/`billing`/`compliance`, the Gazal gateway, and the first
  product app (Wave 1), then wire a hosted environment.
