|
| 1 | +# [ ] MVP Migration Plan: FastAPI on Railway + TypeScript Frontend on GitHub Pages |
| 2 | + |
| 3 | +## [ ] Summary |
| 4 | +- [ ] Build FastAPI backend on Railway using existing Python game logic |
| 5 | +- [ ] Build React + TypeScript frontend on GitHub Pages |
| 6 | +- [ ] Persist anonymous sessions in Railway Postgres via browser-stored UUID |
| 7 | + |
| 8 | +## [ ] Architecture Decisions (Locked) |
| 9 | +- [ ] Frontend stack: `Vite + React + TypeScript` |
| 10 | +- [ ] Session model: anonymous UUID stored in browser `localStorage` |
| 11 | +- [ ] Session persistence: Railway Postgres |
| 12 | +- [ ] API transition: clean API now under `/api/v1/*` (no Hug compatibility paths) |
| 13 | + |
| 14 | +## [ ] Public API / Interface Changes |
| 15 | + |
| 16 | +### [ ] Backend HTTP API (new) |
| 17 | +- [ ] `GET /api/v1/health` -> `{ "status": "ok" }` |
| 18 | +- [ ] `POST /api/v1/session` -> create/validate session |
| 19 | +- [ ] `POST /api/v1/command` -> execute command and persist state |
| 20 | +- [ ] `POST /api/v1/session/reset` -> clear state for session |
| 21 | + |
| 22 | +### [ ] TypeScript Frontend Types (new) |
| 23 | +- [ ] `SessionCreateRequest`, `SessionCreateResponse` |
| 24 | +- [ ] `CommandRequest`, `CommandResponse` |
| 25 | +- [ ] `ApiError` with stable `code` + `message` |
| 26 | +- [ ] Runtime API response validation (e.g. Zod) |
| 27 | + |
| 28 | +### [ ] Persistence Contract |
| 29 | +- [ ] Create `adventure_sessions` table |
| 30 | +- [ ] Fields: `session_id`, `save_data`, `created_at`, `updated_at` |
| 31 | + |
| 32 | +## [x] Phase 0: Repo Restructure + Guardrails (Day 1) |
| 33 | +- [x] Create `backend/` and `frontend/` directories |
| 34 | +- [x] Keep `adventure/` reusable by backend |
| 35 | +- [x] Add architecture + local dev quickstart docs |
| 36 | +- [x] Standardize env vars (`DATABASE_URL`, `CORS_ALLOW_ORIGINS`, `VITE_API_BASE_URL`) |
| 37 | +- [x] Add `CONTRIBUTING.md` for backend/frontend workflows |
| 38 | + |
| 39 | +### [x] Exit Criteria |
| 40 | +- [x] Monorepo layout documented |
| 41 | +- [x] README has exact run instructions for both apps |
| 42 | + |
| 43 | +## [ ] Phase 1: FastAPI Adapter over Existing Engine (Day 1-2) |
| 44 | +- [ ] Create FastAPI app with startup DB init + CORS + Pydantic models |
| 45 | +- [ ] Implement service flow: load session -> optional `admin_load` -> execute -> `admin_save` |
| 46 | +- [ ] Implement `/health`, `/session`, `/command`, `/session/reset` |
| 47 | +- [ ] Preserve current markdown-to-HTML response behavior |
| 48 | + |
| 49 | +### [ ] Exit Criteria |
| 50 | +- [ ] Manual API flow works end-to-end |
| 51 | +- [ ] Command response parity with current Hug behavior |
| 52 | + |
| 53 | +## [ ] Phase 2: Postgres Persistence (Day 2) |
| 54 | +- [ ] Add SQLAlchemy 2.0 + Alembic in backend |
| 55 | +- [ ] Create initial migration for `adventure_sessions` |
| 56 | +- [ ] Add `SessionRepository` abstraction |
| 57 | +- [ ] Implement `PostgresSessionRepository` |
| 58 | +- [ ] Ensure idempotent session create/get semantics |
| 59 | + |
| 60 | +### [ ] Exit Criteria |
| 61 | +- [ ] Fresh DB migration succeeds |
| 62 | +- [ ] Save/load survives app restart |
| 63 | +- [ ] Reset endpoint clears state correctly |
| 64 | + |
| 65 | +## [ ] Phase 3: TS Frontend MVP (Day 2-3) |
| 66 | +- [ ] Create React UI: transcript, input, status/error, reset/new game |
| 67 | +- [ ] Implement session bootstrap from `localStorage` |
| 68 | +- [ ] Implement command send/receive flow with loading states |
| 69 | +- [ ] Configure `VITE_API_BASE_URL` for environment-specific backend URL |
| 70 | +- [ ] Ensure production build works for GitHub Pages |
| 71 | + |
| 72 | +### [ ] Exit Criteria |
| 73 | +- [ ] App playable from GitHub Pages |
| 74 | +- [ ] Refresh resumes session |
| 75 | +- [ ] Reset starts a fresh session |
| 76 | + |
| 77 | +## [ ] Phase 4: Deployments + CI/CD (Day 3-4) |
| 78 | +- [ ] Deploy backend service to Railway |
| 79 | +- [ ] Attach Railway Postgres plugin |
| 80 | +- [ ] Configure backend env vars and health check |
| 81 | +- [ ] Configure GitHub Action to build/deploy frontend to Pages |
| 82 | +- [ ] Configure production CORS for GitHub Pages origin(s) |
| 83 | + |
| 84 | +### [ ] Exit Criteria |
| 85 | +- [ ] Railway API healthy |
| 86 | +- [ ] GitHub Pages deployed successfully |
| 87 | +- [ ] Frontend can call production API without CORS errors |
| 88 | + |
| 89 | +## [ ] Phase 5: Quality, Tests, Contributor UX (Day 4-5) |
| 90 | +- [ ] Backend route tests (`health/session/command/reset`) |
| 91 | +- [ ] Backend service + persistence tests |
| 92 | +- [ ] Frontend API + UI behavior tests |
| 93 | +- [ ] End-to-end smoke test for play/resume/reset |
| 94 | +- [ ] Add contributor docs for extending content and commands |
| 95 | + |
| 96 | +### [ ] Exit Criteria |
| 97 | +- [ ] CI green for backend + frontend |
| 98 | +- [ ] New contributor can run project in <10 minutes from docs |
| 99 | + |
| 100 | +## [ ] Data-Driven Expandability (MVP-Compatible Staging) |
| 101 | +- [ ] Keep existing Python engine for MVP |
| 102 | +- [ ] Define `content/` contract for locations/items/commands metadata |
| 103 | +- [ ] Keep parser/engine in code for now |
| 104 | +- [ ] Plan post-MVP migration of content into validated data files |
| 105 | +- [ ] Add command registry pattern for future plugin-style expansion |
| 106 | + |
| 107 | +## [ ] Testing Scenarios and Acceptance Criteria |
| 108 | + |
| 109 | +### [ ] Core gameplay/session |
| 110 | +- [ ] New browser session starts correctly |
| 111 | +- [ ] Command execution returns expected HTML output |
| 112 | +- [ ] Refresh resumes session state |
| 113 | +- [ ] Reset clears state |
| 114 | +- [ ] Invalid/empty input returns stable error |
| 115 | + |
| 116 | +### [ ] Reliability |
| 117 | +- [ ] Session survives backend restart |
| 118 | +- [ ] Unknown `session_id` handled by create-on-demand policy |
| 119 | +- [ ] DB outage returns structured 5xx response |
| 120 | + |
| 121 | +### [ ] Deployment |
| 122 | +- [ ] GitHub Pages deploy on main succeeds |
| 123 | +- [ ] Railway deploy succeeds and health check passes |
| 124 | +- [ ] Production supports multi-command gameplay flow |
| 125 | + |
| 126 | +## [ ] Risks and Mitigations |
| 127 | +- [ ] Session schema drift -> add session versioning + migrations |
| 128 | +- [ ] Markdown rendering drift -> snapshot parity tests |
| 129 | +- [ ] CORS issues -> explicit allowed-origins env + integration check |
| 130 | + |
| 131 | +## [ ] Assumptions and Defaults |
| 132 | +- [ ] No auth/login in MVP |
| 133 | +- [ ] One local session token per browser |
| 134 | +- [ ] Backend is API-only (no server-rendered pages) |
| 135 | +- [ ] Python engine retained for MVP timeline |
| 136 | +- [ ] Postgres is source of truth for saves |
| 137 | +- [ ] Full data-driven engine evolution happens post-MVP |
0 commit comments