Commit Graph
64 Commits
Author SHA1 Message Date
Keith Solomon 8eefd749be chore: add Node toolchain, archetypes.json, and placeholder images 2026-07-12 19:46:29 -05:00
Keith Solomon 78565cfae9 docs: add Plan 3c implementation plan (JavaScript frontend) 2026-07-12 19:24:12 -05:00
Keith Solomon 7acda302e8 docs: add Plan 3c design spec (JavaScript frontend) 2026-07-12 19:15:01 -05:00
Keith Solomon eef8724626 Merge feature/editor-handlers-and-views into develop
Plan 3b: editor handlers, views, and front controller.

Adds the 6 view templates (layout, home, team-editor, battlefield-editor,
match-stub deleted, upload-result deleted), the 5 remaining HTTP handlers
(GetTeamEditor, PostTeamEditor, GetBattlefieldEditor, PostBattlefieldEditor,
PostImageUpload, PostStartMatch), the real front controller in
public/index.php, and the FullFlowTest integration test. The final
whole-branch review found 3 Critical issues (broken upload-asset URL contract,
upload token source mismatch, and an XSS in the PostTeamEditor success page)
plus 2 Important issues (dead home.php/match-stub.php/upload-result.php);
all were fixed in 4 follow-up commits before this merge.

196/196 tests pass; PHPStan level 6 clean; PHPCS 0 errors on new files.
The web app is fully functional from the browser: php -S 0.0.0.0:8000 -t public
serves the home page, team editor, battlefield editor, image upload endpoint,
and asset-serving endpoint end-to-end.
2026-07-07 10:11:27 -05:00
Keith Solomon b4495f24af chore: remove unused match-stub and upload-result view templates
Neither src/Views/match-stub.php nor src/Views/upload-result.php is
referenced by any handler or route in Plan 3b:

- match-stub is the Plan 4 battle-interface placeholder; Plan 3b does
  not register a /match route.
- upload-result is the iframe-style post-upload response; Plan 3b
  returns JSON from POST /assets/upload and Plan 3c will wire the
  client-side upload form.

Both files were over-eager scaffolding from Task 3 (6a0b147). Drop
them in a follow-up commit rather than amend the shared Task 3 commit.
2026-07-06 23:24:27 -05:00
Keith Solomon ba8fd00411 refactor: route GetHomePage through the home.php template
The handler had a stale inline heredoc that used a '{{ csrf }}' string
substitution to inject the token. The home.php template created in Task 2
is the canonical version (uses render_layout + Escape::attr). Switching
to the template removes the duplicated markup and the ad-hoc str_replace
escape path.
2026-07-06 23:23:32 -05:00
Keith Solomon d15dfc6835 fix: escape scenario id when serialising saved page
PostTeamEditor interpolated the scenario id into a <script> block as
'localStorage.setItem("scenario:<id>", ...)', so an id containing
'</script><script>...</script>' would break out of the JS-string context
and execute in the browser. Use json_encode with JSON_HEX_TAG / HEX_AMP /
HEX_APOS / HEX_QUOT so the id is always a safe JS string literal.

Adds a PostTeamEditorTest case that submits '</script><script>alert(1)</script>'
and asserts the literal '<script>alert(1)</script>' substring is absent
from the response. Updates the existing happy-path and FullFlowTest
assertions to match the new 'scenario:"demo"' (quoted) form.
2026-07-06 23:22:42 -05:00
Keith Solomon 61abb93e59 fix: align upload-asset URL contract end-to-end
- ImageUploadService::store() now returns /assets/uploads/<token>/<file>
  so the URL the upload handler emits matches the new GET route.
- public/index.php registers a dedicated GET /assets/uploads/{userToken}/{filename}
  route; the legacy /assets/{kind}/{filename} is kept as a fallback.
- GetAssets reads the upload token from $request->server['__uploads_token']
  (the front controller threads it that way) instead of the cookies bag.
- Adds GetAssets unit tests for the upload-token happy path and a
  token-mismatch 404, plus a FullFlowTest step that uploads and re-fetches
  the asset through the front controller.
2026-07-06 23:21:33 -05:00
Keith Solomon 5d9af7a4fd test: cover full create-and-save flow end-to-end
Add FullFlowTest, a single end-to-end test that exercises the home page, the team editor POST, the battlefield editor POST, and the start-match POST through the front controller (no php -S).

Wiring fixes in public/index.php (called out in the test brief):

- Honor $_SERVER['__csrf_secret'] when set so the test can supply its own secret; fall back to BATTLEFORGE_SECRET / var/secret.key otherwise.
- Read the raw body from $_SERVER['__raw_body'] when set; fall back to php://input otherwise. PHP CLI's php://input is empty, so an explicit hook is needed for JSON bodies.
- Return the response status from the front controller so the test can assert the HTTP status it set via http_response_code().

