Phase 9: homebrew content + packs

- Homebrew entity (monster/spell/item/feat/condition) — Dexie v6, repo, hook,
  cascade-deleted with campaign
- Homebrew editor page: per-kind fields + description, create/edit/delete
- Compendium merges campaign homebrew of the matching kind (HB badge, generic
  HomebrewDetail) with the same cross-links (add monster->combat, spell/item->character)
- Content packs: export/import homebrew as JSON (validated, ids reassigned)
- System extensibility documented via the existing RulesSystem registry seam
- Fix: card editors (homebrew/npc/quest/note) debounce-save the FULL snapshot, not
  partial patches — editing two fields fast no longer drops an edit

New homebrew e2e + cascade test coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 07:54:53 +02:00
parent 744e91f703
commit 7100ea8dd4
16 changed files with 383 additions and 28 deletions
+3
View File
@@ -13,6 +13,7 @@ import { QuestsPage } from '@/features/world/QuestsPage';
import { CalendarPage } from '@/features/world/CalendarPage';
import { MapsPage } from '@/features/world/MapsPage';
import { PlayerViewPage } from '@/features/player/PlayerViewPage';
import { HomebrewPage } from '@/features/world/HomebrewPage';
const rootRoute = createRootRoute({ component: RootLayout });
@@ -33,6 +34,7 @@ const questsRoute = createRoute({ getParentRoute: () => rootRoute, path: '/quest
const calendarRoute = createRoute({ getParentRoute: () => rootRoute, path: '/calendar', component: CalendarPage });
const mapsRoute = createRoute({ getParentRoute: () => rootRoute, path: '/maps', component: MapsPage });
const playRoute = createRoute({ getParentRoute: () => rootRoute, path: '/play', component: PlayerViewPage });
const homebrewRoute = createRoute({ getParentRoute: () => rootRoute, path: '/homebrew', component: HomebrewPage });
const routeTree = rootRoute.addChildren([
indexRoute,
@@ -48,6 +50,7 @@ const routeTree = rootRoute.addChildren([
calendarRoute,
mapsRoute,
playRoute,
homebrewRoute,
]);
export const router = createRouter({ routeTree, defaultPreload: 'intent' });