Focal
A Nigeria-first operating system for creative businesses — booking, proposals, payments and delivery, in one place.
Solo founder & full-stack engineer
Live at runonfocal.com and in active development. Formerly CreativeOS — renamed in September 2026 because the old name clashed with existing products.
Stack
- Next.js 16
- React 19
- TypeScript
- Drizzle ORM
- Neon Postgres
- Better Auth
- Paystack
- Cloudflare R2 · Stream · Workers
- Vercel AI SDK · AI Gateway
- Upstash Redis · QStash
- Google Calendar API
- Resend
- PostHog
- PWA

The problem
Freelancers and small creative studios in Nigeria run their businesses across WhatsApp, Instagram DMs, Google Drive and spreadsheets. Proposals get lost in chat, approvals are verbal (and unenforceable), invoicing is manual, and finished work goes out as a Drive link with nothing tying it to payment.
The tools that solve this abroad (HoneyBook, Bonsai, Dubsado) assume US/EU payment rails, tax rules, and a client who will happily create an account. None of that fits the Nigerian market.
Constraints that shaped it
Clients won't sign up. Any flow that requires the client to create an account dies on arrival — approving, paying and downloading all had to work with zero client login while still producing a legally meaningful record.
Clients live on WhatsApp, on budget Android phones over patchy 4G. Every client-facing page is server-rendered so links preview properly in WhatsApp, and the approval page has to stay under 1 MB.
Money is local. Invoicing had to speak naira, VAT and TIN, and settle through Paystack — not Stripe.
Multi-tenant from day one. Every studio's data must be strictly isolated, enforced at the database layer, not just in application code.
Approach & architecture
The spine is one client workflow — Lead → Quoted → Approved → In Progress → Delivered → Paid — modelled as explicit stages backed by a stage-event log, so the whole business is queryable and auditable. Studios work it as a list or a drag-and-drop board.
Client approval happens on a no-login page opened from WhatsApp. Each approval writes a record — timestamp, IP, user agent, a hash of the exact document and an email echo — inside a single database transaction, giving the studio a defensible record without ever asking the client to register.
Tenant isolation is enforced twice: every query goes through a tenant-scoped repository layer, and Postgres row-level security sits behind it as a backstop. CI runs "forgotten filter" tests as the restricted database role, so a query that skips the tenant scope fails the build instead of leaking data.

Money on local rails
Clients pay deposits and invoices online through Paystack split payments: the money settles straight into the studio's own subaccount, so the platform never holds funds. On the free plan a 1% fee comes out of the split — never added on top of what the client was quoted — and paid plans waive it. Money is integer kobo end to end.
Retainers bill themselves: a studio marks an invoice as repeating, the client consents once, and a scheduled job charges the saved card each cycle — with retries, notifications, and pause, skip and cancel controls. Studio subscriptions (Free, Pro, Agency) run on the same rails.

From booking to delivery
A public booking page takes deposits and checks the studio's Google Calendar for clashes; calendar sync runs both ways over Google's push webhooks.
Every project gets a no-login client portal: a timeline of where things stand, the one thing the client needs to do next, and inline payment. Finished work is delivered there too — uploaded in resumable chunks to private Cloudflare R2 storage, previewed with watermarks burned in on the server (Cloudflare Stream for video, low-bitrate tagged previews for audio), and unlocked only once the client has approved and paid. Downloads use short-lived signed URLs, and a Cloudflare Worker streams "Download all" as a zip.
Paid studios can white-label all of it on their own domain. Domains are provisioned through Vercel's API, and an incoming host only resolves to a studio through a verified domain record — never on the Host header alone.


An assistant that asks first
Studio Copilot answers questions about the business — revenue trends, collection rate, overdue invoices, what's coming up — and drafts proposals, invoices and client messages. It has ten read tools and ten write tools, and every write comes back as a proposed action the studio confirms before anything changes.
The workspace ID is fixed on the server before the model runs, never a tool input, so no prompt can point Copilot at another studio's data. It runs through the Vercel AI SDK and AI Gateway: a small model handles routing and reads, and a stronger one is reserved for writing.

Trade-offs
No-login access means I traded classic account-based identity for a link-plus-audit-trail model: unguessable 128-bit links with expiry and revocation, an optional PIN on the portal, and a record of every approval. That took careful thought about link security and non-repudiation, but it was the only design the market would actually adopt.
Row-level security adds complexity to every migration and query path, and makes some queries harder to write — accepted deliberately, because a single cross-tenant data leak would be fatal for a multi-studio product.
The pipeline is fixed: six stages, no custom columns, even on the board view. Configurable boards are where tools like Dubsado lose people, and Focal's users want an opinionated flow, not a project-management tool.
Building on Paystack (not Stripe) narrows the platform to Nigeria for now, but that focus is the product's entire reason to exist.
Where it stands
Focal is live and is my most active project: 2,100+ commits, 166 merged pull requests, 55 database tables across 50+ hand-reviewed migrations, and around 2,000 automated tests.
It's production-hardened the unglamorous way: a per-request nonce CSP, passkeys and authenticator-app 2FA, bot protection on sign-up and the AI route, PostHog analytics and error tracking with source maps, and nightly encrypted database backups with a monthly automated restore test. It installs as a PWA, so studios can run it like a native app on cheap Android hardware.
Right now I'm rebuilding the proposal builder into a themed, block-based document editor that works as well on a phone as on a desktop, with on-device face detection so a cropped photo never cuts off a face. It's the piece I'm proudest of — not a clone of an existing app, but a product designed around a market the existing tools ignore.
Next
SEO Content AI