# Plan 3b: Editor Handlers, Views, and Front Controller Design ## Purpose Plan 3b of the four-plan BattleForge build. Completes the web layer that Plan 3a started: the seven remaining PHP tasks that ship the editor pages, the front controller, the full-flow integration test, and CI verification. Plan 3a delivered 10 of 17 written tasks: toolchain, output escaping, CSRF, Request/Response, Router, JSON serializer, image validator, image upload service, scenario draft, and the first two HTTP handlers (home page and asset serving). Plan 3b delivers the remaining 7: - The five remaining HTTP handlers (team editor GET/POST, battlefield editor GET/POST, image upload POST, start-match POST) - The six view templates - The full front controller that wires the routes together and issues the CSRF + upload tokens - A full-flow integration test - CI verification - Final whole-branch code review The design is a delta on `docs/superpowers/specs/2026-07-06-persistence-editors-design.md` (the Plan 3 spec), which is the authoritative design. This document records only the clarifications and decisions that are specific to Plan 3b; everything else is inherited from the Plan 3 spec. ## Success Criteria Plan 3b succeeds when a new user, without developer assistance, can: 1. Visit `http://localhost:8000/`, see the home page, and click "New scenario". 2. Fill in two teams of 3-6 units each on the team editor, upload a custom image, and save. The browser shows a "Saved" toast and the scenario lands in `localStorage` under `scenario:{id}`. 3. Navigate to the battlefield editor, paint a small grid, place deployment zones, place an objective (when the victory condition requires it), and save. The same `localStorage` key is updated with the assembled scenario. 4. Click "Start match" and have the initial `MatchState` round-trip through the server's `PostStartMatch` endpoint, land in `localStorage` under `match:current`, and render the "match loaded" stub. 5. Refresh the page, navigate around, and find their scenarios still in their browser. 6. Try a forged cross-site POST and see a 403. Try to access another user's uploaded image and see a 404. ## Out of Scope (deferred to Plan 3c or Plan 4) - The JavaScript surface: `public/js/storage.js`, `public/js/grid-editor.js`, ESLint, Prettier. The current handlers and views render with HTML form submits and a `