Angel Campa
Colour theme

WorkThe April wave

Gavelhouse

Kept an HOA's legally separate reserve and operating funds from ever mixing in the ledger, and ran accounting, dues, and governance workflows for volunteer treasurers around that rule.

Ran on
Cloudflare Workers
Ran
April 2026 to June 2026
Domain
HOA compliance
Source
hoa-compliance-saas-gavelhouse-snapshot

Built with

  • Cloudflare Workers
  • Hono
  • React 19
  • Astro 5
  • PostgreSQL
  • Drizzle
  • Better Auth

Hosted services

  • Neon (Postgres via Hyperdrive)
  • D1
  • KV
  • R2
  • Stripe
  • Resend
  • Sentry
  • PostHog
Reserve Fund page showing a $166,000 reserve balance at 44.3% funded, with a Fannie Mae LL-2026-03 badge confirming the 18% budget allocation clears the 15% threshold
The reserve-fund compliance page the product was built around: the balance a board is tracking, and the Fannie Mae allocation test run against it. Captured from the local stack against seeded data.

Gavelhouse shipped to production on Cloudflare Workers, built around a 51-entry HOA reserve-fund rule table covering all 50 states and DC, each row carrying its own statute citation.

The decision

Gavelhouse’s deploy pipeline refused to start unless the branch was master, the working tree was clean, and local HEAD matched origin. It existed because one person shipped to production with no reviewer and no separate staging environment. The same preflight check injected the verified commit SHA into the build as BUILD_COMMIT.

After wrangler deploy returned, the pipeline polled the live URL (/api/health for the API, the rendered build-commit meta tag for the two Vite/Astro front ends) until the commit being served matched what had just been pushed, on the reasoning that a zero exit code from wrangler is not evidence the edge is running the new code.

A guard scanned every tracked package.json for a raw wrangler deploy call outside three explicitly sanctioned scripts, and a public-facts guard scanned every tracked text file for retired brand strings, including the product’s former name, so a stale reference could not survive a rebrand into a shipped page. An SEO audit ran inside the same pnpm run verify gate, before the build. Together, the preflight checks and the guards let one person ship to production without a reviewer or a staging environment, with every deploy that ran through a committed script checked before it shipped.

Architecture

Three deployed applications and two shared packages, all on Cloudflare Workers, backed by Postgres through Hyperdrive.

The one rule the product argued for lived in a single function: postEntry.ts summed debits and credits separately for the operating and reserve sides of a journal entry and threw before either side could cross into the other. An audit-trail middleware wrote an auditEvents row for every mutating request across six route groups, derived generically from the request path, body, and response, so no route handler could forget to log itself.

Tenant isolation (a communityId predicate scoping every query to the caller’s HOA) was caught missing six separate times across review phases, and fixed before merge each time.

The KV-backed rate limiter carried a documented, bounded race: Cloudflare KV has no atomic increment, so two concurrent requests could both read the same counter and both pass the limit check. The worst case was quantified in a code comment, and a Durable Object fix was judged not worth the added infrastructure for what the limiter was protecting.

By the numbers

Each figure carries where it came from and when it was measured. Open one to see the command behind it, where the repository recorded a command.

Application source
224,885 lines across 981 tracked files
Provenance

Source portfolio/METRICS.md § Source (includes test files; generated by pnpm run metrics:generate)

Measured

Tests
418 test files, at least 6,580 test cases
Provenance

Source portfolio/METRICS.md § Tests (static count of it( and test( call sites)

Measured

Coverage gate
95% per file (lines, functions, branches, statements) enforced in 5 workspaces
Provenance

Source portfolio/TESTING.md § The automated suite (enforced per file)

Measured

Database
42 Drizzle tables, 27 SQL migrations, plus 2 further Cloudflare D1 migrations for nonce tables
Provenance

Source portfolio/METRICS.md § Database (D1 counted separately: a different database, unrelated lifecycle)

Measured

API surface
107 unique HTTP endpoints across 36 route files
Provenance

Source portfolio/METRICS.md § API (counted from Hono's own route table)

Measured

Repo-tooling tests
268 tests covering scripts/lib at 99.75% statements
Provenance

Source portfolio/TESTING.md § The automated suite

Measured

Reserve-fund rule table
51 entries (50 states plus DC) of HOA reserve-fund requirements, each carrying its statute citation
Provenance

Source README § Notable engineering (packages/shared/src/compliance/states.ts)

Measured

History
680 commits, 2026-04-14 to 2026-08-12
Provenance

Source portfolio/METRICS.md § History (private source repository; 131 of 680 commits under an automation account)

Measured

Screens

Trial balance listing nine accounts with a Fund column marking each one operating or reserve; total debits and credits both read $43,337.00 and the balance check reads Balanced
Trial balance.
Bank reconciliation with four of six statement lines matched, $16.50 unmatched, and two remaining lines awaiting a transaction ID before the ledger can be finalized
Bank reconciliation.
Month-end close for period 2026-08, two of five checklist steps complete, next action Post Adjustments, with the locked 2026-07 period offering an audit pack download
Month-end close.
Violation log with eight violations, four needing attention, each row carrying a dated history of open, notified, cured, and closed events
Violation log.
Read the repositoryhoa-compliance-saas-gavelhouse-snapshot

Its portfolio/ directory holds the architecture, metrics and testing documents these figures were taken from.