## Summary
- Add `is_admin` column to users table with Alembic migration and a `require_admin` FastAPI dependency that protects all admin-facing write endpoints (games, pokemon, evolutions, bosses, routes CRUD)
- Expose admin status to frontend via user API and update AuthContext to fetch/store `isAdmin` after login
- Make navigation menu auth-aware (different links for logged-out, logged-in, and admin users) and protect frontend routes with `ProtectedRoute` and `AdminRoute` components, preserving deep-linking through redirects
- Fix test reliability: `drop_all` before `create_all` to clear stale PostgreSQL enums from interrupted test runs
- Fix test auth: add `admin_client` fixture and use valid UUID for mock user so tests pass with new admin-protected endpoints
## Test plan
- [x] All 252 backend tests pass
- [ ] Verify non-admin users cannot access admin write endpoints (games, pokemon, evolutions, bosses CRUD)
- [ ] Verify admin users can access admin endpoints normally
- [ ] Verify navigation shows correct links for logged-out, logged-in, and admin states
- [ ] Verify `/admin/*` routes redirect non-admin users with a toast
- [ ] Verify `/runs/new` and `/genlockes/new` redirect unauthenticated users to login, then back after auth
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: #67
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
Add user authentication with login/signup/protected routes, boss pokemon
detail fields and result team tracking, moves and abilities selector
components and API, run ownership and visibility controls, and various
UI improvements across encounters, run list, and journal pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds allowedTypes: string[] to NuzlockeRules. When set, the encounter
selector hides non-matching Pokemon and the routes endpoint filters out
routes with no matching encounters, so only eligible locations appear.
Type picker UI in RulesConfiguration; active restriction shown in
RuleBadges. Backend accepts allowed_types query param and joins through
RouteEncounter.pokemon to filter by type.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In flat mode, parent routes with no direct encounters were being
filtered out even when their children had encounters. Now we pre-compute
which parents have encountered children so they're retained in both
flat and hierarchical modes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Routes are shared per version group, so game-exclusive locations (e.g.,
Black City, White Forest) appeared for both games. Now the /games/{id}/routes
endpoint excludes routes that have no encounters for the requested game,
in both flat and hierarchical modes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Route deletion failed with two integrity errors:
1. route_encounters had no cascade, so SQLAlchemy tried to NULL
the non-nullable route_id instead of deleting the rows
2. boss_battles.after_route_id referenced the route being deleted
Added cascade="all, delete-orphan" to Route.route_encounters and
nulled out boss battle after_route_id references before deletion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `category` field (original/remake/enhanced/sequel/spinoff) to the
Game model and tag all 38 games. Create regions.json with generation
mapping, ordering, and genlocke preset defaults per region. Add
GET /games/by-region endpoint returning games grouped by region.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add three new bulk import endpoints that accept the same JSON format as
their corresponding export endpoints, enabling round-trip compatibility:
- POST /evolutions/bulk-import (upsert by from/to pokemon pair)
- POST /games/{id}/routes/bulk-import (reuses seed loader for hierarchy)
- POST /games/{id}/bosses/bulk-import (reuses seed loader with team data)
Generalize BulkImportModal to support all entity types with configurable
title, example, and result labels. Wire up Bulk Import buttons on
AdminEvolutions, and AdminGameDetail routes/bosses tabs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Routes and boss battles now belong to a version_group instead of
individual games, so paired versions (e.g. Red/Blue, Gold/Silver)
share the same route structure and boss battles. Route encounters
gain a game_id column to support game-specific encounter tables
within a shared route. Includes migration, updated seeds, API
changes, and frontend type updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows each sub-zone within a route group to have its own independent
encounter when the Pinwheel Clause rule is enabled (default on), instead
of the entire group sharing a single encounter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merges the run dashboard into the encounters page as a unified view at /runs/:runId,
adds encounter method grouping in the modal and badges on route rows, improves the
home page with recent runs, adds mobile hamburger nav, and polishes empty states.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Add admin API endpoints for games, routes, pokemon, and route encounters
with full CRUD operations including bulk import. Build admin frontend
with game/route/pokemon management pages, navigation, and data tables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement 13 endpoints: read-only reference data (games, routes, pokemon),
run CRUD with cascading deletes, and encounter management. Uses Pydantic v2
with camelCase alias generation to match frontend types, and nested response
schemas for detail views.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>