Deployment topologyNginx edge · Docker · Dokploy
- /→ FrontendTanStack Start SSR · React 19 · tRPC
- /landing→ LandingVite static · waitlist + onboarding
- /api/backend/*→ Go APIGin · CGO + 2GB SQLite · MinIO · Remotion
- /_agent→ Agent proxyBun → OpenClaw runtime + plugins
Supabase Postgres underneath everything: RLS, pgvector, Realtime, Vault, Edge Functions. GitHub Actions deploys only the services whose paths changed.
01 /Retrieval that makes decisions
The RAG layer ranks every car on an auction runlist against what a dealer's lot actually needs, and buyers use that ranking on the auction floor. The score is IMX, the Inventory Match Index.
- Semantic and keyword search work together, so conceptual queries ("work truck") and exact ones ("F-150") both land.
- Embeddings come from a chain of providers with a local fallback, so ranking degrades instead of failing.
- Retrieval supplies relevance. Deterministic business rules align it with how a dealership actually operates.
02 /An assistant that cannot leave its tenant
Operators ask questions in plain English and get answers from their own data. Letting a model write SQL against a multi-tenant database only works if the model physically cannot see anyone else's rows.
- Prompts become a tenant-scoped, SELECT-only query DSL executed through ai_execute_query, a hardened security-definer Postgres function tightened over several migrations.
- Writes are risk-classified. Destructive operations require an approval token from a human before they run.
- Every query and write lands in telemetry tables, so any agent action can be audited after the fact.
- Context documents for the user, dealership, and team go through a draft and publish step before they can change agent behavior.
03 /VIN decoding without the network
A paid third-party API became a self-contained Go service over a ~2GB NHTSA database. It decodes make, model, trim, and specs, and corrects mistyped VINs, with zero external calls per decode.
04 /Python to Go, with nothing broken
A core import that populated thousands of rows took up to two minutes. Fixing the FastAPI path got it to 5–25 seconds. Rewriting the services in Go with Gin, plus caching and data-model changes, cut database load by more than 80% and brought responses under a second, with zero breaking changes for the clients.
05 /Other calls worth explaining
Streaming ETL that cleans up after itself
Auction runlists stream row by row through csv.Reader at constant memory. Column mappings are per-auction configs in Supabase, so dealers add a new auction house without a code change. Inserts go in 500-row batches with client-side UUIDs; if linking cars to the runlist fails, the just-inserted cars are deleted so nothing is orphaned.
One API, two transports
tRPC procedures are split into a shared router, safe over both HTTP and Electron IPC, and a cloud-only router for embeddings and heavy IMX compute. The desktop app runs the full shared API in-process with zero duplicated business logic.
A desktop app that supervises its own runtime
The Electron main process spawns the bundled Go binary, launches the OpenClaw agent with loopback-only trusted-proxy auth, relays OpenRouter credentials locally, and manages Chrome for Testing for browser automation.
Collaboration without a collaboration server
The document vault uses TipTap with Yjs CRDTs, relayed over Supabase Realtime channels. Concurrent edits merge conflict-free, with debounced autosave, version history, and point-in-time restore.
Secrets outside application tables
Each user's OpenRouter key is encrypted in Supabase Vault. The Go backend mints and revokes keys through Vault RPCs, so keys never appear in an application query.
Isolation enforced by the database
Every core table carries tenant_id, and RLS binds auth.uid() to the user's tenant inside Postgres. The mobile app talks to Supabase directly with RLS as its only boundary, which only works because the policies are the real security layer.