← Back to work
🔒 Private · NDAFull-Stack Engineer (sole developer) · Nextbit · 2025

Agency Portal

All-in-one operations SaaS that runs a digital agency end-to-end — CRM, task management with time tracking, invoicing, a magic-link client portal, and pay-to-onboard billing in one role-aware app.

The problem

A digital agency's operations are usually scattered across five or six disconnected tools — a CRM, a task tracker, spreadsheets for time and invoicing, a client-update thread, and a billing tool. The goal was to collapse all of it into one role-aware app: bring in a client, spin up projects, assign and track work, invoice it, let the client watch progress in their own portal, and let a prospect sign up and pay without a human — while strictly guaranteeing each of four user types only sees what they're allowed to.

What I built

A single codebase serving three surfaces on one backend: an internal cockpit for staff (dashboard, CRM, task boards, time tracking, invoicing, reports, encrypted credentials vault), a magic-link client portal, and a public pay-to-onboard page. Four roles — owner, manager, member, client — each resolve to a different scope, and every API route filters data through it.

Engineering highlights

1

A real authorization / scope model — proven, not assumed

Access control is centralized in a can()/scope layer; every route filters data by the actor's scope. Each boundary ships an executable proof suite that drives the live server over HTTP and asserts against the database — authorization is demonstrable.

2

Pay-to-onboard: Stripe Checkout → auto-provisioning

Webhooks (checkout.session.completed, invoice.paid, subscription.updated/deleted) drive the subscription lifecycle and provision the client account idempotently, so a replayed webhook never double-creates. Active subscriptions roll up into real MRR.

3

Task time tracking with real-time notifications

Members work a queue grouped/sorted by project, date, or priority. Starting a task timer fires a real-time WebSocket notification to owner and manager; end-of-day worksheets render an Excel-look PDF emailed to the owner.

4

Passwordless client portal with redaction

Clients sign in with a magic link (Better Auth) and receive a redacted projection — the same underlying entities serve staff and clients through different scoped views.

5

Pluggable delivery + encrypted vault

All outbound messaging goes through one send() seam with swappable email/WhatsApp adapters. Per-project credentials are stored with AES-256-GCM encryption.

Results

  • One app that replaces a stack of separate tools — CRM, tasks, time tracking, invoicing, client portal, and self-serve billing.
  • Ten executable proof suites covering scope, portal isolation, onboarding, and billing — authorization and billing are demonstrable, not just claimed.
  • End-to-end type safety with typecheck + build in CI; ships as a single self-migrating Docker image.

Full tech stack

TypeScript (strict, ESM)Hono (Node)PostgreSQLDrizzle ORMBetter Auth (password + magic-link)Stripe (Checkout + webhooks)WebSocketsReact 19ViteTanStack QueryReact RouterTailwind v4cmdkAES-256-GCMDocker

Built at Nextbit — the source lives in a private repository, so it isn't publicly available. A live screen-share demo and code walkthrough are available on request for hiring managers.