feat(backend): versioned stat schemas + stats storage + validation (#139) #206
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/139-stat-schemas"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Second backend issue of the v3.9.0 Game-Aware Systems pillar. Targets the integration branch. Builds on #133.
Closes #139.
What
The structured-stat foundation that #140 (editor), #142 (schema-targeted generation), and #145 (conversion wizard) build on.
game_system_schemastable — versioned (UNIQUE(system_id, version)),statusasTEXT+CHECK(not a PG enum),definitionJSONB, FK togame_systemsON DELETE CASCADE. Seeded with dnd5e v1 and pf2e v1 (npc + creature sections) loaded fromapp/game_systems/<key>/schema_v1.json. Migrationc7d8e9f0a1b2(chains off #133'sb5c6d7e8f9a0).statsJSONB envelope onlore_entriesandlore_entry_versions(nullable):{system, schema_version, values, visibility}, snapshotted into version history likesidebar_fields.game_system_service, hand-rolled, no new dep):validate_entry_statsresolves the campaign's linked active schema, validates values (rejects unknown fields, type mismatches —boolis notint— out-of-range ints, unknown enum choices), server-stampssystem/schema_version(client values ignored, anti-spoof), defaultsvisibilitytogm. A stats write on an unlinked/schema-less campaign or an entry type the schema doesn't cover → 400.statsenvelope on create/update; explicitnullclears it. Response filtering hides GM-only stat blocks from players via the existing structured-item visibility rules.GET /api/game-systems/{system_id}/schemareturns the active schema definition for #140's editor (404 when none, e.g.generic).ensure_builtin_schemasmirrors #133'sensure_builtin_systemsso thecreate_alltest harness (which skips migrations) sees the seeded schemas.webapp/CLAUDE.mdmigration list brought current (adds #133 + #139; head →c7d8e9f0a1b2).Verification (Docker, py3.12)
test_stat_schemas.pycovering validator accept/reject, the lore-CRUD stats path, version snapshot, and the schema endpoint) — no regressions.upgrade head→downgrade -1→upgrade headclean;game_system_schemasseeded (dnd5e v1 / pf2e v1 active);statscolumns added to both tables.Known follow-ups (out of #139 scope)
stats— the campaign export/import bundle constructs lore dicts from an explicit key list; extending it (with an export-schema-version bump) is a natural follow-up, deliberately left out here. Flagging so a round-trip stat-block loss is tracked.BOT_CONTRACT_VERSIONstays 1.🤖 Generated with Claude Code
statsstorage + validation service #139