Key point
app/admin-v2, its APIs are app/api, and its logic is app/lib, all inside the thybrid Next.js app. That one app is built with OpenNext and deployed as one Cloudflare Worker, which serves thybrid.com, the apply form and admin.thybrid.com. Nine small satellite Workers handle crons, jobs and read paths.Composition of Desktop/thybrid
About 29 GB in total. Most of it is worktrees, exports and archive, not product code.
| Folder | Size | What it is |
|---|---|---|
worktrees/ | 12G | Old git worktrees. Only dev-v3 is still needed. |
exports/ | 8.8G | Reports, wipe backups and release logs, by date. |
archive/ | 4.7G | Old material. |
website/ | 3.6G | The main repo (thybrid-landing, branch main). Real product code is about 1.4 GB of this. |
thybrid-leadgen/ | 1.2G | Lead-gen tooling. |
fran_voice/ | 847M | Voice samples. |
research/, assets/, tools/, data/ | about 450M | Research, brand assets, scripts, data. |
.env | 12K | Single env file with secrets. Never copy it. |
Inside website/
| Item | Size | Regenerable |
|---|---|---|
node_modules | 813M | Yes (npm install) |
infra | 711M | No, Terraform (large provider caches inside) |
.open-next | 506M | Yes, build output |
public | 435M | No, site media and funnel kit |
.next | 179M | Yes, build output |
exports | 45M | No |
docs, app, tests, services | 14M, 14M, 11M, 11M | No, source |
Repo map: website/
website/
app/ Next.js app router (site + ThybridOS + APIs)
admin-v2/ ThybridOS UI and server actions
api/ HTTP routes (apply, booking, cron, slack, stripe, zoom, meta...)
lib/ business logic (~620 files)
ve/ landing and form (live /apply funnel)
apply, book, rewire, sanctuary, gallery ... public pages
db/migrations/ Neon SQL migrations (35 files)
tests/ ~720 test files
scripts/ tooling (118 files)
docs/ OPS, CRM, BOOKING, DECISIONS, ROLES, SECURITY ...
public/ static assets, shared/funnel form kit
infra/ Terraform: AWS, Cloudflare, Access
services/ ads-sync, alarm-slack, meta-api, meta-browser, llm-modal, stt-modal, notion-cc
cron-worker/ jobs-worker/ leads-worker/ hot-worker/ media-worker/
crm-sync-worker/ adset-analyzer-worker/ reports-worker/ mcp-worker/
*-site/ static report sites (automations, qa, seoaeo, uxopt, adsreport, appflow)
wrangler.jsonc main Worker config (KV, R2, queue, service binding)
wrangler.dev.jsonc dev Worker config
package.json next 16, react 18, @opennextjs/cloudflare, wrangler 4
ThybridOS inside the app
UI: app/admin-v2
Pages: applicant, ask, audit, automations, calendar, calls, campaigns, connections, digest, enroll, exports, inbox, marketing, payments, people, pipeline, reports, reviews, sessions, sign-in, tasks, team. Shared pieces: AdminShell.tsx, HomeClient.tsx, HomeViz.tsx, and server actions such as applicant-actions.ts, book-actions.ts, call-actions.ts, connections-actions.ts.
API: app/api
Logic: app/lib
Domains: admin-v2, ai, ask, automations, booker, booking-native, brand, call-bot, calls, command-centre, connections, conversions, crm-read, email-campaigns, exports, invariants, journey, marketing, personal-notify, privacy, recorder, social, sync, webhooks, weekly-digest, zoom-native. Plus flat files for the apply flow (apply-final*.ts), ads (ads-report.ts, adset-scoreboard.ts), applicant messages and stage moves.
Cloudflare Workers
| Worker | Job | Where in repo |
|---|---|---|
thybrid | thybrid.com, apply form, ThybridOS at admin.thybrid.com, all write APIs | app/ via OpenNext |
thybrid-hot | Fast booking slot reads | hot-worker/ |
thybrid-media | Films under /m/ | media-worker/ |
thybrid-sweep | Every app cron, plus the call-score queue consumer | cron-worker/ |
thybrid-jobs | Morning jobs: Google offline conversions, Clarity digest, marketing collectors | jobs-worker/ |
thybrid-leads | Lead-gen helpers, watchdog on sweep heartbeat, WhatsApp health check | leads-worker/ |
thybrid-adset-analyzer | Daily ad set check against real applications | adset-analyzer-worker/ |
thybrid-crm-sync | Monthly cold backup of Neon to R2 | crm-sync-worker/ |
thybrid-reports | Command Centre at dash.thybrid.com | reports-worker/ |
thybrid-mcp | Read-only data connector for Claude | mcp-worker/ |
thybrid-dev | dev.thybrid.com test copy. Writes to the same prod data. | same code, wrangler.dev.jsonc |
thybrid-old | Old static site | worktree old-site |
| static report Workers | automations, qa, seoaeo, uxopt, adsreport, appflow | *-site/ |
Systems map
flowchart LR
V1["Visitor / applicant"] --> W1
V1 --> W2
V1 --> W3
subgraph CF["Cloudflare"]
W1["thybrid: site + ThybridOS + APIs"]
W2["thybrid-hot"]
W3["thybrid-media"]
W4["thybrid-sweep: crons"]
W5["thybrid-jobs"]
W6["thybrid-leads"]
W7["thybrid-adset-analyzer"]
W8["thybrid-crm-sync"]
W9["thybrid-reports"]
W10["thybrid-mcp"]
KV[("KV")]
R2[("R2")]
D1[("D1 leads")]
Q["Queue call-score"]
ACC["Cloudflare Access"]
end
subgraph AWS["AWS Singapore"]
DDB[("DynamoDB applications")]
ADS[("DynamoDB ads-daily")]
LMB["Lambda ads-sync"]
SM["Secrets Manager"]
end
NEON[("Neon Postgres CRM")]
SL["Slack"]
RS["Resend"]
ZM["Zoom"]
ST["Stripe"]
META["Meta"]
W1 --> DDB
W1 --> NEON
W1 --> KV
W1 --> SL
W1 --> RS
W1 --> ZM
W1 --> ST
W1 --> META
W1 --> Q
W4 -->|"calls app routes"| W1
Q --> W4
W5 --> NEON
W7 --> META
W7 --> DDB
W8 --> NEON
W8 --> R2
LMB --> META
LMB --> ADS
LMB --> SM
ACC --> W1
ACC --> W9
Data stores
| Store | Where | Holds |
|---|---|---|
DynamoDB thybrid-applications | AWS Singapore | Master record of every application. Point-in-time recovery on. |
DynamoDB thybrid-ads-daily | AWS Singapore | Daily Meta spend rows. |
| Neon Postgres | Singapore | CRM: people, pipeline, calendar, calls, tasks, notes, marketing. About 92 tables. Applications are mirrored, not mastered here. |
| KV (one shared namespace) | Cloudflare | Live switches, heartbeats, form drafts, rate limits. |
R2 thybrid-crm-archive | Cloudflare | Monthly Neon snapshots, job output. |
R2 thybrid-site-media | Cloudflare | Site films. |
D1 thybrid-leads | Cloudflare | Lead-gen data. |
Data flow
Lead to payment
flowchart TD A["Meta ad or Instagram"] --> B["Homepage"] B --> C["Apply form, 3 screens"] C --> D["Application saved: DynamoDB"] D --> E["CRM copy: Neon"] D --> F["Review card: Slack"] D --> H["Email 01: Resend"] D --> I["Lead event: Meta CAPI, consent only"] F --> J["Closer reads in Slack or ThybridOS"] J -->|"Not a fit"| K["Email 02 decline"] J -->|"Good fit"| L["Closer messages on WhatsApp by hand"] L --> M["Book call in ThybridOS: Zoom meeting"] M --> N["Emails 03 and 04"] M --> O["Slack card 65 min before"] O --> P["Zoom call, 30 min"] P --> Q["Outcome card in Slack"] Q -->|"No-show"| R["Email 05"] Q -->|"Sold"| S["Stripe invoice drafted in ThybridOS"] S --> T["Payment webhook records it"]
Where an application is written
sequenceDiagram participant P as Applicant participant S as thybrid Worker participant K as KV participant D as DynamoDB participant N as Neon CRM participant SL as Slack participant E as Resend participant M as Meta CAPI P->>S: Screen 1, contact details S->>K: Draft saved S->>D: Draft row P->>S: Submit last screen S->>D: Application row S->>N: CRM contact and pipeline stage S->>M: Lead event (consent only) S->>SL: Review card S->>E: Email 01 received
Scheduled jobs (Bangkok time)
| When | Worker | Job |
|---|---|---|
| Every minute | thybrid-leads | Lead-gen bridge, watchdog on sweep heartbeat |
| Every 5 min | thybrid-sweep | Main sweep: review reminders, host 1-hour card, outcome asks, emails 04 and 05, journeys, broadcasts, social posts, connection warnings |
| Every 5 min | thybrid-sweep | Zoom recordings and transcripts poll |
| :17, :33, :43 hourly | thybrid-sweep | CRM sync, data-truth checks, health check of Resend, Stripe, Meta, Slack |
| 03:00 | Lambda ads-sync | Yesterday's Meta numbers to DynamoDB and Notion |
| 07:41 | thybrid-crm-sync | Heartbeat, full Neon backup on the 1st |
| 09:05 to 09:45 | sweep, jobs, analyzer | Dashboard rebuild, Google offline conversions, ad alerts, Clarity digest, ad set check |
| 14:20 to 14:50 | thybrid-sweep | Funnel digest, Meta card, weekly review (Monday), measurement card |
| 17:00 | thybrid-sweep | Command Centre scoreboard |
| 20:30 | thybrid-leads | Lead-gen digest |
Infrastructure and security
- Terraform in
infra/: DynamoDB, ads Lambda, IAM, Secrets Manager, Cloudflare DNS and Access, call transcripts bucket. - Access: Cloudflare Access email PIN in front of admin, dash and the MCP.
/api/*is never gated so webhooks work. ThybridOS also has its own password and 2-step code. - Binding cap: the main Worker sits at Cloudflare's 128 text-binding limit. New settings go in code constants or KV.
- Release path: work in a dev worktree, run
npm test, deploy dev, then prod only on the owner's word.
External services
Transfer plan to Desktop/thybridos
- Copy
website/withoutnode_modules,.next,.open-nextand.env. About 1.4 GB, git history kept. - Disable or rename the Worker deploy in the copy so it cannot overwrite production.
- Run
npm installandnpm testin the copy to confirm it builds. - Docs already in
thybridos/thybrid-docs: Build Plan and Product Overview.