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
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.
Deployment topology
See operations. 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.