Hard-won knowledge from building the platform — each one cost real time and debugging sessions

Lessons Learned

Hard-won knowledge from building this system. Each one cost real time and debugging sessions.

1

Build-Time vs Runtime Are Different Worlds

Next.js prerenders pages at build time where env vars may not exist. Runtime handles real requests where they MUST exist. We learned this the hard way when a "helpful" placeholder URL masked a broken Supabase connection in production. Rule: runtime code must throw on missing config. Build-time code can use placeholders.

2

Return-Based Auth Beats Throw-Based

requireSession() returns SessionContext | Response instead of throwing. This eliminated try/catch boilerplate in every API route, made auth errors explicit in the type system, and prevented stack traces from leaking to users.

3

Reviewer Parse Failures Must Never Block Delivery

The Reviewer agent validates proposals with Claude Haiku. If Haiku returns malformed JSON (it happens), the proposal should still be delivered. We implemented a soft pass pattern — parse failure = pass with needs_human_review flag set.

4

Memory Writes Must Be Non-Fatal

The Memory Node (step 7 in the brain pipeline) runs AFTER the proposal is committed. If the OpenAI embedding API is down, the user still gets their proposal. Intelligence accumulation is valuable but never worth blocking delivery.

5

Promise.allSettled Over Promise.all

When fetching usage counts across 6 tables, one failed query shouldn't crash the entire response. Promise.allSettled() gives you partial results. We only use Promise.all() when ALL results are truly required to proceed.

6

One Change Per Branch, Always

Batching unrelated changes makes root cause analysis impossible when something breaks. We enforce: one logical change per branch, one branch per PR. It feels slower but catches issues faster.

7

Vercel and Fly.io Are Separate Worlds

Secrets set in Vercel don't propagate to Fly.io. The worker and brain have their own env vars managed via fly secrets set. We've been burned by updating one and forgetting the other. Now it's in the deployment checklist.

8

Solo Founder Architecture: Optimize for Debuggability

As a solo builder, the ability to debug at 2 AM matters more than theoretical scalability. PostgreSQL polling is debuggable with a SQL query. Message brokers add infrastructure I'd have to monitor alone. Every architectural choice was filtered through: "Can I debug this by myself?"

Ready to create AI-powered proposals?

Start Free