Commit Graph

66 Commits

Author SHA1 Message Date
a8c4944bb6 chore(phase-01): checkpoint after Wave 3 Task 1 — pause for resume on another machine
All checks were successful
Deploy Dimension47 / deploy (push) Successful in 49s
Phase 1 execution state at pause:
- Wave 1 ✓ (01-01 schema/migration, 01-02 pure-function lib)
- Wave 2 ✓ (01-03 seed pipeline + Wizard worked example)
- Wave 3 partial (01-03b Task 1 of 3 done — 6 caster overlays salvaged from c5d40cd)
- Wave 4 pending (01-04 LevelingModule)
- Wave 5 pending (01-05 React wizard UI)

To resume: \`/gsd-execute-phase 1\` discovers SUMMARY files for completed plans
and picks up at 01-03b Task 2 (class-feature-options bulk curation).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 15:13:50 +02:00
c5d40cdae8 feat(01-03b): populate spell-slot overlay for 6 caster classes + Champion
- Cleric / Druid (PREPARED, DIVINE/PRIMAL): L1..L19 standard +2/+1 cadence (19 entries each)
- Witch (PREPARED, ARCANE default): L1..L19 with patron-tradition caveat documented inline (19 entries)
- Bard (SPONTANEOUS, OCCULT): L1..L19 slot progression + L2..L19 repertoireIncrement: 1 per D-18 (37 entries)
- Sorcerer (SPONTANEOUS, ARCANE default): L1=3 grade-1 slots; bloodline-tradition caveat documented; repertoire entries L2..L19 (37 entries)
- Oracle (SPONTANEOUS, DIVINE): L1=3 grade-1 slots; repertoire entries L2..L19 (37 entries)
- Champion: focus-only caster — empty array with comment block explaining focus-pool deferral
- Non-casters (Alchemist/Barbarian/Fighter/Investigator/Monk/Ranger/Rogue/Swashbuckler): empty arrays confirmed (key presence required by seed)
- Wizard untouched (Plan 03 owns it)
- Total entries across all keys: 195 (≥120 must_haves goal met)
- Type-clean: npx tsc --noEmit exits 0
2026-04-27 15:10:27 +02:00
c283cda44d docs(01-03): complete Plan 03 — Foundry seed pipeline + Wizard worked example
Add SUMMARY.md documenting the seed pipeline (320 ClassProgression rows + 1
ClassFeatureOption row), the four auto-fix deviations resolved during execution
(env setup, v8 path, Prisma 7 typed-input, third-party tsc exclusion), and the
contract Plan 03b consumes when appending overlay data.
2026-04-27 14:58:19 +02:00
d421aad4d4 chore(01-03): exclude foundry-pf2e dev clone from tsconfig
- The cloned Foundry pf2e repository ships its own TypeScript source files which
  reference modules our project does not have ('@common/...', 'svelte', 'vite', 'peggy').
- That clone lives at server/prisma/data/foundry-pf2e/ (gitignored, dev-time only;
  the seed reads the JSON files at runtime, never the TS source).
- Add 'prisma/data/foundry-pf2e' to tsconfig exclude list so 'tsc --noEmit' on our
  codebase is unaffected by third-party content.
2026-04-27 14:55:55 +02:00
ce214ab70c fix(01-03): align Foundry path with pf2e-8.0.3 layout
- Foundry pf2e v8 nests pf2e packs under packs/pf2e/ (v7 had packs/classes/ directly)
- Update FOUNDRY_CLASSES_DIR path to packs/pf2e/classes/
- Document v8 layout in SEED-README and update failure-mode path string
- Pitfall #5 mitigation: comment in seed script explains version-specific path

Worked-example verification (Wizard end-to-end):
- 320 ClassProgression rows seeded (16 classes x 20 levels)
- Wizard L1..L19 carry ARCANE spell-slot increments + L1 has 5 cantrips
- Wizard L1 has choiceType=school, choiceOptionsRef=wizard-school
- 1 ClassFeatureOption row for wizard-school (battle-magic / School of Battle Magic)
- Idempotent on re-run: 0 created, 320 updated, 0 errors
2026-04-27 14:53:46 +02:00
e85f790458 feat(01-03): add idempotent ClassProgression + ClassFeatureOption seed script
- Iterate over D16_CLASS_NAMES; read Foundry pf2e class JSONs; merge with hand-curated overlays
- Generic pipeline (Plan 03b appends data to overlay modules; no script changes needed)
- Idempotent findUnique → update OR create per row using compound unique keys
- Loud failure with SEED-README pointer when Foundry clone is missing
- Use Prisma.JsonNull for nullable Json fields per Prisma 7 typed-input contract
- No 'any' types; type-clean against tsconfig.json
2026-04-27 14:48:10 +02:00
d86cf4f434 feat(01-03): add class-feature-options types with Wizard School worked example
- Define ClassFeatureOptionEntry interface as the contract Plan 03b appends to
- Include School of Battle Magic as the worked Wizard School entry (optionsRef: 'wizard-school')
- Add anchor comments naming all remaining class optionsRef strings so Plan 03b knows where to append
- No 'any' types; type-clean against tsconfig.json
2026-04-27 14:45:03 +02:00
29fe01df82 feat(01-03): add spell-slot overlay types with Wizard worked example
- Define SpellTradition type and SpellSlotOverlayEntry interface as the contract Plan 03b appends to
- Wizard fully populated L1..L19 with ARCANE slot progression and L1 cantrip count (5)
- Stub keys for the other 15 D-16 classes set to empty arrays for Plan 03b to populate
- No 'any' types; type-clean against tsconfig.json
2026-04-27 14:44:05 +02:00
65676657fc docs(01-03): add SEED-README with Foundry pf2e clone instructions and pinned tag
- Pin Foundry pf2e tag to pf2e-8.0.3 (current stable, includes Player Core + APG content for all 16 D-16 classes)
- Document clone command, run command, and failure modes
- Reference Plan 03 (Wizard worked example) vs Plan 03b (bulk curation) split
2026-04-27 14:42:58 +02:00
f703b2ed3f chore: merge executor worktree (worktree-agent-a58e8ff5fc0a2fc4e) 2026-04-27 14:36:10 +02:00
3e8698306b docs(01-01): complete level-up foundation plan summary
- Schema, migration, partial unique index, regenerated Prisma Client
- Pure-function module + 9/9 passing Jest spec (Pitfall #8 fixture)
- npm script and .gitignore prepared for Wave 2
- All deviations documented (env setup blocking issue, .js->.ts verification fix)
- Self-check PASSED on files, commits, and runtime verification
2026-04-27 14:33:06 +02:00
8b8e822e5b chore(01-01): add db:seed:class-progression script and gitignore foundry-pf2e
- Add npm script 'db:seed:class-progression' pointing at tsx prisma/seed-class-progression.ts
  (referenced by Wave 2 seed pipeline; placeholder until Wave 2 implements the script)
- Append .gitignore exclusion for server/prisma/data/foundry-pf2e/
  (developer-cloned Foundry pf2e source data, never committed to repo)
2026-04-27 14:30:31 +02:00
65fcebdbdb feat(01-01): implement applyAttributeBoost and isValidBoostSet pure functions
- applyAttributeBoost: PF2e boost-cap-at-18 rule (Pitfall #8 mitigation)
  - Returns score + 2 when current < 18
  - Returns score + 1 when current >= 18
- isValidBoostSet: validates exactly 4 distinct abilities for boost levels
- Pure-function module (no NestJS, no Prisma, no I/O imports)
- TypeScript strict, named exports only
- 9/9 tests pass — proves Jest infrastructure works on src/modules/**/*.spec.ts
2026-04-27 14:30:02 +02:00
1e17225fa2 test(01-01): add failing tests for applyAttributeBoost and isValidBoostSet
- 5 cases for applyAttributeBoost (boost-cap-at-18 rule, Pitfall #8)
- 4 cases for isValidBoostSet (PF2e: 4 distinct abilities required)
- Test fails (RED gate) because module is not yet implemented
2026-04-27 14:29:33 +02:00
78a69c5f31 feat(01-01): add level-up migration with partial unique index
- Generate migration 20260427122603_add_level_up_sessions_and_class_progression
- Auto-creates LevelUpSession, LevelUpHistory, ClassProgression, ClassFeatureOption tables
- Adds Character.freeArchetype and Character.prereqViolations columns
- Hand-append partial unique index 'LevelUpSession_characterId_open_unique'
  with WHERE "committedAt" IS NULL clause (Prisma 7 cannot emit partial indexes)
- Migration applied to dev database via prisma migrate dev
- Prisma Client regenerated and exposes new models + Character columns
2026-04-27 14:28:54 +02:00
de2ec38bf6 feat(01-01): extend Prisma schema with level-up tables and Character columns
- Add LevelUpSession model (DRAFT state, soft-archive on commit via committedAt)
- Add LevelUpHistory model (append-only audit log of committed level-ups)
- Add ClassProgression model (per-class, per-level grants and prof changes)
- Add ClassFeatureOption model (sub-choices like doctrines/schools/instincts)
- Extend Character with freeArchetype Boolean (D-08) and prereqViolations Json (D-06)
- Add reverse relations levelUpSessions and levelUpHistories on Character
- Schema formatted via prisma format and validated via prisma validate
2026-04-27 14:25:10 +02:00
df29617c3e docs(01-02): complete pure-function library plan
Five pure-function modules (types + 4 logic) implemented strict-TDD.
46 passing Jest tests across 4 spec files. Pitfall #8 (boost-cap-at-18)
and Pitfall #9 (no hpCurrent in output) both enforced by spec.

3 documented deviations:
- Rule 3: created apply-attribute-boost.ts dependency (Plan 01-01 work
  not yet merged into worktree base; content matches 01-01 spec exactly)
- Rule 1: corrected L5 expected step list (PF2e CRB has class/skill
  feats only at even levels; plan said feat-class+feat-skill at L5)
- Rule 1: TS-strict type-guard helpers for EvalResult narrowing

Requirements completed: LVL-02, LVL-06, LVL-09, LVL-10, LVL-01, LVL-13, LVL-14
2026-04-27 14:21:00 +02:00
be6eaee6d0 fix(01-02): TS-strict narrowing for EvalResult discriminated union
Rule 1 deviation: TS strict mode (noImplicitAny + strict) couldn't narrow
the EvalResult union via 'r.ok' direct access because the {unknown:true,raw}
variant has no 'ok' property. Added explicit type-guard helpers (isUnknown,
isOk, isFail) for both production and spec narrowing. Runtime behavior
unchanged; tsc --noEmit now exits clean for the leveling lib.

Files:
- prereq-evaluator.ts: 3 type-guard functions, used in OR/AND walkers
- prereq-evaluator.spec.ts: isFail() in lieu of result.ok=== checks
2026-04-27 14:18:10 +02:00
d9ed18c86c feat(01-02): implement compute-applicable-steps (D-10 step ordering)
Task 5 GREEN phase. Pure function returning ordered StepKind[] for a
level-up wizard, conditional on:
- targetLevel (boost levels, skill-increase levels, even/odd)
- hasFreeArchetype (D-13)
- isCaster (D-18)
- classProgressionHasChoiceType (D-19)

Step ordering per D-10:
  class-features → class-feature-choice → boost → skill-increase
  → feat-class/feat-skill (even levels) → feat-general (3,7,11,15,19)
  → feat-ancestry (5,9,13,17) → feat-archetype → spellcaster → review

Invariants: always starts with class-features, always ends with review.
13 tests passing.
2026-04-27 14:14:35 +02:00
de07fc8f78 test(01-02): fix L5 expected step list (Rule 1 deviation)
The plan's expected list for computeApplicableSteps(5, 'Fighter', ...) was
PF2e-incorrect. Per CRB, class feats and skill feats are slotted at EVEN
levels only (2, 4, 6, ..., 20). L5 is odd → no class/skill feat.

Plan said:    [class-features, boost, skill-increase, feat-class, feat-skill, feat-ancestry, review]
PF2e-correct: [class-features, boost, skill-increase, feat-ancestry, review]

The plan's other tests are internally consistent (L4 has feat-class, L3
does NOT have feat-class) — only the L5 case was misstated. Project's
'regelkonform' goal (CLAUDE.md, PROJECT.md) requires PF2e correctness
above plan literalism.
2026-04-27 14:14:24 +02:00
70ec7bb3b7 test(01-02): RED — compute-applicable-steps spec (D-10)
Task 5 RED phase: 13 failing tests covering wizard step ordering.
- Fighter L5 exact step list (no FA, no caster)
- L4 (boost-skip) and L3 (odd-level) edge cases
- L2 has feats but no skill-increase
- Free Archetype toggle (D-13)
- Spellcaster toggle (D-18)
- class-feature-choice when progression has choiceType (D-19)
- Invariants: always starts with class-features, always ends with review

Verified failure: module './compute-applicable-steps' not found.
2026-04-27 14:12:49 +02:00
6011024e87 feat(01-02): implement recompute-derived-stats (Pitfall #8/#9 safe)
Task 4 GREEN phase. Pure pipeline computing DerivedStats from a character
snapshot, wizard choices, and ClassProgression row.

- Imports applyAttributeBoost (Pitfall #8 boost-cap-at-18)
- proficiencyBonus(rank, level) = base[rank] + level (UNTRAINED=0)
- hpMax = ancestryHp + (classHp + conMod) × newLevel
- AC = 10 + min(dexMod, dexCap) + armorAc + proficiencyBonus(armor)
- classDc / perception / saves use proficiencyChanges from progression
  with fallback to character's pre-existing rank
- Output object NEVER contains current/temp HP fields (Pitfall #9)

Pure function, no NestJS, no Prisma, no mutation of input.
5 tests passing.
2026-04-27 14:11:58 +02:00
8dd55b6fa9 test(01-02): RED — recompute-derived-stats spec (Pitfall #8/#9)
Task 4 RED phase: 5 failing tests covering pure recompute pipeline.
- hpMax = ancestryHP + (classHP + conMod) × newLevel
- boost-cap-at-18 for CON boost (Pitfall #8)
- proficiencyChanges from ClassProgression applied (fortitude EXPERT)
- Pitfall #9: result MUST NOT contain hpCurrent or hpTemp
- level passthrough

Verified failure: module './recompute-derived-stats' not found.
2026-04-27 14:10:28 +02:00
da82d9bf82 feat(01-02): implement prereq-evaluator (D-01..D-04)
Task 3 GREEN phase. Three-layer parser + evaluator + German formatter.

Evaluable patterns (D-01):
- Skill rank: 'Trained in Athletics', 'Expert in Stealth', etc.
- Disjunctive OR-list (Oxford comma): 'X, Y, or Z'
- Conjunctive AND: 'X; Y'
- Bare feat name (Title Case, ≤4 words, no function words)
- Heritage: '<name> heritage'
- Class ref + Ancestry ref (against known sets)
- Level ref: 'level N'

Non-evaluable (D-02 → {unknown, raw}):
- Spellcasting tradition refs (spellcasting class feature, divine spells, etc.)
- Deity / worship-of refs
- Age / ethnicity refs
- Vision/sense traits (low-light, darkvision, scent)
- Free-text sentences (heuristic: contains 'you', 'a', 'the', 'of', 'and', 'to')

UNKNOWN-aggressive: any unknown atom in OR or AND poisons the whole prereq.
German failure reasons (D-15): 'Du benötigst...', 'Dir fehlt das Talent...',
'Voraussetzung nicht erfüllt: ...'.

19 tests passing.
2026-04-27 14:09:43 +02:00
66d9d5cc0a test(01-02): RED — prereq-evaluator spec (D-01..D-04)
Task 3 RED phase: 18 failing tests covering prereq DSL evaluation.
Coverage:
- empty/null inputs (always ok)
- skill rank: trained/expert/master/legendary in <skill>
- disjunctive (comma + or) and conjunctive (semicolon)
- bare feat name lookup
- heritage / class refs
- non-evaluable patterns: spellcasting, deity, age, vision, free-text → {unknown, raw}
- German failure reasons asserted

Verified failure: module './prereq-evaluator' not found.
2026-04-27 14:07:02 +02:00
f1897501de feat(01-02): implement skill-increase-cap (LVL-06)
Task 2 GREEN phase. PF2e skill-increase cap rule:
- UNTRAINED → TRAINED at any level
- TRAINED → EXPERT requires L3+
- EXPERT → MASTER requires L7+
- MASTER → LEGENDARY requires L15+

Pure function, no NestJS, no Prisma. 9 tests passing.
2026-04-27 14:06:09 +02:00
3a4267da8c test(01-02): RED — skill-increase-cap spec
Task 2 RED phase: 9 failing tests covering PF2e skill-increase cap rule
(VALIDATION.md rows 1-W1-06 to 1-W1-11). Implementation follows in next
commit (GREEN). Verified failure: module './skill-increase-cap' not found.
2026-04-27 14:05:36 +02:00
4d2cb5e529 feat(01-02): shared types module for leveling lib
Task 1 of Plan 01-02. Types-only file (no runtime behavior, no test).

- Proficiency union (mirrors Prisma enum)
- PROFICIENCY_BASE_BONUS lookup (untrained 0, trained 2, ..., legendary 8)
- EvalResult discriminated union for prereq evaluation
- StepKind union for wizard step ordering (D-10)
- CharacterContext interface for prereq + recompute inputs
- DerivedStats interface — does NOT include hpCurrent (Pitfall #9)
- ClassProgressionRow interface (read-only)
- WizardChoices interface
2026-04-27 14:05:04 +02:00
7e40449e68 feat(01-02): add apply-attribute-boost dependency from Plan 01-01
Rule 3 deviation: Plan 01-01 (wave 0) work not yet merged into this
worktree base (096edbf). Plan 01-02 imports applyAttributeBoost and
AbilityAbbreviation from this module — required for types.ts and
recompute-derived-stats.ts to compile. Content matches 01-01 plan exactly,
so orchestrator merge will be clean.

- export type AbilityScore = number
- export type AbilityAbbreviation = 'STR'|'DEX'|'CON'|'INT'|'WIS'|'CHA'
- export function applyAttributeBoost(score) — PF2e boost-cap-at-18 (Pitfall #8)
- export function isValidBoostSet(targets) — exactly 4 distinct
2026-04-27 14:04:54 +02:00
096edbf950 docs(01): final plan cleanup — narrative consistency for chain-revalidation deferral and Plan 03b sequential framing 2026-04-27 13:56:19 +02:00
5a62ad8cae docs(01): create phase 1 plans (5 waves, level-up wizard) 2026-04-27 12:11:25 +02:00
caa4367105 docs(01): add validation strategy 2026-04-27 11:36:25 +02:00
588632fbc0 docs(01): research phase domain — Level-Up (PF2e regelkonform) 2026-04-27 11:33:51 +02:00
e3064332cc docs(01): UI design contract approved 2026-04-27 11:17:33 +02:00
96c81fa29d docs(01): UI design contract for level-up wizard 2026-04-27 11:02:09 +02:00
24a9562bf3 docs(state): record phase 1 context session 2026-04-27 10:50:29 +02:00
eb1c57c908 docs(01): capture phase context 2026-04-27 10:50:18 +02:00
72a22c1e2e docs: create roadmap (7 phases) 2026-04-27 10:31:04 +02:00
785980fa31 docs: define v1 requirements 2026-04-27 10:23:30 +02:00
fcb65a58cd chore: remove leftover synthesizer helper script
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:19:07 +02:00
ebe2bd478e chore: remove temp summary build script 2026-04-27 10:18:32 +02:00
5e332ad8ef docs(research): synthesize project research 2026-04-27 10:18:23 +02:00
12468bc69b chore: add project config 2026-04-27 09:27:53 +02:00
6d7a5ba348 docs: initialize project 2026-04-27 09:24:08 +02:00
3e91d5713d docs: map existing codebase 2026-04-27 09:13:11 +02:00
Alexander Zielonka
15dc0d289a chore: Remove library link from navbar
All checks were successful
Deploy Dimension47 / deploy (push) Successful in 37s
Library is now accessed per-campaign via the campaign detail page.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:17:01 +01:00
Alexander Zielonka
4b3c0d2667 feat: Add GM library for battle maps and NPC templates
All checks were successful
Deploy Dimension47 / deploy (push) Successful in 35s
- Add library page with tabs for maps and combatants
- Create map upload modal with grid configuration
- Create NPC/monster template modal with abilities
- Add library link to campaign page (GM only)
- Add battle feature TODO documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:28:38 +01:00
Alexander Zielonka
d6f2b62bd7 feat: Add battle screen with real-time sync (Phase 1 MVP)
All checks were successful
Deploy Dimension47 / deploy (push) Successful in 35s
- Add battle module with sessions, maps, tokens, and combatants
- Implement WebSocket gateway for real-time battle updates
- Add map upload with configurable grid system
- Create battle canvas with token rendering and drag support
- Support PC tokens from characters and NPC tokens from templates
- Add initiative tracking and round management
- GM-only controls for token manipulation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 10:04:16 +01:00
Alexander Zielonka
f4c7386358 chore: Add favicon and improve meta tags, remove unused files
All checks were successful
Deploy Dimension47 / deploy (push) Successful in 40s
- Replace vite.svg with Dimension47 logo as favicon
- Add comprehensive meta tags (OG, Twitter, keywords)
- Remove unused action icon files (old versions)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 09:09:29 +01:00
Alexander Zielonka
464b92d3b5 feat: Add AONPRD link and hide notes for weapons in item modal
All checks were successful
Deploy Dimension47 / deploy (push) Successful in 35s
- Added external link to Archives of Nethys for all equipment items
- Notes section now only displays for non-weapon items
- Uses equipment.url field from database, prepends https://2e.aonprd.com if needed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:49:54 +01:00