# Architecture

ADapptive is a monorepo (pnpm workspaces + Turbo, Node 20) that ships one API,
one dashboard, two client channels (SDK and browser extension), and one MCP
server. Customer source code never enters the platform: the implementation
loop runs on the developer's machine.

## Packages

| Path | Package | Role |
|---|---|---|
| `platform/backend/api` | `@adapptive/api` | Fastify 4 REST API + Socket.IO. Tenant-scoped; all authorization decisions live here. |
| `platform/database/database` | `@adapptive/database` | Prisma schema, committed migrations, non-destructive seed, key helpers. |
| `platform/frontend/dashboard` | `@adapptive/dashboard` | Next.js 14. Public site (`/`, `/features`, `/pricing`, `/download`, `/docs`), developer workspace, tester hub, operator summary. Talks to the API server-side through `/api/proxy/*` with the user's OIDC token. |
| `platform/frontend/studio` | `@adapptive/studio` | Local zone configurator. Holds the secret key; never deployed. |
| `sdk/packages/core` | `@adapptive/sdk` | Embeddable widget: zone rendering, Shadow-DOM feedback modal, offline queue, Socket.IO live updates, tester token header. |
| `sdk/packages/react` | `@adapptive/react` | Provider, `FeedbackZone`, hooks. |
| `tools/browser-extension` | `@adapptive/extension` | MV3 extension bundling the SDK. Tester mode (sign in with OIDC PKCE, submit, vote) and developer mode (place zones with a studio token). Live-site access is a per-origin runtime grant. |
| `tools/mcp-server` | `@adapptive/mcp` | MCP server exposing the implementation loop. Runs locally over stdio or hosted over Streamable HTTP at `mcp.adapptive.space`. |
| `deploy/` | — | Coolify compose stacks (API, dashboard, MCP, Postgres, MinIO; Authentik separately). |

## Request flows

```mermaid
sequenceDiagram
  participant T as Tester (extension or SDK)
  participant API as API
  participant DB as Postgres
  participant D as Developer dashboard
  participant M as MCP server
  participant A as Developer's agent
  T->>API: POST /api/feedback (adp_pk + optional tester JWT)
  API->>API: safety pipeline: redact, screen, classify
  API->>DB: Feedback(safetyStatus)
  T->>API: POST /api/votes (weight resolved server-side)
  API->>DB: transactional vote + counters + quorum check
  API-->>D: Socket.IO feedback:updated
  A->>M: get_ready_feedback
  M->>API: GET /api/feedback?status=THRESHOLD_MET (CLEARED only)
  M-->>A: enveloped, redacted items
  A->>M: start_implementation / report_deployment_progress
  M->>API: POST /api/deployments, PATCH status
  API->>DB: Deployment, RewardLedger(DEPLOYED)
  API-->>T: notification: your feedback shipped, please re-verify
```

## Data model

Tenant root is `Customer` (the developer's workspace). Everything below hangs
off it with `customerId` and cascades.

| Area | Models |
|---|---|
| Identity and access | `Customer` (keys, OIDC subject, plan, `isPlatformPool`), `WorkspaceMember` (OWNER/ADMIN/EDITOR/VIEWER), `CampaignCollaborator`, `AuditEvent` |
| Product surface | `Campaign` (slug, goal, URL patterns, schedule, template, visibility, pipeline config), `FeedbackZone` (selector, type, threshold, quorum, audience, window) |
| Contributions | `Feedback` (type, status, safety status and report, redacted copies, screenshot, tester), `Vote` (weight, dedupe per session and tester), `FeedbackAnalysis` (agent-written summary/task plan), `FeedbackVerification` (post-deploy confirmations) |
| Implementation | `Deployment` (branch, PR, URL, status), `DeploymentStage`, `DeploymentLog` |
| Community | `Tester`, `TesterTier`, `TesterPoolMembership`, `TesterInvite` (usage-capped, revocable, optional referrer), `TesterApplication`, `RewardLedger` |
| Economy | `RewardBudget`, `PayoutPolicy`, `TesterWallet`, `Payout` |
| Notifications | `Notification`, `NotificationPreference` (workspace); `TesterNotification` (tester-private inbox: ship-and-verify, reopen, rewards, referrals, applications, digests, payouts) |
| Safety and access | `StudioPairingCode` (extension developer-mode pairing), `McpKey` (least-privilege agent credentials), `AuditEvent` |

Schema: `platform/database/database/prisma/schema.prisma`. Every change is an
additive migration under `prisma/migrations/`; production applies them with a
run-to-completion `migrations` service before the API starts.

## Feedback lifecycle

```
COLLECTING_VOTES ──(threshold + quorum, safety CLEARED)──► THRESHOLD_MET
   ▲                                                          │ start_implementation
   │ re-verify: 3 × STILL_BROKEN                              ▼
   └───────────────────── DEPLOYED ◄── DEPLOYING ◄── AWAITING_APPROVAL ◄── TESTING ◄── GENERATING_CODE
                                                                         (TEST_FAILED, FAILED, REJECTED are terminal-ish side states)
```

`safetyStatus` is orthogonal: `PENDING → CLEARED | FLAGGED → (moderation) →
CLEARED | BLOCKED`. Only `CLEARED` items are ever visible to agents.

## Authentication kinds

| Kind | Credential | Grants |
|---|---|---|
| publishable | `Authorization: Bearer adp_pk_*` | submit feedback, vote, read zones |
| tester | `x-adapptive-tester-token: <OIDC JWT>` alongside the publishable key | identity for weight, dedupe, rewards |
| secret | `Bearer adp_sk_*` | full workspace admin (hash stored) |
| mcp | `Bearer adp_mk_*` | implementation loop only: read feedback/zones/campaigns, write feedback status, deployments, analysis |
| studio token | `x-adapptive-studio-token` | zone CRUD from a browser (short-lived HMAC) |
| oidc (workspace) | `Bearer <Authentik JWT>` | dashboard account and workspace routes by role |
| platform admin | OIDC email in `PLATFORM_ADMIN_EMAILS` | operator aggregate view, applications, moderation across tenants |

Implementation: `platform/backend/api/src/lib/auth.ts`.

## Real-time

Socket.IO rooms are namespaced `zone:<customerId>:<zoneId>`; events
`feedback:new|updated|vote`, `zone:created|updated`,
`deployment:started|progress|completed|failed`.

## Machine-readable surface

`/robots.txt`, `/sitemap.xml`, `/llms.txt`, `/llms-full.txt`,
`/.well-known/security.txt`, `/.well-known/agent-card.json`, `/docs/*.md` on
the dashboard; `/openapi.json` and `/docs` on the API;
`/.well-known/oauth-protected-resource` and `/mcp` on the MCP host. See the
[agent guide](./agent-guide.md).

## Deployment topology

See [operations](./operations.md). Summary: Coolify on the `hs2` VPS, Traefik
as the only public listener, one compose project with `api`, `dashboard`,
`mcp`, `postgres`, `minio`, and `migrations`; Authentik in a second compose
resource; Umami shared.
