Where we are today
Foundation finished — ready to build the real PerFit on top
✅ DONE — FOUNDATION
🌐 todo-web (demo frontend)
🚪 federation-gateway
📋 todo-service
👤 user-service
NEXT
🚀 NEXT — REAL PRODUCT
🌐 web (PerFit frontend)
📷 perfit-service · 👗 garment-service
🎨 body-scan · fitting · auth (Clerk)
todo-web is a demo. The real PerFit apps come next, reusing the same plumbing.
The big picture
One frontend · one gateway · many small services
👤
User
🌐
todo-web
Next.js frontend
🚪
federation-
gateway
Hive Gateway
📋
todo-service
GraphQL subgraph
👤
user-service
GraphQL subgraph
👗
…future subgraphs
Federation in action
The gateway splits queries, calls each subgraph, then stitches the response
1
todo-web sends a query: { todos { title user { name } } }
2
Gateway plans across subgraphs
3
todo-service answers todos · user-service resolves User via __resolveReference
4
Gateway returns one merged response
🌐 todo-web
🚪 federation-gateway
📋 todo-service
👤 user-service
📦 merged response
Federation — concrete use case
"Show me my todos with each owner's name and email"
📋 todo-service knows
type Todo @key(fields: "id") {
id: ID!
title: String!
completed: Boolean!
user: User ← stub only
}
extend type User @key(fields: "id") {
id: ID! @external
}
owns todos · references User by id
👤 user-service knows
type User @key(fields: "id") {
id: ID!
name: String!
email: String!
}
__resolveReference({ id })
→ db.users.findById(id)
owns users · resolves entity references
CLIENT QUERY
query {
todos {
title
user { name email }
} }
🚪 federation-gateway
plans & merges across subgraphs
STEP 1 — todo-service answers
todos: [
{ title:"Buy milk", user:{id:"u1"} },
{ title:"Ship code", user:{id:"u2"} }
]
STEP 2 — user-service resolves refs
_entities([{__typename:"User",id:"u1"},…])
→ [{name:"Ana",email:"a@x"},
{name:"Ben",email:"b@x"}]
STEP 3 — gateway returns merged JSON
[{title:"Buy milk", user:{name:"Ana",email:"a@x"{'}}'},
{title:"Ship code",user:{name:"Ben",email:"b@x"{'}}'}]
Neither service knows the full picture. todo-service only stores userId. user-service only stores users. The gateway uses @key + __resolveReference to join them on the fly — no shared database, no cross-service SQL, no manual REST stitching in the frontend.
Testing vs Production
Two fully isolated environments — same shape, separate data
👤
🧪 TESTING
🌐 todo-web-testing
🚪 federation-gateway-testing
Hive target: testing
📋 todo-service
testing worker
👤 user-service
testing worker
D1 todo-db-testing
D1 user-db-testing
🚀 PRODUCTION
🌐 todo-web-production
🚪 federation-gateway-production
Hive target: production
📋 todo-service
production worker
👤 user-service
production worker
D1 todo-db-prod
D1 user-db-prod
Monorepo layout
One Nx workspace · apps + shared libs
📦 PerFit-Monorepo (Nx)
apps/
🌐
todo-web
🚪
federation-gateway
📋
todo-service
👤
user-service
libs/
🎨
shadcn (UI)
🔧
wrangler-env-patcher
shared by all apps
Where it runs
Cloudflare Workers · D1 · R2 · Queues · Hive registry
☁️ CLOUDFLARE
⚡ Workers
🌐
todo-web
🚪
gateway
📋
todo-svc
👤
user-svc
🗄️
D1
SQLite (Drizzle)
📦
R2
file storage
📬
Queues
async jobs
edge network · runs worldwide · auto-scaling
🐝 HIVE
schema registry
📜 supergraph
testing + production targets
🛡️ schema checks
block breaking changes
📥 CDN delivery
gateway pulls supergraph at build
Why this shape
📦
MONOREPO
Single source of truth.
Shared libs update everywhere at once.
🧩
MICROSERVICES
Each service owns one domain.
Independent deploys, isolated failures.
🚪
FEDERATION
One graph, many subgraphs.
Frontend never knows the topology.
🧪
ENV SPLIT
Testing mirrors production.
Catch regressions before users do.
☁️
CLOUDFLARE
Edge runtime, free tier, no ops.
Workers + D1 + R2 + Queues.
🐝
HIVE REGISTRY
Schema as single source of truth.
Breaking-change checks in CI.
🎯
Foundation done — ready to scale to the real PerFit features.
Unit testing
Jest · 100% coverage threshold · every service & app
✅ jest --coverage
branches · functions · lines · statements
100%
🌐
todo-web
• component tests
• @testing-library/react
• Apollo mocks
• form & hook tests
11 tests ✓
📋
todo-service
• resolver tests
• mocked Drizzle chains
• __resolveReference
• GraphQLError paths
16 tests ✓
👤
user-service
• resolver tests
• mockContext helpers
• entity references
• mutation/query split
passing ✓
🔧
wrangler-env-patcher
• pure unit tests
• tmpdir integration
• TOML parse + patch
• CLI tests
10 tests ✓
Every PR runs the full Jest suite. Resolvers are tested with mocked Drizzle chains so we don't need a real DB. Coverage threshold blocks any merge under 100%.
What's next
🏗️ Foundation ✅ · 🚀 PerFit features starting now
web frontend · perfit-service · garment-service · body-scan · fitting · Clerk auth