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
Three decisions that mattered
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.
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.
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.