ATS
All work · 04

Past the no-code ceiling: a validated AppSheet app rebuilt as a real platform

Client:
A cooperative fundraising organization
Industry:
Nonprofit operations
Status:
In development
Stack:
NestJS · PostgreSQL · Drizzle · Next.js · TypeScript

Years of validated fundraising logic lived inside a production AppSheet app: caller and closer workflows, pledge management, campaign rules that the organization had refined through real use. The app had hit the ceiling that all no-code systems eventually hit: multi-tenancy, permissions, and workflow guarantees it was never built to provide.

The rebuild started with documentation, not code. We extracted the business rules into specifications: architecture decision records, per-module specs, and a gap analysis produced by auditing the original app against its own user manuals with a fleet of parallel review agents. Only then did the platform get built, layer by layer, from those specs.

The system

SPECS + ADRS19 adrs · 28 specsUSER MANUALSvalidated rulesPOSTGRES27 tablesNEXT.JS WEB38 routes
Hover or focus a node for the engineering note.
fig. 04 · coapp, spec-driven system architecture

Three decisions that mattered

01

Documentation is the source of truth

Nineteen architecture decision records and per-module specs were written and reviewed before implementation, and the codebase carries a prompt library that can regenerate each layer from them. The trade-off is real up-front cost. The return is that the platform can be audited, extended, and even rebuilt against a specification instead of against tribal memory, which is precisely what the original no-code app could not offer.

02

Tenancy is enforced in the backend, always

Every request passes a guard chain that derives tenant access from membership, never from the URL. Permissions live in one thirty-key matrix consulted by one authorization service. There is no code path where a client-side mistake can read another tenant's data.

03

Fundraising workflow runs in real transactions

The caller and closer rules that the organization validated over years now execute inside database transactions with row locks and idempotent task creation. The same rules, but with guarantees: no double-assignments, no lost pledges, no race conditions between volunteers.

The AI layer, honestly

There is no AI in the product at runtime, and we say so. The AI story here is the methodology: specifications feeding AI-assisted generation, a twelve-agent audit comparing the old app, its manuals, and the new code, and human architectural review at every layer. We use this project to show how a small studio ships platform-grade software, not to decorate a CRM with a chatbot.

What we would do differently

The generation-first approach meant code arrived faster than tests at the start, and this section said so while it was true. The correction has landed: the platform now runs 52 integration suites, 328 tests against a real Postgres in CI, on every push. What is still honest to say: the unit and browser layers of the testing strategy are not built yet, and the platform is in client QA rounds while the original AppSheet app remains the production bridge. Next time we would land the test harness with the first module rather than after the schema settles.

Results, and how they were measured

27

tables in the multi-tenant schema

Tenant-owned rows carry tenant identity; the backend enforces it everywhere.

19

architecture decision records before build

Plus 28 module and system specs and a documented gap analysis; 23 ADRs and counting today.

155

API endpoints across 26 modules

Generated from specs, guarded by one authorization service.