Roadmap — Appwrite migration (Epics A–G)
Purpose: the big-picture sequence of the migration. Granular tasks live on Project 11; this is the durable overview. Status: as of 2026-07-30 — this roadmap is complete and now historical. Epics A–G all closed: A–F merged during sprint 32 (api #110–#150, web #89–#139, mobile #108–#131, 2026-06-25→07-03), and Epic G finished in two halves — the decommission pre-ramp (#143, 07-03; #149, 07-04; #248, 07-12) and the M6 production-cutover gate (#179/#180/#265, 2026-07-11→07-24). The seven gap tickets shipped too — audit-wiring, observability, reporting, and the payments trio #145/#146/#147 (reframed 2026-07-01/02 to the AngelPay on-device model).
What replaced it. The live plan is no longer epic-shaped. Since 2026-07-11 the work runs as Wave 3 tracks (
wave3-mvp-analysis.md) driven by two verification boards (../product/user-stories.md,../product/mobile-user-stories.md) and tracked against milestones M9 → M10 → M11 inmilestones.md. Read those for current state; read this file for how the platform got here.Frontend/atomic track — closed. The organism/template tier that was open here merged 2026-07-07 (web #80/#82/#83/#85/#86/#87, mobile #103/#104/#106), and every net-new backend gap listed below (customers, notifications, VAS, white-label, denomination snapshot, approvals, held-cart, global search) shipped during sprints 33–34. QR tender stayed deferred by PDR-0001. The design work then moved on to a different problem — not “is the screen built” but “does it match the frame” — which is the design-parity pipeline, not this roadmap.
Sequence
Section titled “Sequence”The work is grouped into seven epics, ordered by dependency (Contracts → Data/Auth → Storage/Functions/Clients → Cutover).
A Foundation ──┬─► B Data ──┐ ├─► C Auth ──┼─► F Client integration ─► G Cutover & decommission ├─► D Storage┤ └─► E Functions┘See ../diagrams/migration-epics-dag.md for the detailed graph.
Epic A — AppwriteFoundation (9 tickets)
Section titled “Epic A — AppwriteFoundation (9 tickets)”Stand up the platform: Appwrite CLI + appwrite.json skeleton, an ADR, NestJS server-SDK module (narrowed — not a CRUD proxy), Web SDK client + SSR, Web type generation (additive, alongside api-types), Kotlin SDK client, an Android Appwrite playground demo ticket, CI schema/functions deploy, and a revision of the POS reuse analysis for Appwrite.
Done looks like: every repo can talk to Appwrite; schema + types generate; CI can push; Appwrite features are demoable in the Android playground.
State (2026-07-03): ✅ done — api CLI + appwrite.json skeleton #111, server-SDK module #112, CI schema/functions deploy #122, production feature flags #123, reuse-analysis revision #110; web SDK client + SSR #90, type generation #100; mobile Kotlin SDK client #108, type generation #109, playground demos #113 (merged 2026-06-25→07-01; a TablesDB migration lost in a squash-merge was restored in api #124, and mobile #123 re-pointed the app at the canonical terminales DB).
Epic B — AppwriteData (7 tickets)
Section titled “Epic B — AppwriteData (7 tickets)”The POS data layer as schema-as-code + RLS (no NestJS CRUD proxy): database schema + type generation and the domain collections — catalog, foundations (merchants/stores/terminals/audit_log), inventory, sales, staff (employees profile) — plus adapting the unit tests from TypeORM. (The repository-abstraction-layer ticket was removed 2026-06-19.)
Done looks like: all POS collections exist as code, typed, with store-team permissions; clients read/write them directly under RLS; tests cover them.
State (2026-07-03): ✅ done — schema + type generation #113, catalog #115, store/terminal/audit #126, staff #129, inventory #136, sales #138, sensitive-ops audit wiring #131, unit tests adapted from TypeORM #141 (all terminales-api, merged 2026-06-29→07-02).
Epic C — AppwriteAuth (16 tickets)
Section titled “Epic C — AppwriteAuth (16 tickets)”Replace BetterAuth: NestJS token-validation guard, store-team roles/multitenancy (store=team, merchant=collection, roles via membership), user-management endpoints, invite flow, PIN custom-token (API); login (email/magic-link), session-cookie/SSR bridge, forgot-password, 2FA (email/SMS), user-management UI, presence (Presences API), PIN re-target (Web); login, session/JWT, 2FA/forgot, PIN (Mobile).
Done looks like: all auth flows run on Appwrite; data authz is Appwrite RLS; the API authorizes its few endpoints via the Appwrite guard + assertStoreRole.
State (2026-07-03): ✅ done — api token guard #114, teams/roles/multitenancy #118, invites #127, user-management endpoints #130, PIN custom token #132; web login #101, forgot-password #123, 2FA #124, session-cookie/SSR bridge #125, user management + invites #126, presence #128, PIN re-target #131; mobile login #115, session/JWT #119, 2FA + forgot-password #120, PIN custom token #124 (merged 2026-06-28→07-02). Legacy controllers migrated onto the Appwrite guard afterwards (api #148, closed 2026-07-03 via PR #150).
Epic D — AppwriteStorage (4 tickets)
Section titled “Epic D — AppwriteStorage (4 tickets)”Buckets-as-code (Infra), a NestJS file service + tokens (API), and upload integration for Web and Mobile. Done looks like: files upload to Appwrite with scoped tokens; clients integrated. State (2026-07-03): ✅ done — buckets schema from CLI #116 + file service/tokens #117 (api), web upload integration #91, mobile upload integration #114 (merged 2026-06-27→06-30).
Epic E — AppwriteFunctions (2 tickets)
Section titled “Epic E — AppwriteFunctions (2 tickets)”Functions scaffolding + CI deploy (Infra) and a hello-world validation (API). Done looks like: the functions pipeline deploys and runs end to end. State (2026-07-03): ✅ done — scaffolding + CI deploy #128 (2026-07-01), hello-world validation #133 (2026-07-02).
Epic F — AppwriteClientIntegration (3 tickets)
Section titled “Epic F — AppwriteClientIntegration (3 tickets)”Wire the UIs to real Appwrite data: the React Query ↔ Appwrite adapter + re-point Web resources (Web), and offline-first direct reads (Mobile). Done looks like: Web resources read/write Appwrite via the adapter; the Android terminal reads from cache offline and syncs idempotently. State (2026-07-03): ✅ done — React Query ↔ Appwrite adapter #121 (2026-06-29), web re-points #130 (2026-07-01) + #139 (products/variants/barcodes/tax-rates, 2026-07-03), mobile offline-first direct reads #125 (2026-07-02).
Epic G — Cutover & decommission (2 tickets)
Section titled “Epic G — Cutover & decommission (2 tickets)”Introduce the production feature-flag scheme (appwrite_*, default OFF, rollout + kill-switch) and, after ramp, decommission TypeORM + BetterAuth.
Done looks like: production traffic migrated behind flags; dead legacy stack removed; app boots on Appwrite auth only.
State (2026-07-30): ✅ done, but not in the order it was written. The decommission ran pre-ramp — there was no production traffic to ramp behind — and finished 2026-07-04..12 (#143 → #149 → #248). The “cutover” half then became its own ProdCutover ticket family at the M6 gate: appwrite push backlog flush + pull verify #179, migrations reintroduced as the only DDL path #180 (2026-07-11), GitHub Actions re-enabled #265 (07-24).
The flag half inverted: instead of a dark ramp with flags defaulting OFF, the PO directed on 2026-07-14 that every flag be ON for MVP. The runtime scheme (api #123 + the #173 evaluator) is still there, so a post-go-live kill-switch remains possible — that ramp is the one open piece, ticket #264, and it belongs to M11 (go-live), not to this epic.
Gap features (added 2026-06-22, all terminales-api)
Section titled “Gap features (added 2026-06-22, all terminales-api)”Re-makes of original POS work that the A–G batch didn’t cover, authored Appwrite-native and promoted as issues #103–109 (each supersedes its TypeORM-era original):
State (2026-07-03): ✅ all seven merged — audit-wiring #103 → PR #131 (2026-07-02), observability #104 → #144 (2026-07-02), reporting #108 → #139 + #109 → #142 (2026-07-02), and the payments trio — reframed 2026-07-01/02 to the AngelPay on-device model (see ../integrations/angelpay-integration-plan.md) — PSP adapter #107 → PR #145, card-present #105 → #147, multi-tender #106 → #146 (all merged 2026-07-03). The AngelPay track also added api terminal pairing #137 + routing fields #140 (2026-07-02) and mobile #129/#130/#131 (2026-07-03); web AngelPay tickets #137/#138 remain open.
- AppwritePayments — PSP adapter (#107, ←#36), card-present checkout (#105, ←#35), multi-tender settlement (#106, ←#34). PSP secrets + DBOS durability stay server-side; state in the
payment_intentscollection. - AppwriteReporting — daily sales report (#108, ←#57), end-of-day Z-report (#109, ←#58). Server aggregation over Appwrite collections.
- AppwriteObservability — POS dashboards & tracing (#104, ←#56). Instruments the Appwrite-era flows.
- AppwriteData (follow-up) — wire remaining sensitive ops to
audit_log(#103, ←#59).
Priorities (as drafted)
Section titled “Priorities (as drafted)”- P1 (27 tickets): Foundation + core Data (catalog/foundations/inventory/sales/staff) + core Auth + the RQ adapter + AppwritePayments (×3).
- P2 (23 tickets): storage adapter, presence, invites, 2FA (email/SMS), client re-point, functions, Android playground demos, reporting (×2), observability, audit-wiring, prod-flags (runtime), decommission, docs/tests.
(50 issues at the 2026-06-22 promotion: the 43-ticket batch + 7 gap tickets. The backlog has since grown far past that — api issues reach #428, web #502, mobile #309 — through the AngelPayCardPayments, VercelDeploys, DesignSystem, DesignParity, Wave 3 and MantarysAggregator tracks. Every issue named in this roadmap is now closed. As of 2026-07-30 the open backlog is 27 issues and none of them belong to Epics A–G — see milestones.md M11.)
What “done” means overall
Section titled “What “done” means overall”All POS domains run on Appwrite; clients hit Appwrite directly for simple paths and NestJS for complex ones; the legacy stack is removed; environments are reproducible from appwrite.config.json + CI. All of that is true as of 2026-07-30 — which is why this roadmap is closed.
What “done” means now is a different question, answered by milestones.md M10–M11: every user story green on Built · Mock E2E · Live E2E, the parity galleries clean, the cutover runbook written and executed. See open-questions-and-todos for what is deliberately deferred and what is still an open PO question.