Test fixes:

- Drop the static keyword on the runFrontController closure; static forbids $this access and the closure must capture $this to record lastStatus.
- Drop the redundant '?? ''' on the ob_get_clean() result; (string) ob_get_clean() is always a string.
- Set $_SERVER['__raw_body'] alongside $this->rawBody for the JSON requests so the front controller can read the body.
2026-07-06 22:59:18 -05:00
Keith Solomon d387caca86 feat: wire the front controller and harden userToken path 2026-07-06 22:36:34 -05:00
Keith Solomon 2dc7bc1130 feat: add image upload and start-match handlers 2026-07-06 22:24:07 -05:00
Keith Solomon 7cb670b512 feat: add battlefield editor GET and POST handlers 2026-07-06 22:05:47 -05:00
Keith Solomon 12b1547fac feat: add team editor GET and POST handlers 2026-07-06 21:54:59 -05:00
Keith Solomon 6a0b147e4e feat: add battlefield, match stub, and upload result templates 2026-07-06 21:41:18 -05:00
Keith Solomon 7e6240733b feat: add home and team editor templates 2026-07-06 21:30:17 -05:00
Keith Solomon c2233c1639 feat: add shared layout template 2026-07-06 21:21:17 -05:00
Keith Solomon 58b3bc8ece docs: add Plan 3b implementation plan (handlers, views, front controller) 2026-07-06 21:10:59 -05:00
Keith Solomon db12577e78 docs: add Plan 3b design spec (handlers, views, front controller) 2026-07-06 21:00:20 -05:00
Keith Solomon 87a7e10c06 Merge feature/persistence-backend into develop
CI / php (push) Failing after 1m19s
Plan 3a (10 of 17 written tasks): web toolchain, output escaping, CSRF,
Request/Response value objects, Router, JSON serializer, image validator,
image upload service, scenario draft, and the first two HTTP handlers
(home page and asset serving). The remaining 7 tasks (5 more handlers,
6 view templates, the front controller, full-flow integration test, and
CI verification) are scope notes in the plan; the next plan will pick
them up.

177/177 tests pass; PHPStan level 6 clean; PHPCS clean on the new files
(pre-existing line-length warnings remain in Plan 1+2 files). All
deviations from the brief are recorded in the per-task reports under
.superpowers/sdd/.
2026-07-06 19:33:57 -05:00
Keith Solomon 3e4184f08d feat: add home page and asset-serving handlers 2026-07-06 19:02:06 -05:00
Keith Solomon 0f4a220e70 feat: add ScenarioDraft form-field adapter 2026-07-06 18:49:33 -05:00
Keith Solomon c24964ff96 feat: add image upload service 2026-07-06 18:36:34 -05:00
Keith Solomon 6399e2d86c feat: add image content validator 2026-07-06 18:32:50 -05:00
Keith Solomon 288c42e176 feat: add JSON serializer for scenarios and match state 2026-07-06 18:20:01 -05:00
Keith Solomon 8b83df60cd feat: add Http router 2026-07-06 17:58:56 -05:00
Keith Solomon 3263975d2a feat: add Request and Response value objects 2026-07-06 17:52:29 -05:00
Keith Solomon 9ce0c2ac20 feat: add CSRF token store and verifier 2026-07-06 17:44:41 -05:00
Keith Solomon a05baeb4f6 chore: track tests/Integration directory with placeholder
The phpunit.xml split into unit + integration testsuites requires the
integration directory to exist on disk, even when empty. The .gitkeep
keeps the directory present in fresh checkouts and on CI; the first real
integration test in a later task will replace the placeholder.
2026-07-06 17:24:41 -05:00
Keith Solomon eed678e688 chore: add web toolchain and infrastructure for Plan 3 2026-07-06 17:22:46 -05:00
Keith Solomon 17782aab33 docs: complete Plan 3a scope notes (handlers/views/front controller stubbed for Plan 3b) 2026-07-06 16:01:22 -05:00
Keith Solomon 8df51fc1ed docs: in-progress Plan 3a (PHP backend) - 10 of ~19 tasks 2026-07-06 15:58:55 -05:00
Keith Solomon 18520fee22 docs: add Plan 3 design spec (persistence, editors, uploads) 2026-07-06 15:36:21 -05:00
Keith Solomon 1d69e89faf chore: add editor settings and initial project notes
CI / php (push) Failing after 1m43s
2026-07-06 14:34:43 -05:00
Keith Solomon 02addec8df docs: include Plan 2 implementation plan in repo 2026-07-06 14:33:41 -05:00
Keith Solomon 86d82c353d Merge feature/curated-content-and-objectives into develop
CI / php (push) Failing after 1m37s
Plan 2: Curated Content, Abilities, Objectives, and Scenario Validation.

