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.
| Piece | vertical-base | Accounting-Next | Fit |
|---|---|---|---|
| Framework | Next.js 16.3 · React 19.2 | Next.js 16 · React 19 | same |
| Database | Prisma 7 · PostgreSQL 18 | Prisma 7 · PostgreSQL 18 + pgvector | same |
| Sign-in | NextAuth 4 · passwords (demo accounts) | NextAuth 4 · Keycloak | keep AN’s |
| Validation · styles | Zod 4 · Tailwind 4 · Radix | Zod 4 · Tailwind 4 · Radix/shadcn | same |
| Tests | Vitest + real-database tests | Jest 30 | port the tests, not the runner |
| Domain | empty: request, status machine, payment, issued document | ledger: operations, journal, charts, reports | different |
| # | Take | What it is | Why eA+ needs it | Size |
|---|---|---|---|---|
| 1 | Tenancy rule + its testscopedDb, 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 |
| 2 | One 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 |
| 3 | The build cycledocs/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 |
| 4 | Decision log + measurementDECISIONS.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 |
| 5 | Country pack with no ifTier 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 |
| 6 | Operations 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 |
| 7 | MCP server to operate an installationtools/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 |
| 8 | Patterns and small partsdocs/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 |
| # | Step | Agent time | Depends on a person? |
|---|---|---|---|
| 1 | Add the business-scoped client and the one-writer rule to AN, each with its failing test first. They cover both known bugs. | hours | Frank’s go-ahead for a PR on AN |
| 2 | Start DECISIONS.md and the eight numbers in AN from day one. | < 1 h | no |
| 3 | Write the eA+ spec in vertical-base’s order, with an accounting version of the 45 questions (periods, closing, counterparts, taxes, migration). | 1–2 days | answers from the Uganda team |
| 4 | Adapt the MCP server and the operations runbooks before the cutover. | 1 day | no |
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.