← Analysis / Análisis
UNCTAD · Easy Accounts · eA+ · what to take from vertical-base

Take vertical-base’s method and its safety rules into Accounting-Next; do not move eA+ onto the template

unctad-ai/vertical-base is the template cut on 16 Sep 2026 from ePhyto, the first service built by AI agents from a written spec. Its stack is the same as Accounting-Next, so its pieces copy in cleanly. But it is shaped for procedures (apply → decide → issue a document), and eA+ is a ledger. So we copy the way of working and two safety rules, not the code base. Those two rules would have caught the two bugs we already found in Accounting-Next.

Same stack, different job

Piecevertical-baseAccounting-NextFit
FrameworkNext.js 16.3 · React 19.2Next.js 16 · React 19same
DatabasePrisma 7 · PostgreSQL 18Prisma 7 · PostgreSQL 18 + pgvectorsame
Sign-inNextAuth 4 · passwords (demo accounts)NextAuth 4 · Keycloakkeep AN’s
Validation · stylesZod 4 · Tailwind 4 · RadixZod 4 · Tailwind 4 · Radix/shadcnsame
TestsVitest + real-database testsJest 30port the tests, not the runner
Domainempty: request, status machine, payment, issued documentledger: operations, journal, charts, reportsdifferent

What to take, in order of value

#TakeWhat it isWhy eA+ needs itSize
1Tenancy rule + its test
scopedDb, M3 §1
Every read and write goes through a client that adds the country (here: the business) filter and stamps it on create. A test fails if a table is left out.AN’s operationBusinessWhere is opt-in and returns “no filter” when no business is active. Questionnaire operations are saved with no businessId, so business reports miss them. A scoped client makes that impossible.small
2One writer per moving figure
M3 §2
A value that changes is written in one function, one transaction, with its history row.The double-count bug is two writers: the monthly questionnaire and daily entries both feed the same totals, and nothing filters by source. One function should own the monthly figure and its “Unsupported amount” gap entry.small
3The build cycle
docs/playbook.md, M1, M8
One prompt per task: read the old service → answer fixed questions → write the spec in order → attack it → build in waves with parallel agents → audit with a session that has no stake → install → measure.This is the analysis → development → rollout cycle the eA+ goal asks for. “Read the old service” is exactly our legacy extraction (data model and rules from KeystoneJS/Mongo and the GDB).medium: adapt
4Decision log + measurement
DECISIONS.md, M9
Every decision the spec did not settle is a numbered row (what, why, cost to reverse, who raised it); a test blocks gaps. Eight numbers per build: human hours, rewrite ratio, audit findings…It is the evidence that AI-driven development works, for UNCTAD and for the next country. ePhyto’s baseline: domain rewritten 6.6 %, screens 22.6 % (the screens had no spec).small
5Country pack with no if
Tier 2
Per country: lists, parameter values, legal references, translations — data only. Behaviour that differs is a rule switched by a parameter.Charts of accounts, taxes (legacy Tax/ConditionalFormula), VAT rates, Luganda strings: Uganda, El Salvador and Cuba become data folders, not code branches.medium
6Operations contract
M6, runbooks
One install command that refuses rather than half-installs; expand-and-contract migrations; backup with a monthly restore drill; a rollback decision tree.We cut over 600+ live users and then grow to 10,000. The runbooks for backup, release and install are ready to adapt.medium
7MCP server to operate an installation
tools/mcp
Health, countries, reference lists, parameters, the check; write tools must be declared or the code does not compile.AN has none. At 10,000 users, support by agent needs a safe door into the running system.medium
8Patterns and small parts
docs/patterns, src/core
Golden-scenario test, outbox (retry sends), period arithmetic (period.ts), chart kit with no library, form kit, eight vertical-add-* skills.A golden scenario for eA+: monthly → daily → gap → abandon daily → back to monthly, in one test. Outbox for sending figures to the GDB. The skills become “add a tax”, “add a chart”.pick as needed

What to leave

Rebuilding eA+ on the templateAN already has the ledger, charts, reports and Keycloak. Moving it means rewriting what works. Copy the rules into AN instead.
Status machine, payments, issued documentsThese are for procedures. eA+ has no application to approve and no certificate to issue.
“No legacy data migration”The foundations paper leaves migration out. eA+ cannot: 600+ users’ data must come across. We write that part ourselves (see the eA+ plan).

Suggested next steps

#StepAgent timeDepends on a person?
1Add the business-scoped client and the one-writer rule to AN, each with its failing test first. They cover both known bugs.hoursFrank’s go-ahead for a PR on AN
2Start DECISIONS.md and the eight numbers in AN from day one.< 1 hno
3Write the eA+ spec in vertical-base’s order, with an accounting version of the 45 questions (periods, closing, counterparts, taxes, migration).1–2 daysanswers from the Uganda team
4Adapt the MCP server and the operations runbooks before the cutover.1 dayno

Confidence: moderate. vertical-base is private and its method documents are marked “harvested draft v0 — not yet reviewed by the team”. Read at commit cf01057, 24 Sep 2026.

Nelson Pérez · nelson.perez@unctad.orgDraft for discussion · English only