Adds the curated content library (archetypes, abilities, terrain behaviors),
per-round objective control, both victory conditions, and full scenario
validation. 9 production files, 7 test files, 130/130 tests, PHPStan level 6
clean, PHPCS clean. See docs/superpowers/plans/2026-07-05-curated-content-
abilities-and-objectives.md for the implementation plan.
2026-07-05 20:38:44 -05:00
Keith Solomon 39b15c35da refactor: tighten useAbility and Scenario archetype lookup
Final-review-driven changes (Tasks 6/M1, I1 from the ledger):

- Drop the redundant abilities-list check in CombatEngine::useAbility.
  By construction (Scenario::__construct enforces the allowlist), any
  ability the unit 'knows' is also archetype-allowed; the second check
  alone is sufficient and removes a dead code path.
- Update testUseAbilityRejectsAnAbilityTheArchetypeForbids to assert the
  'Unit archetype forbids that ability.' message it actually exercises.
- Compute $template once in Scenario::__construct's per-unit loop and
  drop the redundant catalog lookup on the next line.
2026-07-05 20:33:03 -05:00
Keith Solomon 12f5c0bd3a test: cover scenario to match flow with ability and objective 2026-07-05 20:23:28 -05:00
Keith Solomon 6fffaa2306 feat: validate scenario deployment zones and objectives 2026-07-05 20:11:35 -05:00
Keith Solomon 84fb175c0c feat: resolve objective control and objective victory 2026-07-05 20:06:27 -05:00
Keith Solomon 088e85c9b4 feat: model scenarios and start match snapshots 2026-07-05 19:27:22 -05:00
Keith Solomon 06632ff9b3 feat: model objectives, deployment zones, and victory conditions 2026-07-05 19:11:24 -05:00
Keith Solomon e70b60696c feat: track archetype, abilities, and buff on unit state 2026-07-05 19:05:03 -05:00
Keith Solomon 88149ab1cf feat: catalog curated abilities and definitions 2026-07-05 18:47:20 -05:00
Keith Solomon 0ac8c06c5e feat: catalog curated unit archetypes and templates 2026-07-05 18:41:53 -05:00
Keith Solomon 78fc802cdc fix: enforce LF for PHP files 2026-07-04 18:07:00 -05:00
Keith Solomon de0bc9c43f ci: pin workflow action revisions 2026-07-04 16:15:54 -05:00
Keith Solomon 07e58c84fe ci: enforce PHP quality checks 2026-07-04 16:11:14 -05:00
Keith Solomon fef22d7b56 fix: guard invalid turn transitions 2026-07-04 16:07:36 -05:00
Keith Solomon acfbbf4a91 feat: add alternating team turns 2026-07-04 16:02:49 -05:00
Keith Solomon 7588b304e1 refactor: reuse position distance for attacks 2026-07-04 15:58:29 -05:00
Keith Solomon 3c6359243a feat: resolve attacks and elimination victory 2026-07-04 15:53:57 -05:00
Keith Solomon 3eba823e52 fix: enforce executable movement state 2026-07-04 15:47:29 -05:00
Keith Solomon 1550e2920b feat: validate and resolve unit movement 2026-07-04 15:37:05 -05:00
Keith Solomon 5297b41208 fix: enforce immutable match state invariants 2026-07-04 15:33:05 -05:00
Keith Solomon 94560da5b4 test: verify original match remains unchanged 2026-07-04 15:25:06 -05:00
Keith Solomon 0c5e824942 feat: model immutable combat state 2026-07-04 15:23:00 -05:00
Keith Solomon 4421c5ae32 test: strengthen battlefield boundary coverage 2026-07-04 15:19:06 -05:00
Keith Solomon b789f1b61f fix: validate battlefield reachability inputs 2026-07-04 15:15:08 -05:00
Keith Solomon 189be5bc64 feat: model battlefield terrain and movement costs 2026-07-04 15:08:40 -05:00
Keith Solomon 7b82adbd71 chore: identify Composer package as project 2026-07-04 15:05:11 -05:00
Keith Solomon a97ecbc6d3 chore: bootstrap PHP quality toolchain 2026-07-04 15:02:06 -05:00
Keith Solomon e20017f1e5 docs: plan combat core implementation 2026-07-04 14:59:00 -05:00
Keith Solomon 5ddfff2679 chore: ignore local worktrees 2026-07-04 14:59:00 -05:00
Keith Solomon f43fa541c0 docs: define curated tactical sandbox scope 2026-07-04 13:41:13 -05:00