Most agency founders I know run their business out of a mess of Google Sheets, Notion pages, and WhatsApp threads. They lose leads because nothing is tracked. They miss invoices because payments live in a spreadsheet nobody updates. They waste 30 minutes every Monday just figuring out where things stand.
That's the problem I set out to fix for the Replit Buildathon. The result is RevOs — a full-stack agency operating system that puts everything in one dark, fast, premium dashboard.
Here's exactly what I built and how.
What RevOs Does-
Ten fully functional CRUD modules, all connected to a real database:
- Clients — full contact management with status tracking
- Leads — pipeline from cold to closed
- Projects — track deliverables and status per client
- Payments — log invoices, amounts, and payment status
- Analytics — revenue charts and pipeline overview
- Cold Calls — outreach log with outcomes
- Sales — deal tracking and close rates
- Events — calendar-style scheduling
- SOPs — internal process documentation
- Content — content pipeline management
- Not mocked. Not hardcoded. Every module reads and writes to a real PostgreSQL database.
The Stack-
Frontend
- 1. React + TypeScript + Vite
- 2. Tailwind CSS with a custom dark/gold design system
- 3. TanStack Query for server state management
- 4. Clerk for authentication (sign-in, sign-up, session management)
- 5. Deployed on Cloudflare Pages — global edge, instant loads
Backend
- Node.js + Express + TypeScript
- Drizzle ORM with Zod validation on every route
- OpenAPI contract-first approach — schema defined once, types generated everywhere
- Deployed on Render
Database
- PostgreSQL on Neon — serverless, scales to zero, free tier
- Drizzle Kit for schema push
Auth
- Clerk development instance
- Custom dark/gold themed sign-in and sign-up pages
- Deep appearance overrides to match the RevOs brand
The Architecture
The project is a pnpm monorepo with three workspace packages:
artifacts/cashup/ → React frontend
artifacts/api-server/ → Express backend
lib/db/ → Drizzle schema + database client (shared)
The frontend never imports from the backend directly. All communication goes through a typed API layer — fetch calls using a base URL helper, validated on the server with Zod schemas generated from an OpenAPI spec.
The backend uses Drizzle ORM with drizzle-kit push to sync the schema to Neon — no migration files to manage, just push the schema and it figures out the diff.
The Design
The UI is intentionally premium. Agencies aren't going to use an ugly tool every day — it has to feel good to open.
The design system uses:
- Deep near-black backgrounds (#0A0A0B)
- Gold primary (#C9A84C) for accents, buttons, and active states
- Subtle gold/dark gradients on auth pages
- Animated orbs behind the sign-in card
- A custom gold "R" favicon
- The Clerk sign-in and sign-up pages are fully custom-themed to match — no default Clerk UI leaking through.
Deployment Reality
This wasn't a "works on localhost" project. I went end-to-end with real deployment:
- Cloudflare Pages for the frontend — connected to GitHub, auto-deploys on push, _redirects file for SPA routing
- Render for the API — free tier, with UptimeRobot pinging /api/health every 5 minutes to prevent cold starts
- Neon for the database — connection string set as an env var on Render, schema pushed remotely
- CORS is locked to the Cloudflare Pages origin. The API is rate-limited. Helmet is set up for security headers. It's not a toy deployment.
The Hardest Parts
Clerk on a .pages.dev domain. Clerk's production instance requires DNS control to verify your domain — which you can't do on a *.pages.dev subdomain. The workaround: stay on a Clerk development instance, which works on any domain without DNS setup.
CORS across services. The frontend on Cloudflare, API on Render, and database on Neon are three separate services. Getting CORS right — especially for credentialed requests — took careful ordering of middleware (CORS before everything, correct origin matching, credentials flag on both sides).
Render cold starts. Free tier Render spins down after inactivity. UptimeRobot on a 5-minute ping interval keeps it warm.
Try It
Built solo, shipped in one buildathon sprint. RevOs isn't a demo — it's a working product you can sign up for and use to run your agency right now.
Built for the Replit Buildathon.
(lots of love+vibecoding)
Top comments (1)
revos-3b2.pages.dev/