Locations like Mt. Moon (with 1F, B1F, B2F floors) are now grouped so only one encounter can be logged per location group, enforcing Nuzlocke first-encounter rules correctly. - Add parent_route_id column with self-referential FK to routes table - Add parent/children relationships on Route model - Update games API to return hierarchical route structure - Add validation in encounters API to prevent parent route encounters and duplicate encounters within sibling routes (409 conflict) - Update frontend with collapsible RouteGroup component - Auto-derive route groups from PokeAPI location/location-area structure - Regenerate seed data with 70 parent routes and 315 child routes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.2 KiB
title, status, type, priority, created_at, updated_at, parent
| title | status | type | priority | created_at | updated_at | parent |
|---|---|---|---|---|---|---|
| Combine sub-areas into single locations | completed | feature | normal | 2026-02-05T14:27:13Z | 2026-02-06T09:56:11Z | nuzlocke-tracker-f5ob |
Some game locations have multiple encounter tables (e.g. Mount Moon 1F, Mount Moon B1F, Mount Moon B2F) but are treated as a single location for Nuzlocke first-encounter rules.
Needs a concept of 'location groups' — a parent location that contains multiple sub-areas, each with their own encounter table. For Nuzlocke purposes, the first encounter in any sub-area of the group counts as that location's encounter.
Implementation Summary
Added hierarchical route grouping so locations like Mt. Moon (with floors 1F, B1F, B2F) are treated as a single location for Nuzlocke first-encounter rules. The first encounter in ANY sub-area counts as that location's encounter.
Changes Made
-
Database Migration (
c3d4e5f6a7b8_add_route_grouping.py)- Added nullable
parent_route_idcolumn with self-referential FK (CASCADE delete)
- Added nullable
-
Backend Model (
backend/src/app/models/route.py)- Added
parent_route_idfield - Added self-referential
parentandchildrenrelationships
- Added
-
Backend Schemas (
backend/src/app/schemas/game.py)- Added
parent_route_idtoRouteResponse,RouteCreate,RouteUpdate - Added
RouteWithChildrenResponsewith nested children
- Added
-
Backend API - Games (
backend/src/app/api/games.py)- Updated
list_game_routesto support hierarchical response (default) or flat list (?flat=true)
- Updated
-
Backend API - Encounters (
backend/src/app/api/encounters.py)- Added validation: cannot create encounter on parent route (400 error)
- Added validation: cannot create encounter if sibling already has one (409 error)
-
Frontend Types (
frontend/src/types/game.ts)- Added
parentRouteIdtoRouteinterface - Added
RouteWithChildreninterface
- Added
-
Frontend Page (
frontend/src/pages/RunEncounters.tsx)- Added
organizeRoutes()helper to build hierarchy from flat list - Added
getGroupEncounter()to check if any child has an encounter - Updated progress counter to count groups (not individual sub-routes)
- Added collapsible
RouteGroupcomponent - Sibling routes are disabled after one has an encounter
- Added
-
Seed Data (
backend/src/app/seeds/fetch_pokeapi.py)- Updated to automatically detect grouped locations from PokeAPI's location/location-area structure
- Parent routes have empty encounters; children have actual encounters
- 70 parent routes with 315 child routes across all games
-
Seed Loader (
backend/src/app/seeds/loader.py,run.py)- Updated
upsert_routesto handle hierarchical structure with parent_route_id - Updated seed runner to process child route encounters
- Updated
Considerations
- Data model: add a parent_route_id or location_group concept to the Route model
- Seed data: identify which routes should be grouped (automatically derived from PokeAPI location/area structure)
- Encounter tracking: when logging an encounter in a sub-area, mark the whole group as visited
- Route list UI: show grouped locations as collapsible sections