Compare commits
9 Commits
renovate/c
...
012cfb96cd
| Author | SHA1 | Date | |
|---|---|---|---|
| 012cfb96cd | |||
| e3e015852c | |||
| 59b4f7f28c | |||
| e212251da8 | |||
| f49c8cee85 | |||
| b34f1083a3 | |||
| b85668c233 | |||
| 45cbff7672 | |||
| 51b47dbfb0 |
@@ -0,0 +1,19 @@
|
||||
---
|
||||
# nuzlocke-tracker-009n
|
||||
title: Add CLI export for all seed data types
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T11:37:27Z
|
||||
updated_at: 2026-02-08T11:38:48Z
|
||||
---
|
||||
|
||||
Add export functions for games, pokemon, routes/encounters, and evolutions to the seed CLI, matching the existing export API endpoints. Consolidate with the existing --export-bosses into a single --export flag that dumps everything.
|
||||
|
||||
## Checklist
|
||||
- [x] Add export_games() to run.py — writes games.json
|
||||
- [x] Add export_pokemon() to run.py — writes pokemon.json
|
||||
- [x] Add export_routes() to run.py — writes {game_slug}.json per game (routes + encounters)
|
||||
- [x] Add export_evolutions() to run.py — writes evolutions.json
|
||||
- [x] Replace --export-bosses with --export flag that exports all data types
|
||||
- [x] Update __main__.py docstring
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-0arz
|
||||
title: Integration tests for Runs & Encounters API
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:21Z
|
||||
updated_at: 2026-02-10T09:33:21Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write integration tests for the core run tracking and encounter API endpoints. This is the heart of the application.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test run CRUD operations (create, list, get, update, delete)
|
||||
- [ ] Test run creation with rules configuration (JSONB field)
|
||||
- [ ] Test encounter logging on a run (create encounter on a route)
|
||||
- [ ] Test encounter status changes (alive → dead, alive → retired, etc.)
|
||||
- [ ] Test duplicate encounter prevention (dupes clause logic)
|
||||
- [ ] Test shiny encounter handling
|
||||
- [ ] Test egg encounter handling
|
||||
- [ ] Test ending a run (completion/failure)
|
||||
- [ ] Test error cases (encounter on invalid route, duplicate route encounters, etc.)
|
||||
|
||||
## Notes
|
||||
|
||||
- Run endpoints: `backend/src/app/api/runs.py`
|
||||
- Encounter endpoints: `backend/src/app/api/encounters.py`
|
||||
- This is the most critical area — Nuzlocke rules enforcement should be thoroughly tested
|
||||
- Tests need game + pokemon + route fixtures as prerequisites
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-0pas
|
||||
title: Extract version groups and route ordering to JSON files
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-07T13:27:37Z
|
||||
updated_at: 2026-02-07T13:32:30Z
|
||||
---
|
||||
|
||||
Move VERSION_GROUPS and ROUTE_ORDER from fetch_pokeapi.py into separate JSON files (version_groups.json, route_order.json) for easier editing. Update the script to load from the JSON files.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# nuzlocke-tracker-0q8f
|
||||
title: Encounter Tracking Interface
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:44:37Z
|
||||
updated_at: 2026-02-05T14:21:54Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Build the main interface for tracking encounters on each route/area.
|
||||
|
||||
## Checklist
|
||||
- [x] Create route list component showing all areas in the game
|
||||
- [x] Display encounter status per route (uncaught, caught, failed, skipped)
|
||||
- [x] Build encounter modal/form:
|
||||
- [x] Select Pokémon from route's available encounters
|
||||
- [x] Enter nickname for caught Pokémon
|
||||
- [x] Mark as caught, failed (ran/KO'd), or skipped (duplicates clause)
|
||||
- [x] Show route progression (e.g., 15/45 routes completed)
|
||||
- [x] Allow editing/updating existing encounters
|
||||
- [x] Support marking gift/static encounters separately (deferred to nuzlocke-tracker-rxrt)
|
||||
|
||||
## UX Considerations
|
||||
- Quick entry flow - minimize clicks to log an encounter
|
||||
- Visual distinction between route types (grass, water, cave, etc.)
|
||||
- Mobile-friendly for tracking while playing
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
# nuzlocke-tracker-1e9k
|
||||
title: Populate encounter data for Gen 8+ stub games
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T08:59:02Z
|
||||
updated_at: 2026-02-11T13:39:09Z
|
||||
parent: nuzlocke-tracker-rzu4
|
||||
---
|
||||
|
||||
Fill in encounter data for games that currently have null/stub seed files. These games are not covered by PokeAPI and require manual curation or an alternative data source.
|
||||
|
||||
## Games with null/stub data:
|
||||
- [ ] Sword (null)
|
||||
- [ ] Shield (null)
|
||||
- [ ] Brilliant Diamond (null)
|
||||
- [ ] Shining Pearl (null)
|
||||
- [ ] Scarlet (null)
|
||||
- [ ] Violet (null)
|
||||
- [ ] Legends Arceus (null)
|
||||
|
||||
## Format requirements:
|
||||
Each game's JSON file must follow the existing structure:
|
||||
\`\`\`json
|
||||
[
|
||||
{
|
||||
"name": "Route Name",
|
||||
"order": 1,
|
||||
"encounters": [
|
||||
{
|
||||
"pokeapi_id": 25,
|
||||
"pokemon_name": "pikachu",
|
||||
"method": "walk",
|
||||
"encounter_rate": 10,
|
||||
"min_level": 5,
|
||||
"max_level": 8
|
||||
}
|
||||
],
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
\`\`\`
|
||||
|
||||
## Notes:
|
||||
- This is likely the largest manual task unless the "explore automated sources" task finds a viable alternative
|
||||
- Depends on findings from the automated data sources task — if automation is viable, this becomes much easier
|
||||
- Sword/Shield and Scarlet/Violet use open-world/Wild Area mechanics that may need special handling
|
||||
- Legends Arceus has a fundamentally different encounter system (overworld encounters, alpha Pokémon, space-time distortions)
|
||||
- BD/SP are remakes of Diamond/Pearl — existing D/P data could serve as a starting point
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-1guz
|
||||
title: Component tests for key frontend components
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:45Z
|
||||
updated_at: 2026-02-10T09:33:45Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write component tests for the most important frontend React components, focusing on user interactions and rendering correctness.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test `EncounterModal` — form submission, validation, Pokemon selection
|
||||
- [ ] Test `StatusChangeModal` — status transitions, confirmation flow
|
||||
- [ ] Test `EndRunModal` — run completion/failure flow
|
||||
- [ ] Test `GameGrid` — game selection rendering, click handling
|
||||
- [ ] Test `RulesConfiguration` — rules toggle interactions, state management
|
||||
- [ ] Test `Layout` — navigation rendering, responsive behavior
|
||||
- [ ] Test admin form modals (GameFormModal, RouteFormModal, PokemonFormModal) — CRUD form flows
|
||||
- [ ] Test `AdminTable` — sorting, filtering, action buttons
|
||||
|
||||
## Notes
|
||||
|
||||
- Focus on user-facing behavior, not implementation details
|
||||
- Use @testing-library/user-event for simulating clicks, typing, etc.
|
||||
- Mock API responses for components that fetch data
|
||||
- Don't aim for 100% coverage — prioritise the most complex/interactive components
|
||||
- Page components (RunEncounters, RunDashboard, etc.) are large and complex — consider testing their sub-components instead
|
||||
34
.beans/nuzlocke-tracker-1iuh--project-setup-tech-stack.md
Normal file
34
.beans/nuzlocke-tracker-1iuh--project-setup-tech-stack.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# nuzlocke-tracker-1iuh
|
||||
title: Project Setup & Tech Stack
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:43:55Z
|
||||
updated_at: 2026-02-04T15:55:46Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
blocking:
|
||||
- nuzlocke-tracker-sm1b
|
||||
- nuzlocke-tracker-k5lm
|
||||
- nuzlocke-tracker-uw2j
|
||||
- nuzlocke-tracker-dgax
|
||||
- nuzlocke-tracker-0q8f
|
||||
- nuzlocke-tracker-hm6t
|
||||
- nuzlocke-tracker-8tuw
|
||||
- nuzlocke-tracker-8fcj
|
||||
---
|
||||
|
||||
Set up the initial project structure and choose the technology stack.
|
||||
|
||||
## Checklist
|
||||
- [x] Initialize the project (e.g., Vite + React/Vue/Svelte or Next.js)
|
||||
- [x] Set up TypeScript configuration
|
||||
- [x] Configure linting (ESLint) and formatting (Prettier)
|
||||
- [x] Set up basic folder structure (components, types, utils, data)
|
||||
- [x] Add Tailwind CSS or chosen styling solution
|
||||
- [x] Create basic app shell with routing
|
||||
|
||||
## Considerations
|
||||
- Should be a web app for accessibility
|
||||
- Consider PWA capabilities for offline use
|
||||
- Keep bundle size small for fast loading
|
||||
89
.beans/nuzlocke-tracker-25mh--genlocke-tracking.md
Normal file
89
.beans/nuzlocke-tracker-25mh--genlocke-tracking.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
# nuzlocke-tracker-25mh
|
||||
title: Genlocke tracking
|
||||
status: completed
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-08T12:17:19Z
|
||||
updated_at: 2026-02-09T11:07:51Z
|
||||
---
|
||||
|
||||
Track a **genlocke** — a series of linked nuzlocke runs, typically one per generation or region. The player picks one game per generation/region and surviving Pokemon carry over between legs.
|
||||
|
||||
## User Flow
|
||||
|
||||
### 1. Create Genlocke
|
||||
The user starts a new genlocke and gives it a name.
|
||||
|
||||
### 2. Select Games (Legs)
|
||||
The user picks which games to play, in order. The UI offers **preset templates** to speed this up, but the user can always customize:
|
||||
|
||||
- **True Genlocke** — One original game per generation (Red/Blue/Yellow → Gold/Silver/Crystal → Ruby/Sapphire/Emerald → ...). Uses the original releases only.
|
||||
- **Normal Genlocke** — Uses the latest remake or enhanced version for each region (FireRed/LeafGreen → HeartGold/SoulSilver → Emerald → Platinum → ...). This is the most common format.
|
||||
- **Custom** — The user picks any games in any order. No restrictions on which games or how many.
|
||||
|
||||
For the preset templates, the user still picks *which* game within each generation/region slot (e.g., FireRed vs LeafGreen for Gen 1). The template just determines which slots are shown. The user can add/remove/reorder legs after selecting a template.
|
||||
|
||||
Games are grouped by **region** (not release generation) for the purpose of presets, since that's how genlocke players think about it (e.g., FireRed is a "Kanto" leg, not a "Gen 3" leg).
|
||||
|
||||
### 3. Configure Rules
|
||||
Two categories of rules are configured:
|
||||
|
||||
**Per-game nuzlocke rules** — The standard nuzlocke ruleset (first encounter only, permadeath, duplicates clause, level caps, etc.). These are set once and apply uniformly to all legs. Uses the existing `NuzlockeRules` interface.
|
||||
|
||||
**Genlocke-specific rules** — Overarching rules that govern how legs connect:
|
||||
- **Keep HoF** (default) — Pokemon that enter the Hall of Fame at the end of a leg are transferred to the next leg as eggs (breed at level 1). This is the standard genlocke mechanic.
|
||||
- **Retire HoF** — Pokemon that enter the Hall of Fame are retired. They (and their evolutionary families) become unavailable in future legs (added to a cumulative dupe list). This is also known as the "Gauntlet" rule. Increases difficulty by forcing new Pokemon each leg.
|
||||
- Potentially more rules in the future (e.g., item carry-over restrictions, level scaling).
|
||||
|
||||
### 4. Sequential Run Progression
|
||||
- When the genlocke is created, the **first leg** is automatically started as a new nuzlocke run.
|
||||
- Each leg is a full nuzlocke run, tracked exactly like any standalone run (encounters, team, bosses, graveyard, etc.).
|
||||
- When a leg is marked as **completed** (Hall of Fame), the next leg is started. A transfer step happens between legs where the user selects which surviving Pokemon to carry forward.
|
||||
- When a leg is marked as **failed** (wipe), the genlocke itself is marked as failed (game over).
|
||||
- The final leg's completion marks the entire genlocke as completed.
|
||||
|
||||
### 5. Genlocke Overview Page
|
||||
A dedicated page showing:
|
||||
- **Progress** — Which leg is active, which are completed, which are upcoming. Visual timeline or step indicator.
|
||||
- **Configuration** — Selected games, rules, genlocke-specific rules.
|
||||
- **Cumulative Stats** — Total encounters, total deaths, total HoF entries across all legs.
|
||||
- **Lineage Tracking** — Show Pokemon that have carried over across multiple legs (their journey through the genlocke).
|
||||
- **Cumulative Graveyard** — All deaths across all legs in one view.
|
||||
|
||||
## Data Model
|
||||
|
||||
### New entities:
|
||||
- **`Genlocke`** — Top-level entity: name, status (active/completed/failed), genlocke rules (JSONB), created_at.
|
||||
- **`GenlockeLeg`** — Join table linking a Genlocke to a NuzlockeRun: genlocke_id, run_id, leg_order. Defines the sequence.
|
||||
|
||||
### Changes to existing entities:
|
||||
- **`NuzlockeRun`** — No schema changes needed. A run that's part of a genlocke is just a normal run that happens to be referenced by a GenlockeLeg. The genlocke-level rules are stored on the Genlocke, not duplicated per run.
|
||||
|
||||
### Transfer tracking:
|
||||
- **`GenlockeTransfer`** — Records which Pokemon were carried between legs: from_leg_id, to_leg_id, encounter_id (the source encounter from the completed leg), to_encounter_id (the egg/gift encounter created in the next leg).
|
||||
|
||||
## Child Features (suggested breakdown)
|
||||
1. **Genlocke creation wizard** — Multi-step UI: name → game selection (with presets) → rules → confirm
|
||||
2. **Genlocke overview page** — Dashboard with progress, stats, configuration
|
||||
3. **Leg progression** — Auto-start next leg when current completes, transfer step
|
||||
4. **Transfer UI** — Select surviving Pokemon to carry forward between legs
|
||||
5. **Lineage tracking** — Show a Pokemon's journey across legs
|
||||
6. **Cumulative graveyard** — Deaths across all legs in one view
|
||||
7. **Gauntlet/Retire HoF rule** — Enforce the "retire" mechanic with cumulative dupe list
|
||||
|
||||
## Success Criteria
|
||||
- [x] A user can create a new genlocke via a multi-step wizard (name, game selection with presets, rules)
|
||||
- [x] Games can be selected using True Genlocke, Normal Genlocke, or Custom presets, grouped by region
|
||||
- [x] Nuzlocke rules are configured once and applied uniformly to all legs
|
||||
- [x] Genlocke-specific rules (Keep HoF / Retire HoF) can be selected
|
||||
- [x] The first leg starts automatically upon genlocke creation
|
||||
- [x] Each leg is a full nuzlocke run, tracked identically to standalone runs
|
||||
- [x] Completing a leg triggers a transfer step where surviving Pokemon can be carried forward
|
||||
- [x] Failing a leg marks the entire genlocke as failed
|
||||
- [x] Completing the final leg marks the genlocke as completed
|
||||
- [x] A genlocke overview page shows progress, configuration, cumulative stats, lineage, and graveyard
|
||||
- [x] Transferred Pokemon appear as eggs (base form, level 1) in the next leg
|
||||
- [x] Pokemon lineage is trackable across multiple legs
|
||||
- [x] A cumulative graveyard shows all deaths across the entire genlocke
|
||||
- [x] The Retire HoF / Gauntlet rule correctly retires HoF Pokemon and adds their families to the dupe list
|
||||
19
.beans/nuzlocke-tracker-29oy--boss-seed-data-pipeline.md
Normal file
19
.beans/nuzlocke-tracker-29oy--boss-seed-data-pipeline.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
# nuzlocke-tracker-29oy
|
||||
title: Boss seed data pipeline
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T11:33:33Z
|
||||
updated_at: 2026-02-08T11:35:13Z
|
||||
---
|
||||
|
||||
Export boss data from admin, save as seed JSON files, and load them during seeding.
|
||||
|
||||
## Checklist
|
||||
- [x] Add unique constraint to boss_battles (version_group_id, order) + Alembic migration
|
||||
- [x] Add upsert_bosses to seed loader (loader.py)
|
||||
- [x] Add boss loading step to seed runner (run.py)
|
||||
- [x] Add boss count to verify() function
|
||||
- [x] Add export_bosses() function to run.py
|
||||
- [x] Add --export-bosses flag to __main__.py
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
# nuzlocke-tracker-2b4r
|
||||
title: Add route ordering for Gen 5+ games
|
||||
status: scrapped
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T08:58:55Z
|
||||
updated_at: 2026-02-11T13:54:47Z
|
||||
parent: nuzlocke-tracker-rzu4
|
||||
---
|
||||
|
||||
Add route progression ordering in `route_order.json` for all games that currently lack it. Routes should be ordered to match the typical in-game progression (main story first, post-game after).
|
||||
|
||||
## Games needing route ordering:
|
||||
- [ ] Diamond/Pearl (could alias to Platinum if progression is similar enough)
|
||||
- [ ] Black/White
|
||||
- [ ] Black 2/White 2
|
||||
- [ ] X/Y
|
||||
- [ ] Sun/Moon
|
||||
- [ ] Ultra Sun/Ultra Moon (could alias to Sun/Moon if similar enough)
|
||||
- [ ] Sword/Shield
|
||||
- [ ] Brilliant Diamond/Shining Pearl (could alias to Platinum/Diamond-Pearl)
|
||||
- [ ] Scarlet/Violet
|
||||
- [ ] Legends Arceus
|
||||
- [ ] Legends Z-A
|
||||
- [ ] Let's Go Pikachu/Eevee (currently aliased to firered-leafgreen — verify this is correct)
|
||||
|
||||
## Approach:
|
||||
- Reference Bulbapedia "walkthrough" or "appendix" pages for progression order
|
||||
- Consider aliasing games that share the same region and route progression
|
||||
- Mark a clear divider between main story and post-game routes where applicable
|
||||
- The format is an array of route name strings in `route_order.json`, keyed by version group slug
|
||||
|
||||
## Notes:
|
||||
- This is primarily manual work — play order guides are widely available online
|
||||
- Verify route names match exactly what's in the encounter data files (case-sensitive)
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# nuzlocke-tracker-338l
|
||||
title: Verify fetch_pokeapi.py rewrite
|
||||
status: scrapped
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-07T15:08:10Z
|
||||
updated_at: 2026-02-07T19:05:29Z
|
||||
---
|
||||
|
||||
All code changes are complete. Run verification:
|
||||
1. Run the script to completion
|
||||
2. Verify output (pokemon.json has forms, correct IDs, etc.)
|
||||
3. Verify cache speedup on second run
|
||||
4. Frontend build check
|
||||
|
||||
## Checklist
|
||||
- [ ] Run fetch_pokeapi.py to completion
|
||||
- [ ] Verify pokemon.json has more entries with forms (megas, gmax, regionals)
|
||||
- [ ] Verify pokeapi_id/national_dex split is correct
|
||||
- [ ] Verify route/encounter JSON files
|
||||
- [ ] Verify cache speedup on second run
|
||||
- [ ] Frontend build passes
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-36wg
|
||||
title: Make footer stick to bottom of viewport
|
||||
status: completed
|
||||
type: bug
|
||||
priority: normal
|
||||
created_at: 2026-02-13T07:47:48Z
|
||||
updated_at: 2026-02-13T12:59:22Z
|
||||
---
|
||||
|
||||
On pages with little content, the footer appears right after the content instead of staying at the bottom of the viewport. The footer should always be at the bottom of the browser window, pushing down when there's enough content but not floating in the middle of the page when content is short (sticky footer pattern).
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-37gk
|
||||
title: Curate route ordering to match game progression
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T12:25:05Z
|
||||
updated_at: 2026-02-07T12:27:11Z
|
||||
---
|
||||
|
||||
Implement ROUTE_ORDER in fetch_pokeapi.py for progression-based sorting, and add Export Order button to AdminGameDetail. See bean j28y for full plan.
|
||||
16
.beans/nuzlocke-tracker-3c9l--set-up-branching-structure.md
Normal file
16
.beans/nuzlocke-tracker-3c9l--set-up-branching-structure.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# nuzlocke-tracker-3c9l
|
||||
title: Set up branching structure
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:35Z
|
||||
updated_at: 2026-02-10T10:49:55Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
Create the `develop` branch from `main` and establish the `main`/`develop`/`feature/*` branching workflow.
|
||||
|
||||
- Create `develop` branch from current `main`
|
||||
- Push `develop` to remote
|
||||
- Set `develop` as the default working branch
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# nuzlocke-tracker-3el1
|
||||
title: Run progression dividers (main story / endgame)
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T13:40:14Z
|
||||
updated_at: 2026-02-08T20:25:59Z
|
||||
---
|
||||
|
||||
Add support for dividing a run's boss battle progression into sections like "Main Story" and "Endgame" (e.g., post-Elite Four content). This helps players visually distinguish where the main campaign ends and optional/endgame content begins.
|
||||
|
||||
## Context
|
||||
|
||||
Currently boss battles are displayed as a flat ordered list. In many Pokemon games there's a clear distinction between the main story (up through the Champion) and endgame content (rematches, Battle Frontier, Kanto in GSC/HGSS, etc.). A visual divider would make it easier to track progress through each phase.
|
||||
|
||||
## Scope
|
||||
|
||||
- **Admin side**: Allow marking boss battles or defining breakpoints that separate progression phases (e.g., "everything after this boss is endgame")
|
||||
- **Run side**: Render a visual divider/section header between main story and endgame boss battles
|
||||
- Should support at minimum two sections (main story, endgame), but consider whether the design should be flexible enough for arbitrary sections (e.g., "Kanto" in HGSS)
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Decide on data model approach (e.g., a `section` field on boss battles, or a separate progression divider entity tied to the version group)
|
||||
- [ ] Add backend models and migrations
|
||||
- [ ] Add API support for managing sections/dividers
|
||||
- [ ] Update admin UI to allow assigning bosses to sections or inserting dividers
|
||||
- [ ] Update run-side boss progression display to render section headers/dividers
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
# nuzlocke-tracker-3lfw
|
||||
title: Configure Nginx Proxy Manager for nuzlocke-tracker
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:50Z
|
||||
updated_at: 2026-02-10T08:44:18Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
blocking:
|
||||
- nuzlocke-tracker-vpn5
|
||||
---
|
||||
|
||||
Add a proxy host entry in Nginx Proxy Manager on Unraid to route LAN traffic to the app.
|
||||
|
||||
- Add a proxy host (e.g., `nuzlocke.local`) pointing to the frontend/API containers
|
||||
- Configure appropriate ports and forwarding rules
|
||||
- Test access from other devices on the LAN
|
||||
17
.beans/nuzlocke-tracker-48ds--database-backup-strategy.md
Normal file
17
.beans/nuzlocke-tracker-48ds--database-backup-strategy.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# nuzlocke-tracker-48ds
|
||||
title: Database backup strategy
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:55Z
|
||||
updated_at: 2026-02-10T10:55:15Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
Set up a simple scheduled backup for the production PostgreSQL database.
|
||||
|
||||
- Create a backup script using `pg_dump` that runs inside or against the PostgreSQL container
|
||||
- Set up a cron job on Unraid to run the backup on a schedule (e.g., daily)
|
||||
- Store backups in a designated location on Unraid with rotation (keep last N backups)
|
||||
- Document the restore procedure
|
||||
30
.beans/nuzlocke-tracker-4c31--backend-setup-framework.md
Normal file
30
.beans/nuzlocke-tracker-4c31--backend-setup-framework.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-4c31
|
||||
title: Backend Setup & Framework
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:46:49Z
|
||||
updated_at: 2026-02-04T16:10:13Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
blocking:
|
||||
- nuzlocke-tracker-l7e3
|
||||
- nuzlocke-tracker-bkhs
|
||||
---
|
||||
|
||||
Set up the backend API project with chosen framework and structure.
|
||||
|
||||
## Checklist
|
||||
- [x] Choose backend framework (Node.js/Express, Fastify, NestJS, Go, Python/FastAPI, etc.) - **Python/FastAPI**
|
||||
- [x] Initialize backend project
|
||||
- [x] Set up TypeScript (if applicable) - N/A (Python with type hints via Pydantic)
|
||||
- [x] Configure linting and formatting - **ruff**
|
||||
- [x] Set up project structure (routes, controllers, services, models)
|
||||
- [x] Add environment configuration (.env handling) - **pydantic-settings**
|
||||
- [x] Set up development server with hot reload - **uvicorn --reload**
|
||||
- [x] Add basic health check endpoint - `/health` and `/`
|
||||
|
||||
## Considerations
|
||||
- Should match team's expertise
|
||||
- Consider ease of deployment
|
||||
- TypeScript preferred for type safety with frontend
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
# nuzlocke-tracker-4ph2
|
||||
title: Fix and complete route ordering for all games
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T13:55:09Z
|
||||
updated_at: 2026-02-11T14:21:24Z
|
||||
parent: nuzlocke-tracker-rzu4
|
||||
---
|
||||
|
||||
Audit existing route ordering and add missing ordering for all games in `route_order.json`. Use Bulbapedia walkthrough/appendix pages as the primary reference for game progression order.
|
||||
|
||||
## Approach:
|
||||
- Reference Bulbapedia walkthrough pages (e.g. `Appendix:FireRed_and_LeafGreen_walkthrough`) to determine correct progression order
|
||||
- Cross-reference route names from walkthroughs against actual route names in encounter data files
|
||||
- Consider building a script to semi-automate this (scrape walkthrough pages → match against encounter data → generate ordering)
|
||||
|
||||
## Games to fix (existing but incorrect):
|
||||
- [x] Platinum — fixed ordering to start with Twinleaf Town, matched names to encounter data
|
||||
|
||||
## Games to add ordering for:
|
||||
- [x] Diamond/Pearl (separate ordering, slight differences from Platinum)
|
||||
- [x] Black/White
|
||||
- [x] Black 2/White 2
|
||||
- [x] X/Y
|
||||
- [x] Sun/Moon
|
||||
- [x] Ultra Sun/Ultra Moon (separate ordering, has additional areas)
|
||||
- [x] Sword/Shield
|
||||
- [x] Brilliant Diamond/Shining Pearl (separate ordering with Grand Underground)
|
||||
- [x] Scarlet/Violet
|
||||
- [x] Legends Arceus
|
||||
- [x] Legends Z-A
|
||||
|
||||
## Games to audit (existing, likely correct):
|
||||
- [x] FireRed/LeafGreen (and aliases: Red/Blue, Yellow, Let's Go) — rewritten with correct encounter data names
|
||||
- [x] HeartGold/SoulSilver (and aliases: Gold/Silver, Crystal) — rewritten with correct encounter data names
|
||||
- [x] Emerald (and aliases: Ruby/Sapphire, ORAS) — rewritten with correct encounter data names
|
||||
|
||||
## Notes:
|
||||
- Route names must match exactly what's in the encounter data files (case-sensitive)
|
||||
- "Starter" should be the first entry for each game
|
||||
- Post-game areas placed after main story areas
|
||||
- Replaces beans nuzlocke-tracker-6lud and nuzlocke-tracker-2b4r
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# nuzlocke-tracker-55kp
|
||||
title: Docker Development Environment Setup
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T16:07:25Z
|
||||
updated_at: 2026-02-04T16:13:04Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Set up Docker and docker-compose for local development environment.
|
||||
|
||||
## Checklist
|
||||
- [x] Create Dockerfile for backend API
|
||||
- [x] Create Dockerfile for frontend (if needed)
|
||||
- [x] Create docker-compose.yml with services (api, db, frontend)
|
||||
- [x] Add PostgreSQL service configuration
|
||||
- [x] Configure volume mounts for hot reload
|
||||
- [x] Add environment variable handling
|
||||
- [x] Create .dockerignore files
|
||||
- [x] Document usage in README
|
||||
|
||||
## Notes
|
||||
- Should support hot reload for development
|
||||
- Database data should persist between restarts
|
||||
31
.beans/nuzlocke-tracker-5bez--non-evolution-form-changes.md
Normal file
31
.beans/nuzlocke-tracker-5bez--non-evolution-form-changes.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
# nuzlocke-tracker-5bez
|
||||
title: Non-evolution form changes
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T13:40:00Z
|
||||
updated_at: 2026-02-08T11:57:36Z
|
||||
---
|
||||
|
||||
Some Pokemon can change form without evolving, using items or abilities. These form changes affect types, stats, and appearance but are not part of the evolution chain.
|
||||
|
||||
## Examples
|
||||
|
||||
- **Oricorio**: Changes form (Baile/Pom-Pom/Pa'u/Sensu) by using nectar items from different islands. Each form has a different type (Fire, Electric, Psychic, Ghost + Flying).
|
||||
- **Darmanitan**: Has a Zen Mode ability that changes it to Darmanitan (Zen) in battle (Fire/Psychic). Galarian Darmanitan Zen Mode is Ice/Fire.
|
||||
- **Rotom**: Changes form by interacting with appliances (Heat/Wash/Frost/Fan/Mow), each with different secondary types.
|
||||
- **Shaymin**: Changes between Land and Sky forme using the Gracidea flower.
|
||||
- **Tornadus/Thundurus/Landorus**: Incarnate vs Therian forms via the Reveal Glass.
|
||||
- **Hoopa**: Confined vs Unbound via the Prison Bottle.
|
||||
|
||||
## Scope
|
||||
|
||||
This is lower priority than basic form support (bean f44d) and submodule update (bean 6aje). It matters for tracking because a player might catch an Oricorio in one form and change it to another — the tracker should reflect the current form's types.
|
||||
|
||||
## Design considerations
|
||||
|
||||
- Should the tracker allow manually changing a caught Pokemon's form?
|
||||
- Or should it just track the form as encountered and leave it static?
|
||||
- How to represent form-change items/methods in the data model?
|
||||
- This may not need seed data support — could be a manual UI action on a caught Pokemon
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# nuzlocke-tracker-5o1v
|
||||
title: Improve encounter method input in route encounter form
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T19:06:10Z
|
||||
updated_at: 2026-02-08T19:17:14Z
|
||||
parent: nuzlocke-tracker-iu5b
|
||||
---
|
||||
|
||||
Replace the free-text encounter method input in the route encounter form (RouteEncounterFormModal) with a smarter selector that leverages the known encounter methods already defined in the codebase.
|
||||
|
||||
## Current behavior
|
||||
- The encounter method field in RouteEncounterFormModal is a plain `<input type="text">` with a placeholder "e.g. Walking, Surfing, Fishing"
|
||||
- Easy to introduce typos or inconsistent naming (e.g. "walking" vs "walk" vs "Grass")
|
||||
- The app already has a well-defined set of encounter methods in `EncounterMethodBadge.tsx` with METHOD_CONFIG and METHOD_ORDER (starter, gift, fossil, trade, walk, headbutt, surf, rock-smash, old-rod, good-rod, super-rod)
|
||||
- The backend stores this as a `String(30)` column, so it's not strictly enum-constrained
|
||||
|
||||
## Desired behavior
|
||||
- Replace the free-text input with a dropdown/select that lists the known encounter methods from METHOD_ORDER, using the human-readable labels from getMethodLabel()
|
||||
- Include an "Other" option that reveals a text input for custom methods not in the predefined list
|
||||
- When editing an existing encounter, pre-select the correct method
|
||||
- Consider showing the colored badge preview next to each option for visual consistency with how methods appear elsewhere in the app
|
||||
|
||||
## Files
|
||||
- `frontend/src/components/admin/RouteEncounterFormModal.tsx` — replace the text input with new selector
|
||||
- `frontend/src/components/EncounterMethodBadge.tsx` — export METHOD_CONFIG or add a helper to get the list of known methods
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
# nuzlocke-tracker-5tac
|
||||
title: Enable naming generator for Genlockes
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T21:14:21Z
|
||||
updated_at: 2026-02-14T08:52:16Z
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Genlockes are multiple nuzlocke runs played back-to-back. Currently, naming scheme selection is only available per-run, meaning genlocke runs don't get naming schemes at all (they're created automatically during genlocke creation and leg advancement). This task adds genlocke-level naming scheme selection and lineage-aware name suggestions.
|
||||
|
||||
## Key Behaviors
|
||||
|
||||
### 1. Genlocke-Level Naming Scheme
|
||||
- When creating a genlocke, the user selects a naming scheme (same categories as standalone runs)
|
||||
- This scheme is stored on the `Genlocke` model and automatically applied to every leg's `NuzlockeRun`
|
||||
- Both the initial run (created in `create_genlocke`) and subsequent runs (created in `advance_leg`) inherit the genlocke's naming scheme
|
||||
|
||||
### 2. Name Suggestions (Current Leg Only)
|
||||
- Duplicate name checking stays scoped to the current run (already the case)
|
||||
- Transferred pokemon carry their nicknames forward, so they naturally occupy names in the current run's used-name set
|
||||
|
||||
### 3. Lineage-Aware Name Suggestions (Roman Numerals)
|
||||
- When catching a pokemon in a genlocke leg (leg 2+), the system checks if any pokemon from the same **evolution family** was caught in a previous leg
|
||||
- If so, the original nickname is suggested with a roman numeral suffix (e.g., "Heracles II", "Heracles III")
|
||||
- The numeral represents the Nth distinct leg where this evolution family was originally caught (not transferred)
|
||||
- Leg 1: Magikarp → "Heracles" (no numeral, first appearance)
|
||||
- Leg 2: Magikarp or Gyarados caught → suggest "Heracles II"
|
||||
- Leg 3: Magikarp caught again → suggest "Heracles III"
|
||||
- Transferred pokemon don't count as new appearances (they're the same individual)
|
||||
- The "base name" is taken from the first original encounter of that family across all legs
|
||||
- The lineage suggestion appears as a **priority suggestion** alongside regular naming scheme suggestions
|
||||
- The user can always choose a different name
|
||||
|
||||
### 4. How the API Changes
|
||||
- `GET /runs/{run_id}/name-suggestions` gains an optional `pokemon_id` query param
|
||||
- When `pokemon_id` is provided AND the run belongs to a genlocke:
|
||||
- Determine the pokemon's evolution family
|
||||
- Query previous legs' encounters (excluding transfer-target encounters) for matching family members
|
||||
- If matches found: compute the roman numeral and prepend "{base_name} {numeral}" to the suggestions list
|
||||
- Regular naming scheme suggestions are returned as before
|
||||
|
||||
## Checklist
|
||||
|
||||
### Backend
|
||||
- [x] Add `naming_scheme` column to `genlockes` table (Alembic migration)
|
||||
- [x] Update `Genlocke` model with `naming_scheme: Mapped[str | None]`
|
||||
- [x] Update `GenlockeCreate` schema to accept optional `naming_scheme: str | None`
|
||||
- [x] Update `GenlockeResponse` and `GenlockeDetailResponse` to include `naming_scheme`
|
||||
- [x] Update `create_genlocke` endpoint: pass `naming_scheme` to the first leg's `NuzlockeRun`
|
||||
- [x] Update `advance_leg` endpoint: pass the genlocke's `naming_scheme` to the new leg's `NuzlockeRun`
|
||||
- [x] Add roman numeral helper function (e.g., in `services/naming.py`)
|
||||
- [x] Update `get_name_suggestions` endpoint to accept optional `pokemon_id` param
|
||||
- [x] Implement lineage lookup: when in genlocke context with `pokemon_id`, query prior legs for evolution family matches (excluding transfers) and compute suggestion with roman numeral
|
||||
- [ ] Add tests for lineage-aware name suggestions
|
||||
|
||||
### Frontend
|
||||
- [x] Update `CreateGenlockeInput` type to include `namingScheme?: string | null`
|
||||
- [x] Add naming scheme selector to genlocke creation wizard (in the Rules step or as a new step)
|
||||
- [x] Update `GenlockeResponse` / `GenlockeDetailResponse` types to include `namingScheme`
|
||||
- [x] Update `EncounterModal` to pass selected `pokemonId` to name suggestions API when in genlocke context
|
||||
- [x] Update `getNameSuggestions` API client to accept optional `pokemonId` param
|
||||
- [x] Display lineage suggestion prominently in the suggestions UI (e.g., first pill with distinct styling)
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-5uoz
|
||||
title: Fix webp sprites not loading in production nginx
|
||||
status: completed
|
||||
type: bug
|
||||
priority: normal
|
||||
created_at: 2026-02-11T12:21:29Z
|
||||
updated_at: 2026-02-11T12:24:02Z
|
||||
---
|
||||
|
||||
Sprites (.webp) don't load in prod while .png images work fine. The files are in the container but nginx/proxy isn't serving them correctly. Fix by adding explicit webp MIME type to nginx config.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-5wsn
|
||||
title: Add run management to admin panel
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T09:53:01Z
|
||||
updated_at: 2026-02-08T09:53:25Z
|
||||
---
|
||||
|
||||
Create AdminRuns page with table listing all runs (name, game, status, started date) with delete functionality. Wire it into routing and admin navigation.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# nuzlocke-tracker-66hg
|
||||
title: Auto-select boss team variant based on starter choice
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T20:21:40Z
|
||||
updated_at: 2026-02-08T20:34:35Z
|
||||
---
|
||||
|
||||
When a run's starter Pokemon is known, automatically match it against boss battle condition labels (e.g., "Chose Bulbasaur") and pre-select the matching variant instead of showing the pill selector.
|
||||
|
||||
## Context
|
||||
|
||||
Currently, bosses with variant teams (condition_label) display a pill selector on the run page (BossDefeatModal and RunEncounters BossTeamPreview) so the user can manually toggle between team variants. However, if the run's starter choice is known, the correct variant can be inferred automatically.
|
||||
|
||||
## Behavior
|
||||
|
||||
- If the run has a starter Pokemon recorded, check each variant's condition label for a match (e.g., starter name "Bulbasaur" matches condition label "Chose Bulbasaur")
|
||||
- If exactly one condition label matches, auto-select that variant and hide the pill selector entirely
|
||||
- If no match is found (or the run has no starter), fall back to showing the pill selector as today
|
||||
- Matching should be case-insensitive and check if the starter name appears anywhere in the condition label (substring match)
|
||||
|
||||
## Affected Components
|
||||
|
||||
- `BossDefeatModal` — auto-select variant, hide pills when matched
|
||||
- `BossTeamPreview` in `RunEncounters` — same logic
|
||||
- May need to check how/where the run's starter Pokemon is stored and accessible
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] Determine how the starter Pokemon is stored/accessible from the run data
|
||||
- [x] Add matching logic to find the right variant from condition labels
|
||||
- [x] Update BossDefeatModal to auto-select and hide pills when starter matches
|
||||
- [x] Update BossTeamPreview in RunEncounters with same logic
|
||||
- [ ] Test with variant bosses where starter matches a condition
|
||||
- [ ] Test fallback behavior when no starter is set or no match found
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-6aje
|
||||
title: Update PokeAPI data submodule to latest version
|
||||
status: completed
|
||||
type: task
|
||||
priority: high
|
||||
created_at: 2026-02-06T10:53:45Z
|
||||
updated_at: 2026-02-07T14:35:41Z
|
||||
---
|
||||
|
||||
The local PokeAPI data repository we use as a submodule is outdated. It's missing data for newer Pokemon forms and potentially newer games.
|
||||
|
||||
## Why this is important now
|
||||
|
||||
After adding form support to seeding (bean f44d), we discovered that the submodule is missing many form entries. Currently only 16 forms are included — all from Gen 7 (Alolan + Oricorio/Lycanroc). Missing forms include:
|
||||
|
||||
- **Galarian forms** (Gen 8): Galarian Meowth, Ponyta, Rapidash, Slowpoke, Farfetch'd, Weezing, Mr. Mime, Corsola, Zigzagoon, Linoone, Darumaka, Darmanitan, Stunfisk, Yamask
|
||||
- **Hisuian forms** (Gen 8/Legends Arceus): Hisuian Growlithe, Voltorb, Typhlosion, Samurott, Decidueye, Zorua, Zoroark, Braviary, Goodra, Avalugg, Sneasel, Lilligant, Qwilfish, Sliggoo
|
||||
- **Paldean forms** (Gen 9): Paldean Wooper, Tauros
|
||||
- **Other missing forms**: Basculin (White-Striped), regional bird variants, etc.
|
||||
|
||||
These forms have different types and stats from their base species and appear in encounter data for their respective games. Without them in the submodule, the seeding script can't create Pokemon records for them.
|
||||
|
||||
## Action
|
||||
|
||||
- Check for updates to the PokeAPI data repository
|
||||
- Update the submodule to the latest version
|
||||
- Re-run fetch_pokeapi.py to regenerate seed data
|
||||
- Add any new games to VERSION_GROUPS in fetch_pokeapi.py
|
||||
- Verify that form count increases significantly after update
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-6kux
|
||||
title: 'Admin Panel: Tabs for Routes/Bosses + Boss Export'
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T10:49:47Z
|
||||
updated_at: 2026-02-08T10:51:25Z
|
||||
---
|
||||
|
||||
Add tabbed UI to AdminGameDetail (Routes/Bosses tabs) and boss battle export endpoint
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
# nuzlocke-tracker-6lud
|
||||
title: Audit and fix route ordering for Gen 1-4 games
|
||||
status: scrapped
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T08:59:16Z
|
||||
updated_at: 2026-02-11T13:54:47Z
|
||||
parent: nuzlocke-tracker-rzu4
|
||||
---
|
||||
|
||||
Review the existing route ordering for Gen 1-4 games that already have ordering defined. The current ordering may not accurately reflect typical game progression.
|
||||
|
||||
## Games to audit:
|
||||
- [ ] FireRed/LeafGreen (and aliased: Red/Blue, Yellow, Let's Go)
|
||||
- [ ] HeartGold/SoulSilver (and aliased: Gold/Silver, Crystal)
|
||||
- [ ] Emerald (and aliased: Ruby/Sapphire, Omega Ruby/Alpha Sapphire)
|
||||
- [ ] Platinum
|
||||
|
||||
## What to check:
|
||||
- Routes are in correct progression order (match typical walkthrough)
|
||||
- No routes are missing from the ordering
|
||||
- No routes are listed that don't exist in the encounter data
|
||||
- Aliases make sense (e.g. Red/Blue may have slightly different progression from FR/LG)
|
||||
- Post-game areas are placed after main story areas
|
||||
- Sub-areas (children) inherit parent ordering correctly
|
||||
|
||||
## Notes:
|
||||
- Cross-reference with Bulbapedia walkthrough pages
|
||||
- The Platinum ordering currently starts with cities and mines rather than the starting town/routes — this may be incorrect
|
||||
- Diamond/Pearl currently aliases to nothing — check if it should alias to Platinum or needs its own ordering
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
# nuzlocke-tracker-6r4z
|
||||
title: 'Admin table improvements: Routes and Bosses'
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-13T13:01:55Z
|
||||
updated_at: 2026-02-13T13:06:08Z
|
||||
---
|
||||
|
||||
1. Routes table: add column for 'pinwheel close' and a column for quicklink to encounters
|
||||
2. Bosses table: add column for Position after route column, ideally as an inline dropdown for mass editing
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-704x
|
||||
title: Run progression dividers (main story / endgame)
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T13:46:12Z
|
||||
updated_at: 2026-02-08T13:48:28Z
|
||||
---
|
||||
|
||||
Add section field to boss battles to enable visual dividers between game progression phases (Main Story, Endgame, etc.) in both admin and run views.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# nuzlocke-tracker-765i
|
||||
title: Update CLAUDE.md with branching rules
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:38Z
|
||||
updated_at: 2026-02-10T10:49:56Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
blocking:
|
||||
- nuzlocke-tracker-3c9l
|
||||
---
|
||||
|
||||
Once the branching structure is in place, add instructions to CLAUDE.md enforcing the branching strategy:
|
||||
|
||||
- Never commit directly to `main`
|
||||
- Day-to-day work happens on `develop`
|
||||
- New work is done on `feature/*` branches off `develop`
|
||||
- Merge flow: `feature/*` → `develop` → `main`
|
||||
- `main` is always production-ready
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
# nuzlocke-tracker-7jba
|
||||
title: Review and complete special encounters for all games
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T08:59:24Z
|
||||
updated_at: 2026-02-11T13:52:06Z
|
||||
parent: nuzlocke-tracker-rzu4
|
||||
---
|
||||
|
||||
Only starters were missing from the encounter data. Gifts, trades, and fossils are already present in the per-game encounter JSON files.
|
||||
|
||||
The `special_encounters.json` file previously contained starters, gifts, and fossils for Gen 1-3 — but only the starters were actually needed (the rest was redundant). Additionally, starters were missing for Gen 4+ games. Yellow and Let's Go were incorrectly aliased to firered-leafgreen (wrong starters).
|
||||
|
||||
## Checklist:
|
||||
- [x] Remove non-starter entries from special_encounters.json
|
||||
- [x] Add Yellow starter (Pikachu) — was incorrectly aliased to firered-leafgreen
|
||||
- [x] Add Let's Go starters (Pikachu, Eevee) — was incorrectly aliased to firered-leafgreen
|
||||
- [x] Add Gen 4 starters (Diamond/Pearl/Platinum/BD/SP)
|
||||
- [x] Add Gen 5 starters (Black/White/B2/W2)
|
||||
- [x] Add Gen 6 starters (X/Y)
|
||||
- [x] Add Gen 7 starters (Sun/Moon/USUM)
|
||||
- [x] Add Gen 8 starters (Sword/Shield)
|
||||
- [x] Add Gen 9 starters (Scarlet/Violet)
|
||||
- [x] Add Legends Arceus starters
|
||||
- [x] Add Legends Z-A starters
|
||||
37
.beans/nuzlocke-tracker-8fcj--local-storage-persistence.md
Normal file
37
.beans/nuzlocke-tracker-8fcj--local-storage-persistence.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# nuzlocke-tracker-8fcj
|
||||
title: Frontend API Integration
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:44:42Z
|
||||
updated_at: 2026-02-05T13:55:52Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
blocking:
|
||||
- nuzlocke-tracker-uw2j
|
||||
- nuzlocke-tracker-0q8f
|
||||
- nuzlocke-tracker-hm6t
|
||||
- nuzlocke-tracker-8tuw
|
||||
---
|
||||
|
||||
Implement frontend services to communicate with the backend API.
|
||||
|
||||
## Checklist
|
||||
- [x] Create API client/service layer
|
||||
- [x] Implement API calls for:
|
||||
- [x] Fetch available games
|
||||
- [x] Fetch routes for a game
|
||||
- [x] Fetch Pokémon data
|
||||
- [x] Create/update/delete Nuzlocke runs
|
||||
- [x] Create/update encounters
|
||||
- [x] Update Pokémon status
|
||||
- [x] Add loading states and error handling
|
||||
- [x] Add retry logic for failed requests
|
||||
|
||||
## Technical Notes
|
||||
- Using native `fetch` via `src/api/client.ts` wrapper
|
||||
- Using TanStack Query for caching, loading states, and retry
|
||||
- All API responses typed with TypeScript
|
||||
- Vite dev proxy configured for `/api` → backend
|
||||
- Query hooks in `src/hooks/` for each domain (games, pokemon, runs, encounters)
|
||||
- Mutations auto-invalidate relevant query caches
|
||||
28
.beans/nuzlocke-tracker-8tuw--run-dashboardoverview.md
Normal file
28
.beans/nuzlocke-tracker-8tuw--run-dashboardoverview.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# nuzlocke-tracker-8tuw
|
||||
title: Run Dashboard/Overview
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:44:38Z
|
||||
updated_at: 2026-02-05T14:16:36Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Create the main dashboard showing the current state of the Nuzlocke run.
|
||||
|
||||
## Checklist
|
||||
- [x] Show run statistics:
|
||||
- [x] Total encounters (caught/failed/skipped)
|
||||
- [x] Total deaths
|
||||
- [x] Routes completed
|
||||
- [x] Quick navigation to:
|
||||
- [x] Route list / encounter tracking
|
||||
- [x] Graveyard (fallen Pokémon)
|
||||
- [x] Show active rules as badges/icons
|
||||
- [x] Display game name and run start date
|
||||
|
||||
## UX Considerations
|
||||
- This is the home screen users return to most
|
||||
- Keep it clean and informative at a glance
|
||||
- Easy access to add new encounters
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# nuzlocke-tracker-8w9s
|
||||
title: Gauntlet rule option for genlockes
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T19:15:43Z
|
||||
updated_at: 2026-02-09T09:05:12Z
|
||||
parent: nuzlocke-tracker-25mh
|
||||
---
|
||||
|
||||
Add the **Retire HoF** (aka Gauntlet) rule as a genlocke-specific rule option. When enabled, Pokemon that enter the Hall of Fame at the end of a leg are NOT transferred to the next game — instead, they and their entire evolutionary families are added to a cumulative dupe list for all subsequent legs.
|
||||
|
||||
## Behavior
|
||||
- Toggled as a genlocke-specific rule during genlocke creation (step 3 of the wizard)
|
||||
- Mutually exclusive with "Keep HoF" — you pick one or the other
|
||||
- When a leg is completed:
|
||||
- Surviving HoF Pokemon are marked as "retired" rather than being available for transfer
|
||||
- Their evolutionary families (full chain: e.g., Charmander/Charmeleon/Charizard) are added to a cumulative dupe list
|
||||
- In subsequent legs, the duplicates clause treats these families as already caught/dead
|
||||
- The cumulative dupe list grows with each completed leg, making later legs increasingly restrictive
|
||||
- The genlocke overview page should display the cumulative retired/duped families
|
||||
|
||||
## Dependencies
|
||||
- Requires the genlocke creation wizard (to set the rule)
|
||||
- Requires the leg progression system (to trigger retirement on leg completion)
|
||||
- Should integrate with the existing duplicates clause enforcement in the encounter system
|
||||
|
||||
## Notes
|
||||
- This is a popular variant that increases difficulty by forcing entirely new Pokemon each generation
|
||||
- The dupe list should be visible somewhere in the genlocke dashboard so the player knows which families are off-limits
|
||||
|
||||
## Checklist
|
||||
- [x] Add a `retireHoF` boolean (or equivalent) to the genlocke rules JSONB schema
|
||||
- [x] On leg completion with Retire HoF enabled: resolve the full evolutionary families of all surviving HoF Pokemon
|
||||
- [x] Store the cumulative retired families list (could be a JSONB field on the Genlocke, or derived from completed legs)
|
||||
- [x] Implement `GET /api/v1/genlockes/{id}/retired-families` — return the list of retired evolutionary families with which leg they were retired in
|
||||
- [x] Integrate with the encounter system's duplicates clause: when logging an encounter in a genlocke leg, check the cumulative retired list and flag duplicates
|
||||
- [ ] Build a "Retired Families" display on the genlocke overview page showing all off-limits Pokemon with their sprites
|
||||
- [x] Ensure the creation wizard's genlocke rules step correctly toggles between Keep HoF and Retire HoF
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# nuzlocke-tracker-94hx
|
||||
title: Add sort options to run team overview
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-09T10:03:49Z
|
||||
updated_at: 2026-02-09T11:09:33Z
|
||||
---
|
||||
|
||||
The Active Team / Final Team section on the run dashboard (`RunDashboard.tsx`) currently displays Pokemon in whatever order encounters arrive from the backend — there is no explicit sorting. Add a sort dropdown so the user can choose how their team is ordered.
|
||||
|
||||
## Sort options
|
||||
- **Route order** (default) — sort by the route's `order` field, matching game progression
|
||||
- **Catch level** — sort by `catchLevel`, ascending
|
||||
- **Species name** — sort alphabetically by the display Pokemon's name (accounting for evolutions via `currentPokemon`)
|
||||
- **National Dex** — sort by the display Pokemon's `nationalDex` number
|
||||
|
||||
## Scope
|
||||
- Frontend-only change — all data is already available in the `EncounterDetail` objects
|
||||
- Add a small sort control (dropdown or segmented buttons) above the team grid
|
||||
- Persist the selected sort in component state (no need for localStorage)
|
||||
- Apply the same sort options to both the Active Team and Graveyard sections
|
||||
|
||||
## Checklist
|
||||
- [x] Add sort state and sort logic to `RunDashboard.tsx`
|
||||
- [x] Add sort dropdown/control above the team grid
|
||||
- [x] Apply sorting to both `alive` and `dead` encounter arrays
|
||||
- [x] Verify sort works correctly with evolved Pokemon (use `currentPokemon ?? pokemon` for name/dex)
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-94v0
|
||||
title: Handle Pokemon Forms properly
|
||||
status: scrapped
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-05T17:47:30Z
|
||||
updated_at: 2026-02-07T13:21:32Z
|
||||
---
|
||||
|
||||
Some pokemon have different forms, either regional forms or based on other criteria. They behave differently, are different encounters and might have different evolutions. This needs to be handled.
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-9c66
|
||||
title: Integration tests for Genlockes & Bosses API
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:26Z
|
||||
updated_at: 2026-02-10T09:33:26Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write integration tests for the genlocke challenge and boss battle API endpoints.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test genlocke CRUD operations (create, list, get, update, delete)
|
||||
- [ ] Test leg management (add/remove legs to a genlocke)
|
||||
- [ ] Test Pokemon transfers between genlocke legs
|
||||
- [ ] Test boss battle CRUD (create, list, update, delete per game)
|
||||
- [ ] Test boss battle results per run (record win/loss)
|
||||
- [ ] Test stats endpoint for run statistics
|
||||
- [ ] Test export endpoint
|
||||
- [ ] Test error cases (invalid transfers, boss results for wrong game, etc.)
|
||||
|
||||
## Notes
|
||||
|
||||
- Genlocke endpoints: `backend/src/app/api/genlockes.py`
|
||||
- Boss endpoints: `backend/src/app/api/bosses.py`
|
||||
- Stats endpoints: `backend/src/app/api/stats.py`
|
||||
- Export endpoints: `backend/src/app/api/export.py`
|
||||
- Genlocke tests require multiple runs as fixtures
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# nuzlocke-tracker-9c8d
|
||||
title: Rebrand to Another Nuzlocke Tracker (ANT)
|
||||
status: todo
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T14:46:09Z
|
||||
updated_at: 2026-02-10T14:46:56Z
|
||||
---
|
||||
|
||||
Adopt the new branding: **Another Nuzlocke Tracker**, abbreviated **ANT**.
|
||||
|
||||
## Context
|
||||
|
||||
- No existing Nuzlocke tracker uses this name or acronym.
|
||||
- The name is self-deprecating/playful ("yet another...") and the acronym opens up mascot/logo possibilities (ant character).
|
||||
- **Durant** (Steel/Bug, Gen V) is the mascot Pokémon — an actual ant Pokémon that ties the ANT acronym directly into the Pokémon universe.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Update project name in package.json / config files
|
||||
- [ ] Update page titles, meta tags, and any visible app name references
|
||||
- [ ] Update README and any documentation with the new name
|
||||
- [ ] Design or source a Durant-themed logo/icon
|
||||
- [ ] Update favicon and app icons
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# nuzlocke-tracker-9cx2
|
||||
title: Drag-and-drop reordering for boss battles
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T12:33:18Z
|
||||
updated_at: 2026-02-08T13:11:50Z
|
||||
parent: nuzlocke-tracker-iu5b
|
||||
---
|
||||
|
||||
Add drag-and-drop reordering for boss battles, matching the existing pattern used for routes.
|
||||
|
||||
## Current behavior
|
||||
- Boss battles have a manual 'order' field that must be edited individually
|
||||
- Routes already have drag-and-drop reordering via @dnd-kit
|
||||
|
||||
## Desired behavior
|
||||
- Boss battles in the AdminGameDetail bosses tab support drag-and-drop reordering
|
||||
- Same visual pattern as routes: drag handle on the left, auto-recalculate order on drop
|
||||
- Reuse the same @dnd-kit setup already in place for routes
|
||||
|
||||
## Files
|
||||
- frontend/src/pages/admin/AdminGameDetail.tsx — add DnD to bosses tab
|
||||
- Backend may need a reorder endpoint for bosses (similar to routes reorder)
|
||||
67
.beans/nuzlocke-tracker-9ngw--stats-screen.md
Normal file
67
.beans/nuzlocke-tracker-9ngw--stats-screen.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
# nuzlocke-tracker-9ngw
|
||||
title: Stats Screen
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T19:19:40Z
|
||||
updated_at: 2026-02-07T19:45:55Z
|
||||
---
|
||||
|
||||
A dedicated stats page aggregating data across all runs. Accessible from the main navigation.
|
||||
|
||||
## Sections
|
||||
|
||||
### 1. Run Overview
|
||||
- Total runs, active runs, completed runs, failed runs
|
||||
- Win rate (completed / (completed + failed), excluding active)
|
||||
- Average run duration (started_at → completed_at for finished runs)
|
||||
- Pie or bar chart: runs by game (using game.name / game.color)
|
||||
- Pie or bar chart: runs by region (game.region)
|
||||
- Pie or bar chart: runs by generation (game.generation)
|
||||
|
||||
### 2. Encounter Stats
|
||||
- Total encounters across all runs
|
||||
- Breakdown by status: caught / fainted / missed (counts + percentages)
|
||||
- Catch rate: caught / total encounters
|
||||
- Average encounters per run
|
||||
|
||||
### 3. Pokemon Rankings
|
||||
- Top N most-caught Pokemon (by pokemon_id frequency across encounters with status=caught), showing sprite + name + count
|
||||
- Top N most-encountered Pokemon (any status), same display
|
||||
- Configurable N (default 5, expandable to 10/all)
|
||||
|
||||
### 4. Team & Deaths
|
||||
- Total Pokemon caught, total deaths (caught with faint_level != null)
|
||||
- Mortality rate: deaths / caught
|
||||
- Most common death causes (death_cause field, grouped + counted, top 5)
|
||||
- Average catch level, average faint level
|
||||
- Type distribution of caught Pokemon (bar chart of pokemon.types, counted across all caught encounters)
|
||||
|
||||
## Data Access
|
||||
|
||||
### Option A — Frontend-only (compute from existing data)
|
||||
The list-runs endpoint already returns all runs with encounters. Stats can be computed client-side by fetching all runs. This is simpler but won't scale well with many runs.
|
||||
|
||||
### Option B — Dedicated backend endpoint (recommended for scale)
|
||||
Add `GET /api/stats` that runs aggregate queries server-side and returns pre-computed stats. This is more work but performs better and keeps the frontend thin.
|
||||
|
||||
**Recommendation:** Start with Option A for simplicity. If performance becomes an issue, migrate to Option B.
|
||||
|
||||
## UI Notes
|
||||
- New route: `/stats`
|
||||
- Add "Stats" link to the main nav/sidebar
|
||||
- Use the existing `StatCard` component for top-level numbers
|
||||
- Charts: consider a lightweight library (e.g., recharts) or simple CSS bar charts to avoid heavy dependencies
|
||||
- Responsive grid layout matching the existing design system (dark mode support)
|
||||
|
||||
## Checklist
|
||||
- [x] Add `/stats` route and page component
|
||||
- [x] Add "Stats" navigation link
|
||||
- [x] Fetch all runs with encounters (or add backend stats endpoint)
|
||||
- [x] Run Overview section (counts, win rate, duration)
|
||||
- [x] Encounter Stats section (caught/fainted/missed breakdown)
|
||||
- [x] Pokemon Rankings section (top caught, top encountered, expandable)
|
||||
- [x] Team & Deaths section (mortality, death causes, type distribution)
|
||||
- [x] Charts for region/generation/type breakdowns
|
||||
- [x] Responsive layout + dark mode styling
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-9z2k
|
||||
title: Implement non-evolution form changes
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T11:51:18Z
|
||||
updated_at: 2026-02-08T11:52:36Z
|
||||
---
|
||||
|
||||
Add ability to change Pokemon forms (e.g. Rotom appliances, Oricorio nectar forms) without evolving. Mirror existing evolution UI pattern with a new 'Change Form' button in StatusChangeModal.
|
||||
19
.beans/nuzlocke-tracker-a7q2--handle-pokemon-evolutions.md
Normal file
19
.beans/nuzlocke-tracker-a7q2--handle-pokemon-evolutions.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
# nuzlocke-tracker-a7q2
|
||||
title: Handle pokemon evolutions
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-05T14:27:07Z
|
||||
updated_at: 2026-02-05T18:26:11Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Add support for pokemon evolutions in the tracker. When a pokemon evolves during a Nuzlocke run, the tracker should reflect the new species while preserving the encounter history (original catch route, catch level, nickname, etc.).
|
||||
|
||||
## Implementation
|
||||
|
||||
- **Data model**: `Evolution` table with from/to pokemon, trigger, level, item, and condition fields. `Encounter.current_pokemon_id` tracks evolved species separately from original.
|
||||
- **Seed data**: Evolution chains fetched from PokeAPI submodule data, with an overrides file for manual corrections.
|
||||
- **API**: `GET /pokemon/{id}/evolutions` returns available evolutions. `PATCH /encounters/{id}` accepts `current_pokemon_id` to record an evolution.
|
||||
- **Frontend**: "Evolve" button in StatusChangeModal shows available evolutions with trigger details. PokemonCard displays the current (evolved) species with "Originally: {name}" label.
|
||||
58
.beans/nuzlocke-tracker-ahza--deployment-strategy.md
Normal file
58
.beans/nuzlocke-tracker-ahza--deployment-strategy.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
# nuzlocke-tracker-ahza
|
||||
title: Deployment Strategy
|
||||
status: completed
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-09T14:03:53Z
|
||||
updated_at: 2026-02-10T11:36:07Z
|
||||
---
|
||||
|
||||
Define and implement a deployment strategy for running the nuzlocke-tracker in production on a local Unraid server while keeping laptop/PC as the development environment.
|
||||
|
||||
## Context
|
||||
|
||||
- **Components:** API (Python/FastAPI), Frontend (Vite/React), PostgreSQL database
|
||||
- **Dev environment:** Laptop/PC — continue using the existing `docker-compose.yml` for local development
|
||||
- **Production host:** Unraid server running Docker containers
|
||||
- **Networking:** LAN-only access, Nginx Proxy Manager already in place on Unraid
|
||||
- **Orchestration:** Docker Compose for production (matching dev workflow). Deploy via SSH from the dev machine.
|
||||
|
||||
## Decided Approach
|
||||
|
||||
**Docker Compose + SSH + Gitea (source hosting, container registry)**
|
||||
|
||||
1. **Gitea** runs on Unraid behind Nginx Proxy Manager with SSL (e.g., `gitea.nerdboden.de`). It serves as the self-hosted Git remote and container registry.
|
||||
2. **Images are built on the dev machine** (podman or docker, cross-compiled for linux/amd64) and pushed to Gitea's container registry as **user-level packages** (e.g., `gitea.nerdboden.de/thefurya/nuzlocke-tracker-api:latest`, `gitea.nerdboden.de/thefurya/nuzlocke-tracker-frontend:latest`).
|
||||
3. **Production runs docker compose** on Unraid at `/mnt/user/appdata/nuzlocke-tracker/`, pulling images from the Gitea container registry instead of mounting source.
|
||||
4. **A deploy script** on the dev machine automates the full flow: build images → push to Gitea registry → SCP compose file to Unraid → generate `.env` if missing → SSH to pull images and (re)start containers.
|
||||
5. **Nginx Proxy Manager** handles routing on the LAN (e.g., `nuzlocke.nerdboden.de` → frontend container, `gitea.nerdboden.de` → Gitea).
|
||||
6. **Database** uses a bind mount (`./data/postgres`) for persistence on the Unraid disk; migrations run automatically on API container startup.
|
||||
|
||||
## Branching Strategy
|
||||
|
||||
**`main` + `develop` + feature branches**
|
||||
|
||||
- **`main`** — always production-ready. Only receives merges from `develop` when ready to deploy. The deploy script builds from `main`.
|
||||
- **`develop`** — integration branch for day-to-day work. Features are merged here and tested before promoting to `main`.
|
||||
- **`feature/*`** — short-lived branches off `develop` for individual features/fixes. Merged back into `develop` via PR or direct merge when complete.
|
||||
|
||||
**Workflow:**
|
||||
1. Create `feature/xyz` from `develop`
|
||||
2. Work on the feature, commit, merge into `develop`
|
||||
3. When ready to deploy: merge `develop` → `main`
|
||||
4. Run `./deploy.sh` (builds from `main`, pushes to Gitea registry, deploys to Unraid via SSH)
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] **Set up branching structure** — create `develop` branch from `main`, establish the `main`/`develop`/`feature/*` workflow
|
||||
- [x] **Update CLAUDE.md with branching rules** — once the branching structure is in place, add instructions to CLAUDE.md that the branching strategy must be adhered to (always work on feature branches, never commit directly to `main`, merge flow is `feature/*` → `develop` → `main`)
|
||||
- [x] **Configure Gitea container registry** — create an access token with `read:package` and `write:package` scopes, verify `docker login gitea.nerdboden.de` works, test pushing and pulling an image as a user-level package
|
||||
- [x] **Create production docker-compose file** (`docker-compose.prod.yml`) — uses images from the Gitea container registry, production env vars, no source volume mounts, proper restart policies
|
||||
- [x] **Create production Dockerfiles (or multi-stage builds)** — ensure frontend is built and served statically (e.g., via the API or a lightweight nginx container), API runs without debug mode
|
||||
- [x] **Create deploy script** — `./deploy.sh` builds images (podman/docker, linux/amd64), pushes to Gitea registry, SCPs compose file, generates `.env` if needed, pulls and starts containers via SSH
|
||||
- [x] **Configure Nginx Proxy Manager** — add proxy host entries for Gitea and the nuzlocke-tracker frontend/API on the appropriate ports
|
||||
- [x] **Environment & secrets management** — deploy script auto-generates `.env` with `POSTGRES_PASSWORD` on Unraid if missing; file lives at `/mnt/user/appdata/nuzlocke-tracker/.env`
|
||||
- [x] **Implement Gitea Actions CI/CD pipeline** — set up Gitea Actions runner on Unraid, create CI workflow (lint/test on `develop`) and deploy workflow (build/push/deploy on `main`); uses GitHub Actions-compatible syntax for portability
|
||||
- [x] **Database backup strategy** — set up a simple scheduled backup for the PostgreSQL data (e.g., cron + `pg_dump` script on Unraid)
|
||||
- [x] **Document the deployment workflow** — README or docs covering how to deploy, redeploy, rollback, and manage the production instance
|
||||
24
.beans/nuzlocke-tracker-aiw6--create-deploy-script.md
Normal file
24
.beans/nuzlocke-tracker-aiw6--create-deploy-script.md
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
# nuzlocke-tracker-aiw6
|
||||
title: Create deploy script
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:48Z
|
||||
updated_at: 2026-02-09T17:28:22Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
blocking:
|
||||
- nuzlocke-tracker-izf6
|
||||
- nuzlocke-tracker-vpn5
|
||||
- nuzlocke-tracker-xmyh
|
||||
- nuzlocke-tracker-jzqz
|
||||
---
|
||||
|
||||
Create a `./deploy.sh` script for the dev machine that automates the full deployment flow.
|
||||
|
||||
- Ensure the script runs from `main` branch (or warns if not)
|
||||
- Build Docker images for API and frontend
|
||||
- Tag images for the local registry (e.g., `unraid:5000/nuzlocke-api:latest`)
|
||||
- Push images to the local registry
|
||||
- Trigger the Portainer webhook to redeploy the stack
|
||||
- Print status/confirmation of each step
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
# nuzlocke-tracker-b9oj
|
||||
title: Implement Dupes Clause & Shiny Clause Enforcement
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T20:03:12Z
|
||||
updated_at: 2026-02-07T20:07:50Z
|
||||
---
|
||||
|
||||
Add enforcement for duplicatesClause and shinyClause rules:
|
||||
- Dupes Clause: Grey out Pokemon in encounter modal whose evolution family is already caught
|
||||
- Shiny Clause: Dedicated Shiny Box for bonus shiny catches that bypass route locks
|
||||
|
||||
## Checklist
|
||||
- [x] Migration: Add is_shiny column to encounters table
|
||||
- [x] Backend model + schema: Add is_shiny field
|
||||
- [x] Backend: Shiny route-lock bypass in create_encounter
|
||||
- [x] Backend: Evolution families endpoint (GET /pokemon/families)
|
||||
- [x] Frontend types + API: Add isShiny fields and fetchPokemonFamilies
|
||||
- [x] Frontend: Dupes Clause greying in EncounterModal
|
||||
- [x] Frontend: ShinyEncounterModal + ShinyBox components
|
||||
- [x] Frontend: RunEncounters orchestration (split encounters, duped IDs, shiny box)
|
||||
- [x] TypeScript type check passes
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
# nuzlocke-tracker-bi4e
|
||||
title: Integrate name suggestions into encounter registration UI
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T15:56:44Z
|
||||
updated_at: 2026-02-11T20:48:02Z
|
||||
parent: nuzlocke-tracker-igl3
|
||||
---
|
||||
|
||||
Show name suggestions in the encounter registration flow so users can pick a nickname with a single click.
|
||||
|
||||
## Requirements
|
||||
|
||||
- When a user registers a new Pokemon encounter, display 5-10 name suggestions below/near the nickname input
|
||||
- Each suggestion is a clickable chip/button that fills in the nickname field
|
||||
- Include a "regenerate" button to get a fresh batch of suggestions
|
||||
- Only show suggestions if the run has a naming scheme selected
|
||||
- The nickname input should still be editable for manual entry
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- **Data fetching**: Call `GET /api/v1/runs/{run_id}/name-suggestions?count=10` to get suggestions from the backend.
|
||||
- **Regeneration**: Each call to the endpoint returns a fresh random batch (backend handles exclusion of used names).
|
||||
- **No dictionary data in frontend**: All suggestion logic lives in the backend.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] Add a name suggestions component (chips/buttons with regenerate)
|
||||
- [x] Integrate the component into the encounter registration modal/form
|
||||
- [x] Wire up the backend API endpoint to the component via React Query
|
||||
- [x] Ensure clicking a suggestion populates the nickname field
|
||||
- [x] Ensure regenerate fetches a new batch from the API
|
||||
- [x] Hide suggestions gracefully if no naming scheme is set on the run
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# nuzlocke-tracker-bkhs
|
||||
title: API Endpoints Implementation
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:46:59Z
|
||||
updated_at: 2026-02-05T13:47:57Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
blocking:
|
||||
- nuzlocke-tracker-8fcj
|
||||
- nuzlocke-tracker-hy41
|
||||
---
|
||||
|
||||
Implement the REST/GraphQL API endpoints for the tracker.
|
||||
|
||||
## Checklist
|
||||
- [x] Reference Data endpoints (read-only for tracker):
|
||||
- [x] GET /api/v1/games - List all games
|
||||
- [x] GET /api/v1/games/:id - Get game details with routes
|
||||
- [x] GET /api/v1/games/:id/routes - List routes for a game
|
||||
- [x] GET /api/v1/routes/:id/pokemon - List available Pokémon for a route
|
||||
- [x] GET /api/v1/pokemon/:id - Get Pokémon details
|
||||
- [x] Run Management endpoints:
|
||||
- [x] POST /api/v1/runs - Create new run
|
||||
- [x] GET /api/v1/runs - List all runs
|
||||
- [x] GET /api/v1/runs/:id - Get run details with encounters
|
||||
- [x] PATCH /api/v1/runs/:id - Update run (settings, status)
|
||||
- [x] DELETE /api/v1/runs/:id - Delete a run
|
||||
- [x] Encounter endpoints:
|
||||
- [x] POST /api/v1/runs/:id/encounters - Log new encounter
|
||||
- [x] PATCH /api/v1/encounters/:id - Update encounter (status, nickname)
|
||||
- [x] DELETE /api/v1/encounters/:id - Remove encounter
|
||||
- [x] Add request validation
|
||||
- [x] Add proper error responses
|
||||
|
||||
## Notes
|
||||
- Follow REST conventions
|
||||
- Return appropriate HTTP status codes
|
||||
- Include pagination for list endpoints if needed
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
# nuzlocke-tracker-bs05
|
||||
title: Build PokeDB.org data import tool
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-10T14:04:11Z
|
||||
updated_at: 2026-02-11T10:54:04Z
|
||||
parent: nuzlocke-tracker-rzu4
|
||||
blocking:
|
||||
- nuzlocke-tracker-spx3
|
||||
---
|
||||
|
||||
Build a standalone Python tool that converts PokeDB.org's JSON data export into our existing seed JSON format. This replaces PokeAPI as the single source of truth for ALL games (Gen 1-9).
|
||||
|
||||
Python was chosen over Go because:
|
||||
- The backend is already Python, so the team is familiar with it
|
||||
- We're processing local JSON files — no need for Go's concurrency
|
||||
- Remains a standalone tool in `tools/import-pokedb/`, not part of the backend
|
||||
|
||||
## Data source
|
||||
|
||||
PokeDB.org provides a full data export at https://pokedb.org/data-export with JSON downloads:
|
||||
- `encounters.json` (69MB, 37,724 records) — all encounter data across all games
|
||||
- `locations.json` — 839 locations
|
||||
- `location_areas.json` — 2,672 location areas
|
||||
- `encounter_methods.json` — 73 encounter methods
|
||||
- `versions.json` — 82 game versions
|
||||
- `pokemon_forms.json` — Pokemon forms with identifiers
|
||||
|
||||
**No scraping required.** Just download the JSON files and process them locally.
|
||||
|
||||
**Terms of use:** "Data is provided for educational, research, and non-commercial purposes." Attribution to PokeDB requested.
|
||||
|
||||
## Encounter data coverage
|
||||
|
||||
Encounter counts by version:
|
||||
- Sword: 10,160 / Shield: 10,144
|
||||
- Scarlet: 4,135 / Violet: 4,101
|
||||
- SoulSilver: 2,492 / HeartGold: 2,475
|
||||
- Shining Pearl: 2,021 / Brilliant Diamond: 2,013
|
||||
- Legends Arceus: 1,756
|
||||
- Black 2: 1,418 / White 2: 1,418
|
||||
- Crystal: 1,375 / Alpha Sapphire: 1,338 / Platinum: 1,337
|
||||
- Diamond: 1,292 / Pearl: 1,289 / Silver: 1,284 / Gold: 1,282
|
||||
- LeafGreen: 987 / FireRed: 985 / White: 981 / Black: 947
|
||||
- Ultra Moon: 886 / Ultra Sun: 885 / X: 880 / Y: 879
|
||||
- Emerald: 763 / Let's Go Eevee: 710 / Sun: 709 / Moon: 707
|
||||
- Sapphire: 707 / Ruby: 707 / Let's Go Pikachu: 690
|
||||
- Blue: 528 / Red: 526 / Yellow: 496
|
||||
|
||||
## Data format details
|
||||
|
||||
Each encounter record has:
|
||||
- `pokemon_form_identifier` — e.g. "pidgey-default", "mr-mime-default"
|
||||
- `version_identifiers` — array of game version IDs (e.g. ["sword", "shield"])
|
||||
- `location_area_identifier` — e.g. "route-01-kanto", "axews-eye"
|
||||
- `encounter_method_identifier` — e.g. "walking-tall-grass", "surfing", "npc-trade"
|
||||
- `levels` — string like "2 - 4" or "67"
|
||||
- Rate fields vary by game generation:
|
||||
- Gen 1/3/6: `rate_overall` (single percentage)
|
||||
- Gen 2/4: `rate_morning`, `rate_day`, `rate_night` (time-of-day percentages)
|
||||
- Gen 5: `rate_spring`, `rate_summer`, `rate_autumn`, `rate_winter` (seasonal)
|
||||
- Gen 8 Sw/Sh: `weather_*_rate` fields (per-weather percentages, e.g. "40%")
|
||||
- Gen 8 Legends Arceus: `during_*` and `while_*` booleans (time+weather conditions)
|
||||
- Gen 9 Sc/Vi: `probability_*` fields (overworld probability weights)
|
||||
- `trade_for` — Pokemon form identifier for NPC trades
|
||||
- `alpha_levels` — for Legends Arceus alpha encounters
|
||||
- `visible` — overworld vs hidden encounter
|
||||
- Max Raid and Tera Raid fields for special encounters
|
||||
|
||||
## Subtasks
|
||||
|
||||
Work is broken into child task beans:
|
||||
|
||||
- [ ] **Set up Python tool scaffold** — project structure, CLI entry point, PokeDB JSON file loading
|
||||
- [ ] **Build reference data mappings** — pokemon_form → pokeapi_id, location_area → name/region, encounter method mapping
|
||||
- [ ] **Core encounter processing** — filter by game version, parse levels, handle rate variants, group by location area
|
||||
- [ ] **Output seed JSON** — produce per-game JSON in existing format, integrate route ordering + special encounters
|
||||
- [ ] **Validation & full generation** — compare against existing data, run for all games, fix discrepancies
|
||||
|
||||
## Encounter method mapping (draft)
|
||||
|
||||
PokeDB method → Our seed method:
|
||||
- `walking-tall-grass`, `walking-*` → "walk"
|
||||
- `surfing`, `surfing-*` → "surf"
|
||||
- `fishing-old-rod` → "old-rod"
|
||||
- `fishing-good-rod` → "good-rod"
|
||||
- `fishing-super-rod` → "super-rod"
|
||||
- `fishing` → "fishing"
|
||||
- `rock-smash` → "rock-smash"
|
||||
- `headbutt-*` → "headbutt"
|
||||
- `npc-gift`, `egg`, `revive` → "gift"
|
||||
- `npc-trade` → "trade"
|
||||
- `symbol-encounter` → "walk" (overworld, Gen 8+)
|
||||
- `wanderer` → "walk" (overworld visible)
|
||||
- `fixed-encounter`, `static-encounter` → "static"
|
||||
- `swarm` → "swarm"
|
||||
- `poke-radar` → "pokeradar"
|
||||
- `dual-slot-mode` → "dual-slot"
|
||||
- Others: TBD based on relevance
|
||||
|
||||
## Notes
|
||||
- This tool replaces `tools/fetch-pokeapi/` as the primary data source for all games
|
||||
- Pokemon form identifiers need mapping to pokeapi IDs — may need a fuzzy match since naming conventions differ
|
||||
- The existing `pokemon.json` has names and pokeapi IDs we can use as a lookup
|
||||
- S/V probability weights are not percentages — they represent relative spawn weights
|
||||
- Legends Arceus uses boolean conditions (during_night + while_clear) rather than rates
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
# nuzlocke-tracker-c6ly
|
||||
title: Build name suggestion engine
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T15:56:44Z
|
||||
updated_at: 2026-02-11T20:44:27Z
|
||||
parent: nuzlocke-tracker-igl3
|
||||
blocking:
|
||||
- nuzlocke-tracker-bi4e
|
||||
---
|
||||
|
||||
Build the backend service and API endpoint that picks random name suggestions from the dictionary based on a selected naming scheme.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Given a category and a run ID, return 5-10 unique suggestions
|
||||
- The engine queries the run's existing encounter nicknames and excludes them from suggestions
|
||||
- Support regeneration (return a fresh batch, avoiding previously shown suggestions where possible)
|
||||
- Handle edge case where category is nearly exhausted gracefully (return fewer suggestions)
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- **Backend service**: A Python module that loads the dictionary JSON, filters by category, excludes used names, and picks random suggestions.
|
||||
- **API endpoint**: `GET /api/v1/runs/{run_id}/name-suggestions?count=10` — reads the run's `naming_scheme`, fetches encounter nicknames, returns suggestions.
|
||||
- **No new DB tables needed**: Used names come from `Encounter.nickname` on the run's encounters.
|
||||
- **Caching**: Load the dictionary once and cache in memory (it's static data).
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] Create a service module for name suggestion logic (e.g. `services/name_suggestions.py`)
|
||||
- [x] Implement dictionary loading with in-memory caching
|
||||
- [x] Implement random selection from a category with exclusion of used names
|
||||
- [x] Add API endpoint for fetching suggestions
|
||||
- [x] Add unit tests for the suggestion logic
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-ceeh
|
||||
title: Clean up old seed generation tools
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T12:52:31Z
|
||||
updated_at: 2026-02-11T13:55:49Z
|
||||
---
|
||||
|
||||
Remove the old Go fetch-pokeapi tool from tools/fetch-pokeapi/ and update README.md references to point to the new import-pokedb tool instead.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# nuzlocke-tracker-ch77
|
||||
title: Integration tests for Games & Routes API
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:13Z
|
||||
updated_at: 2026-02-10T09:33:13Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write integration tests for the games and routes API endpoints in `backend/src/app/api/games.py`.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test CRUD operations for games (create, list, get, update, delete)
|
||||
- [ ] Test route management within a game (create, list, reorder, update, delete)
|
||||
- [ ] Test route encounter management (add/remove Pokemon to routes)
|
||||
- [ ] Test bulk import functionality
|
||||
- [ ] Test region grouping/filtering
|
||||
- [ ] Test error cases (404 for missing games, validation errors, duplicate handling)
|
||||
|
||||
## Notes
|
||||
|
||||
- Use the httpx AsyncClient fixture from the test infrastructure task
|
||||
- Each test should be independent — use fixtures to set up required data
|
||||
- Test both success and error response codes and bodies
|
||||
29
.beans/nuzlocke-tracker-czeh--improve-admin-panel-ux.md
Normal file
29
.beans/nuzlocke-tracker-czeh--improve-admin-panel-ux.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# nuzlocke-tracker-czeh
|
||||
title: Improve admin panel UX
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-05T18:28:04Z
|
||||
updated_at: 2026-02-07T11:59:49Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Improve the admin panel with better interactions and missing management capabilities.
|
||||
|
||||
## Checklist
|
||||
- [x] Evolution data management:
|
||||
- [x] List evolutions (searchable/filterable)
|
||||
- [x] Add new evolution
|
||||
- [x] Edit evolution details (trigger, level, item, conditions)
|
||||
- [x] Delete evolution
|
||||
- [x] Route reordering:
|
||||
- [x] Replace up/down buttons with drag-and-drop
|
||||
- [x] Table sorting (Games table):
|
||||
- [x] Add sortable column support to AdminTable component
|
||||
- [x] Enable sorting by Region, Generation, and Release Year on Games table
|
||||
- [x] General UX improvements:
|
||||
- [x] Improve table layouts and spacing
|
||||
- [x] Add loading states and better error feedback
|
||||
- [x] Add confirmation toasts for successful actions
|
||||
- [x] Improve mobile responsiveness of admin views
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
# nuzlocke-tracker-d8cp
|
||||
title: Set up frontend test infrastructure
|
||||
status: draft
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T09:33:33Z
|
||||
updated_at: 2026-02-10T09:34:00Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
blocking:
|
||||
- nuzlocke-tracker-ee9s
|
||||
- nuzlocke-tracker-1guz
|
||||
---
|
||||
|
||||
Set up the test infrastructure for the React/TypeScript frontend. No testing tooling currently exists.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Install Vitest, @testing-library/react, @testing-library/jest-dom, @testing-library/user-event, jsdom
|
||||
- [ ] Configure Vitest in `vite.config.ts` or a dedicated `vitest.config.ts`
|
||||
- [ ] Set up jsdom as the test environment
|
||||
- [ ] Create a test setup file (e.g. `src/test/setup.ts`) that imports @testing-library/jest-dom matchers
|
||||
- [ ] Create test utility helpers (e.g. render wrapper with providers — QueryClientProvider, BrowserRouter)
|
||||
- [ ] Add a \`test\` script to package.json
|
||||
- [ ] Verify the setup by writing a simple smoke test
|
||||
- [ ] Set up MSW (Mock Service Worker) or a similar API mocking strategy for hook/component tests
|
||||
|
||||
## Notes
|
||||
|
||||
- Vitest integrates natively with Vite, which the project already uses
|
||||
- React Testing Library is the standard for testing React components
|
||||
- The app uses React Query (TanStack Query) and React Router — the test wrapper needs to provide these contexts
|
||||
- MSW is recommended for mocking API calls in hook and component tests, but simpler approaches (vi.mock) may suffice initially
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-dgax
|
||||
title: Nuzlocke Rules Configuration
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:44:22Z
|
||||
updated_at: 2026-02-04T15:58:43Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Create the rules/difficulty settings screen for customizing the Nuzlocke run.
|
||||
|
||||
## Checklist
|
||||
- [x] Create rules configuration component
|
||||
- [x] Implement core Nuzlocke rules toggles:
|
||||
- [x] Standard rules (catch first encounter only, permadeath)
|
||||
- [x] Nickname requirement toggle
|
||||
- [x] Duplicates clause (can skip already-caught species)
|
||||
- [x] Shiny clause (can catch shinies regardless)
|
||||
- [x] Add optional difficulty modifiers:
|
||||
- [x] Hardcore mode (no items in battle)
|
||||
- [x] Level caps (can't overlevel gym leaders)
|
||||
- [x] Set mode only (no switch after KO)
|
||||
- [x] Persist selected rules to run state (local state; backend API TBD)
|
||||
- [x] Show rule explanations/tooltips
|
||||
|
||||
## Notes
|
||||
- Rules should be toggleable after run starts (user preference)
|
||||
- Default to standard Nuzlocke rules
|
||||
30
.beans/nuzlocke-tracker-dqyb--set-up-python-tool-scaffold.md
Normal file
30
.beans/nuzlocke-tracker-dqyb--set-up-python-tool-scaffold.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
# nuzlocke-tracker-dqyb
|
||||
title: Set up Python tool scaffold
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T08:42:58Z
|
||||
updated_at: 2026-02-11T08:49:55Z
|
||||
parent: nuzlocke-tracker-bs05
|
||||
blocking:
|
||||
- nuzlocke-tracker-zno2
|
||||
---
|
||||
|
||||
Set up the standalone Python tool project in `tools/import-pokedb/`.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] Create `tools/import-pokedb/` directory structure
|
||||
- [x] Set up `pyproject.toml` with dependencies (just stdlib should suffice for JSON processing, maybe `click` for CLI)
|
||||
- [x] Create CLI entry point (`__main__.py` or similar) that accepts:
|
||||
- Path to directory containing PokeDB JSON export files
|
||||
- Target output directory (default: `backend/src/app/seeds/data/`)
|
||||
- Optional: specific game version to generate (default: all)
|
||||
- [x] Load and parse all PokeDB JSON files: `encounters.json`, `locations.json`, `location_areas.json`, `encounter_methods.json`, `versions.json`, `pokemon_forms.json`
|
||||
- [x] Basic validation that all expected files are present and parseable
|
||||
|
||||
## Notes
|
||||
- Keep it as a standalone tool, not part of the backend
|
||||
- The PokeDB JSON files are downloaded manually from https://pokedb.org/data-export — no need to automate the download
|
||||
- Model the CLI similarly to how `tools/fetch-pokeapi/` works (cd into dir, run the tool)
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# nuzlocke-tracker-dyzh
|
||||
title: Click-to-edit pattern across admin tables
|
||||
status: completed
|
||||
type: feature
|
||||
priority: high
|
||||
created_at: 2026-02-08T12:32:53Z
|
||||
updated_at: 2026-02-08T12:45:17Z
|
||||
parent: nuzlocke-tracker-iu5b
|
||||
blocking:
|
||||
- nuzlocke-tracker-fxi7
|
||||
- nuzlocke-tracker-mg46
|
||||
---
|
||||
|
||||
Replace the current pattern of separate Edit/Delete action buttons with an inline click-to-edit pattern across all admin pages.
|
||||
|
||||
## Current behavior
|
||||
- Table rows show data with Edit and Delete buttons on the right
|
||||
- Clicking Edit opens a modal form
|
||||
- Clicking Delete opens a confirmation dialog
|
||||
|
||||
## Desired behavior
|
||||
- Clicking a table row opens an edit card/panel inline or as a detail view
|
||||
- The edit card shows all fields in editable form
|
||||
- A Delete button is available within the edit card
|
||||
- Save/Cancel buttons to confirm or discard changes
|
||||
- Clicking outside or pressing Escape cancels
|
||||
|
||||
## Affected pages
|
||||
- AdminPokemon (pokemon table)
|
||||
- AdminEvolutions (evolutions table)
|
||||
- AdminGames (games table)
|
||||
- AdminGameDetail routes tab (routes table)
|
||||
- AdminGameDetail bosses tab (boss battles table)
|
||||
- AdminRouteDetail (route encounters table)
|
||||
- AdminRuns (runs table — delete only, no edit)
|
||||
|
||||
## Notes
|
||||
- Some pages already have row click handlers (Games navigates to detail). Preserve that where it makes sense — the edit card could be the detail page itself.
|
||||
- Keep modal forms for Create (adding new entities) since there's no row to click yet.
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
# nuzlocke-tracker-ecn3
|
||||
title: Prune stale seed data during seeding
|
||||
status: completed
|
||||
type: bug
|
||||
priority: normal
|
||||
created_at: 2026-02-21T16:28:37Z
|
||||
updated_at: 2026-02-21T16:29:43Z
|
||||
---
|
||||
|
||||
Seeds only upsert (add/update), they never remove routes, encounters, or bosses that no longer exist in the seed JSON. When routes are renamed, old route names persist in production.
|
||||
|
||||
## Fix
|
||||
|
||||
After upserting each entity type, delete rows not present in the seed data:
|
||||
|
||||
1. **Routes**: After upserting all routes for a version group, delete routes whose names are not in the seed set. FK cascades handle child routes and encounters.
|
||||
2. **Encounters**: After upserting encounters for a route+game, delete encounters not in the seed data for that route+game pair.
|
||||
3. **Bosses**: After upserting bosses for a version group, delete bosses with order values beyond what the seed provides.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
# nuzlocke-tracker-ee9s
|
||||
title: Unit tests for frontend utilities and hooks
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:38Z
|
||||
updated_at: 2026-02-10T09:33:38Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write unit tests for the frontend utility functions and custom React hooks.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test `utils/formatEvolution.ts` — evolution chain formatting logic
|
||||
- [ ] Test `utils/download.ts` — file download utility
|
||||
- [ ] Test `hooks/useRuns.ts` — run CRUD hook with mocked API
|
||||
- [ ] Test `hooks/useGames.ts` — game fetching hook
|
||||
- [ ] Test `hooks/useEncounters.ts` — encounter operations hook
|
||||
- [ ] Test `hooks/usePokemon.ts` — pokemon data hook
|
||||
- [ ] Test `hooks/useGenlockes.ts` — genlocke operations hook
|
||||
- [ ] Test `hooks/useBosses.ts` — boss operations hook
|
||||
- [ ] Test `hooks/useStats.ts` — stats fetching hook
|
||||
- [ ] Test `hooks/useAdmin.ts` — admin operations hook
|
||||
|
||||
## Notes
|
||||
|
||||
- Utility functions are pure functions — straightforward to test
|
||||
- Hooks wrap React Query — test that they call the right API endpoints, handle loading/error states, and invalidate queries correctly
|
||||
- Use `@testing-library/react`'s `renderHook` for hook testing
|
||||
- Mock the API client (from `src/api/`) rather than individual fetch calls
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
# nuzlocke-tracker-eltb
|
||||
title: Deduplicate case-only duplicate sub-areas in seed data
|
||||
status: completed
|
||||
type: bug
|
||||
priority: normal
|
||||
created_at: 2026-02-08T12:21:44Z
|
||||
updated_at: 2026-02-08T12:22:37Z
|
||||
---
|
||||
|
||||
PokeAPI returns both lowercase and uppercase floor names (e.g. '1f' vs '1F') as separate sub-areas with identical encounter data. This causes duplicate routes in the UI. Fix by merging case-insensitive duplicate children in all seed JSON files, keeping the uppercase name and combining encounters.
|
||||
|
||||
649 duplicates across all 22 seed files.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# nuzlocke-tracker-em40
|
||||
title: Add filtering to admin tables
|
||||
status: completed
|
||||
type: feature
|
||||
priority: low
|
||||
created_at: 2026-02-08T12:33:46Z
|
||||
updated_at: 2026-02-08T19:28:04Z
|
||||
parent: nuzlocke-tracker-iu5b
|
||||
---
|
||||
|
||||
Add filter controls to admin tables beyond the existing text search.
|
||||
|
||||
## Current state
|
||||
- Pokemon and Evolutions have text search
|
||||
- No other filter dimensions available
|
||||
|
||||
## Desired filters
|
||||
- **Pokemon**: Filter by type, generation (derived from dex range)
|
||||
- **Evolutions**: Filter by trigger type (level-up, trade, item, etc.)
|
||||
- **Games**: Filter by region, generation
|
||||
- **Routes**: Filter by encounter method availability
|
||||
- **Runs**: Filter by status (active, completed, failed), game
|
||||
|
||||
## UX
|
||||
- Filter chips or dropdown selectors above the table, next to the existing search bar
|
||||
- Filters combine with search (AND logic)
|
||||
- Clear all filters button
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
# nuzlocke-tracker-ey30
|
||||
title: Reorder Crystal routes to match Gold ordering
|
||||
status: completed
|
||||
type: task
|
||||
created_at: 2026-02-13T14:23:40Z
|
||||
updated_at: 2026-02-13T14:23:40Z
|
||||
---
|
||||
|
||||
Adjusted the route ordering of crystal.json to match gold.json. The sequence is identical — only the order field was changed, encounters were preserved. Crystal is missing Cerulean City (not present in Crystal) so orders are offset by -1 from that point.
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
# nuzlocke-tracker-f44d
|
||||
title: Add Pokemon forms support to seeding
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-06T10:11:23Z
|
||||
updated_at: 2026-02-07T13:30:57Z
|
||||
---
|
||||
|
||||
The current seeding only fetches base Pokemon species. It should also include alternate forms (Alolan, Galarian, Mega, regional variants, etc.) which have different types and stats.
|
||||
|
||||
## Scope
|
||||
|
||||
1. **Data model evaluation**: Determine if Pokemon forms need a separate table or can be handled with additional fields on the existing Pokemon model (e.g., `form_name`, `base_pokemon_id`)
|
||||
|
||||
2. **PokeAPI structure**: Investigate how forms are represented in PokeAPI data:
|
||||
- `pokemon-form` endpoint
|
||||
- `pokemon` endpoint (forms like `pikachu-alola` have separate entries)
|
||||
- Relationship between species and forms
|
||||
|
||||
3. **Seed data updates**: Update `fetch_pokeapi.py` to:
|
||||
- Fetch all forms for Pokemon that appear in encounter tables
|
||||
- Include form-specific data (types, sprites)
|
||||
- Handle form naming consistently
|
||||
|
||||
4. **Frontend considerations**: Ensure Pokemon selector in encounter modal can distinguish forms when relevant
|
||||
|
||||
## Questions to resolve
|
||||
- Should forms be stored as separate Pokemon records or as variants of a base Pokemon?
|
||||
- How do encounter tables reference forms vs base species in PokeAPI?
|
||||
- Which games have form-specific encounters that need to be supported?
|
||||
35
.beans/nuzlocke-tracker-f5ob--mvp-core-nuzlocke-tracker.md
Normal file
35
.beans/nuzlocke-tracker-f5ob--mvp-core-nuzlocke-tracker.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
# nuzlocke-tracker-f5ob
|
||||
title: MVP - Core Nuzlocke Tracker
|
||||
status: completed
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:43:34Z
|
||||
updated_at: 2026-02-07T12:31:15Z
|
||||
blocking:
|
||||
- nuzlocke-tracker-f0fm
|
||||
---
|
||||
|
||||
The minimum viable product for the Nuzlocke Tracker application. This epic covers the essential features needed for a user to track a basic Nuzlocke run.
|
||||
|
||||
## Architecture
|
||||
- **Frontend**: Web application for users to track their runs
|
||||
- **Backend API**: RESTful or GraphQL API for data persistence
|
||||
- **Database**: Persistent storage for game data, user runs, and encounters
|
||||
- **Admin Panel**: Interface for managing reference data (games, routes, Pokémon)
|
||||
|
||||
## Goals
|
||||
- Allow users to select a Pokémon game to play
|
||||
- Support optional difficulty/rule settings
|
||||
- Track encounters per route/area
|
||||
- Track Pokémon status (alive, dead, boxed)
|
||||
- Provide a clear overview of the current run
|
||||
- Admin can manage game/route/Pokémon reference data
|
||||
|
||||
## Out of Scope for MVP
|
||||
- User authentication (single user assumed)
|
||||
- Multiple simultaneous runs
|
||||
- Cloud sync across devices
|
||||
- Team builder/planner
|
||||
- Detailed statistics and analytics
|
||||
- Social features
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# nuzlocke-tracker-fxi7
|
||||
title: Pokemon detail card with encounters and evolution chain
|
||||
status: completed
|
||||
type: feature
|
||||
priority: high
|
||||
created_at: 2026-02-08T12:33:05Z
|
||||
updated_at: 2026-02-08T12:53:13Z
|
||||
parent: nuzlocke-tracker-iu5b
|
||||
---
|
||||
|
||||
When viewing/editing a Pokemon in the admin panel, show contextual information about where it can be encountered and its evolution chain.
|
||||
|
||||
## Desired behavior
|
||||
- The pokemon edit card (from click-to-edit) shows:
|
||||
1. Editable fields (name, types, dex number, sprite, etc.)
|
||||
2. **Encounter locations**: A list of routes/games where this pokemon appears as a route encounter. Grouped by game, showing route name + encounter method + levels.
|
||||
3. **Evolution chain**: Visual display of the pokemon's evolution family — predecessors and successors with triggers (level, item, trade, etc.)
|
||||
- Encounter locations link to the route detail page in admin for quick navigation
|
||||
- Evolution chain entries are clickable to open the EvolutionFormModal for direct editing
|
||||
|
||||
## Implementation
|
||||
|
||||
### Tabbed modal (edit mode)
|
||||
In edit mode, the PokemonFormModal uses three tabs instead of a single scrolling view:
|
||||
- **Details** — the form fields (PokeAPI ID, name, types, etc.) with Save/Delete/Cancel footer
|
||||
- **Evolutions** — clickable evolution chain rows that open a stacked EvolutionFormModal for direct editing
|
||||
- **Encounters** — encounter locations grouped by game, with route names linking to admin route detail pages
|
||||
|
||||
In create mode, no tabs are shown (just the form fields).
|
||||
|
||||
### Backend endpoints
|
||||
- `GET /pokemon/{id}/encounter-locations` — returns encounters grouped by game with route/game names eagerly loaded
|
||||
- `GET /pokemon/{id}/evolution-chain` — BFS to find full evolution family, returns all edges with from/to Pokemon
|
||||
|
||||
### Frontend
|
||||
- New types: `PokemonEncounterLocationItem`, `PokemonEncounterLocation`
|
||||
- New API functions: `fetchPokemonEncounterLocations`, `fetchPokemonEvolutionChain`
|
||||
- New hooks: `usePokemonEncounterLocations`, `usePokemonEvolutionChain`
|
||||
- Extracted `formatEvolutionMethod` to shared `utils/formatEvolution.ts`
|
||||
|
||||
## Notes
|
||||
- This helps the admin quickly verify data completeness — 'is this pokemon assigned to the right routes?' and 'are its evolutions set up correctly?'
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-g57d
|
||||
title: Implement conditional boss battle teams
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T19:51:02Z
|
||||
updated_at: 2026-02-08T19:54:52Z
|
||||
---
|
||||
|
||||
Wire up the existing condition_label column on boss_pokemon to support variant teams in the UI. This includes: admin BossTeamEditor with variant tabs, BossDefeatModal with variant selector, RunEncounters boss card variant display, and schema additions for BulkBossPokemonItem and frontend BossPokemonInput.
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
# nuzlocke-tracker-g8zi
|
||||
title: 'Fix Pokemon form identification: separate PokeAPI ID from national dex'
|
||||
status: completed
|
||||
type: bug
|
||||
priority: high
|
||||
created_at: 2026-02-07T13:44:25Z
|
||||
updated_at: 2026-02-07T13:54:29Z
|
||||
blocking:
|
||||
- 6aje
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Pokemon forms (Alolan, Galarian, etc.) share a national dex number with their base species (e.g., Alolan Rattata is still national dex #19, same as regular Rattata). However, the current data model uses the PokeAPI internal ID (e.g., 10091 for Alolan Rattata) as the `national_dex` field. This is semantically wrong and causes:
|
||||
|
||||
1. **Wrong display**: Frontend shows "#10091" next to Alolan Rattata instead of "#19"
|
||||
2. **Broken sorting**: Forms sort at the end of the Pokemon list instead of next to their base species
|
||||
3. **Misleading data**: The field name implies a national Pokedex number but contains an internal API ID
|
||||
|
||||
## Current architecture
|
||||
|
||||
The `national_dex` field is deeply embedded as the unique Pokemon identifier:
|
||||
|
||||
- **Database**: `SmallInteger` column with `UNIQUE` constraint (`alembic/versions/03e5f186a9d5`)
|
||||
- **Models**: `pokemon.py` — `mapped_column(SmallInteger, unique=True)`
|
||||
- **Seeder**: `loader.py` — upsert conflict resolution on `national_dex`, builds `{national_dex: id}` mapping for linking encounters and evolutions
|
||||
- **Seed data**: `fetch_pokeapi.py` — uses PokeAPI pokemon ID as `national_dex` for both base species and forms
|
||||
- **API**: All CRUD operations key on `national_dex`, returned as `nationalDex` in JSON
|
||||
- **Frontend**: Displayed as `#nationalDex` in Pokemon selector, admin table, encounter modals
|
||||
|
||||
## Proposed fix
|
||||
|
||||
Add a `pokemon_id` (or similar) field as the true unique identifier (the PokeAPI pokemon ID), and keep `national_dex` as the real national dex number (shared between forms). This requires changes across every layer.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Add new migration: add `pokemon_id` column (unique, not null), change `national_dex` unique constraint to non-unique
|
||||
- [ ] Update Pokemon model to add `pokemon_id` field
|
||||
- [ ] Update seed data: `pokemon.json` entries get both `pokemon_id` (PokeAPI ID) and `national_dex` (real dex number, from species endpoint)
|
||||
- [ ] Update `fetch_pokeapi.py`: for forms, look up the species to get the real national dex, store PokeAPI ID separately
|
||||
- [ ] Update `loader.py`: upsert on `pokemon_id` instead of `national_dex`, update encounter/evolution linking
|
||||
- [ ] Update API schemas and endpoints to expose both fields
|
||||
- [ ] Update frontend to display real `national_dex` but use `pokemon_id` internally for uniqueness
|
||||
- [ ] Update encounter seed data to reference `pokemon_id` instead of `national_dex`
|
||||
|
||||
## Impact
|
||||
|
||||
Touches almost every layer: migration, model, seeder, API, frontend. Should be done before more forms are added (bean 6aje) to avoid migrating bad data.
|
||||
31
.beans/nuzlocke-tracker-gkcy--output-seed-json.md
Normal file
31
.beans/nuzlocke-tracker-gkcy--output-seed-json.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
# nuzlocke-tracker-gkcy
|
||||
title: Output seed JSON
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-11T08:43:21Z
|
||||
updated_at: 2026-02-11T10:00:00Z
|
||||
parent: nuzlocke-tracker-bs05
|
||||
blocking:
|
||||
- nuzlocke-tracker-vdks
|
||||
---
|
||||
|
||||
Generate the final per-game JSON files in the existing seed format.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] **Apply route ordering**: Use the existing `backend/src/app/seeds/route_order.json` to assign `order` values to routes. Handle aliases (e.g. "red-blue" → "firered-leafgreen"). Log warnings for routes not in the order file.
|
||||
- [x] **Merge special encounters**: Integrate starters, gifts, fossils, and trades from `backend/src/app/seeds/special_encounters.json` into the appropriate routes. Pokemon names are resolved to proper display names via PokemonMapper.
|
||||
- [x] **Output per-game JSON**: Write `{game-slug}.json` files matching the existing format:
|
||||
```json
|
||||
[{"name": "Route 1", "order": 3, "encounters": [...], "children": []}]
|
||||
```
|
||||
- [x] **Output games.json**: Generate the global games list from `version_groups.json` — 38 games written, matching existing count.
|
||||
- [x] **Output pokemon.json**: Generate the global pokemon list including all pokemon referenced in any encounter. Include pokeapi_id, national_dex, name, types, sprite_url.
|
||||
- [x] **Handle version exclusives**: Encounters are filtered by `version_identifiers` per game — verified FireRed vs LeafGreen have 18 exclusives each.
|
||||
|
||||
## Notes
|
||||
- The output must be a drop-in replacement for the existing files in `backend/src/app/seeds/data/`
|
||||
- Boss data (`{game}-bosses.json`) is NOT generated by this tool — it's manually curated
|
||||
- Evolutions data is also separate (currently from PokeAPI) — out of scope for this task
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# nuzlocke-tracker-glh8
|
||||
title: Gather generation metadata (games, regions)
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-08T19:20:49Z
|
||||
updated_at: 2026-02-09T08:06:19Z
|
||||
parent: nuzlocke-tracker-25mh
|
||||
blocking:
|
||||
- nuzlocke-tracker-kz5g
|
||||
---
|
||||
|
||||
Collect and store metadata about each Pokemon generation to support genlocke features. This data is needed so the app can present generation-aware options when setting up a genlocke (e.g. "pick one game per generation").
|
||||
|
||||
## Data to gather per generation
|
||||
- **Generation number** (1–9)
|
||||
- **Main region** (e.g. Gen 1 → Kanto, Gen 2 → Johto, etc.)
|
||||
- **Games in the generation** — including remakes and enhanced versions:
|
||||
- Original titles (e.g. Red, Blue, Yellow)
|
||||
- Remakes that belong to the generation's region (e.g. FireRed/LeafGreen are Gen 1 region but Gen 3 era)
|
||||
- Consider whether remakes should be listed under their original generation (by region) or their release generation (by engine/dex) — genlocke players typically organize by region
|
||||
|
||||
## Notes
|
||||
- This could be stored as seed data (JSON) or as a database table
|
||||
- The existing Game model already has `generation` and `region` fields, so some of this data may already be derivable from existing games in the DB
|
||||
- However, a dedicated generations reference would be useful for UI purposes (showing all generations even if not all games are seeded yet)
|
||||
- Check if `backend/src/app/seeds/data/generations.json` already exists or if this needs to be created from scratch
|
||||
|
||||
## Decisions
|
||||
- Legends games (Hisui, Lumiose) are excluded from genlocke presets — available via Custom only
|
||||
- Black 2/White 2 are grouped with Black/White in the same Unova slot (category: sequel)
|
||||
- Normal Genlocke defaults use best mainline remake: FireRed, HeartGold, Alpha Sapphire, Platinum, Ultra Sun
|
||||
- Metadata stored as `category` field on Game model + standalone `regions.json` seed file
|
||||
|
||||
## Checklist
|
||||
- [x] Define the generation-to-region mapping (Gen 1 = Kanto, Gen 2 = Johto, ..., Gen 9 = Paldea)
|
||||
- [x] Determine how to group games by region (use `region` field on existing Game model, or create a dedicated lookup)
|
||||
- [x] Create a `regions.json` seed file (or equivalent) with: generation number, region name, region order, and which games belong to each region
|
||||
- [x] Categorize each game as "original", "remake", "enhanced", "sequel", or "spinoff" so presets can filter appropriately
|
||||
- [x] Define which game is the "default" pick per region for the Normal Genlocke preset (e.g., FireRed for Kanto, HeartGold for Johto)
|
||||
- [x] Add an API endpoint or extend the games endpoint to return games grouped by region with generation metadata
|
||||
- [x] Verify all seeded games are correctly tagged with their region
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
# nuzlocke-tracker-gvom
|
||||
title: Boss Battles, Level Caps & Badges
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T10:09:33Z
|
||||
updated_at: 2026-02-08T10:15:38Z
|
||||
---
|
||||
|
||||
Add boss battle data models, API endpoints, and UI for gym leaders, elite four, champion, etc. Includes:
|
||||
- Backend models (BossBattle, BossPokemon, BossResult)
|
||||
- Database migration
|
||||
- API endpoints for CRUD and run tracking
|
||||
- Frontend types, API client, hooks
|
||||
- Sticky level cap bar on run page
|
||||
- Boss battle cards interleaved in encounter list
|
||||
- Admin panel for managing boss battles
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] Phase 1: Backend models & migration
|
||||
- [x] Phase 2: Backend schemas
|
||||
- [x] Phase 3: Backend API endpoints
|
||||
- [x] Phase 4: Frontend types, API & hooks
|
||||
- [x] Phase 5: Frontend run page (level cap bar + boss cards)
|
||||
- [x] Phase 6: Frontend admin panel
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# nuzlocke-tracker-h3fw
|
||||
title: Use HoF team for genlocke retirement instead of all alive Pokemon
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T09:15:00Z
|
||||
updated_at: 2026-02-09T09:26:54Z
|
||||
parent: nuzlocke-tracker-8w9s
|
||||
blocking:
|
||||
- nuzlocke-tracker-25mh
|
||||
---
|
||||
|
||||
The current retireHoF implementation in `advance_leg()` retires ALL alive, non-shiny, caught Pokemon from the completed run. This is incorrect — only the Hall of Fame team (up to 6 Pokemon selected by the player) should be retired.
|
||||
|
||||
## Current behavior
|
||||
```python
|
||||
# genlockes.py — retires everything alive
|
||||
select(Encounter.pokemon_id).where(
|
||||
Encounter.run_id == current_leg.run_id,
|
||||
Encounter.status == "caught",
|
||||
Encounter.faint_level.is_(None),
|
||||
Encounter.is_shiny.is_(False),
|
||||
)
|
||||
```
|
||||
|
||||
## Desired behavior
|
||||
- If the run has `hof_encounter_ids` set, use those encounter IDs to determine which Pokemon to retire
|
||||
- If `hof_encounter_ids` is not set (legacy/skipped), fall back to the current "all alive" behavior for backwards compatibility
|
||||
- Only the HoF team members and their evolutionary families get added to the retired list
|
||||
|
||||
## Changes needed
|
||||
- Update `advance_leg()` in `backend/src/app/api/genlockes.py` to check `current_run.hof_encounter_ids` first
|
||||
- If present, query only those encounters for retirement
|
||||
- If absent, keep the current fallback query
|
||||
- Update the frontend `RunEncounters.tsx` to also scope `retiredPokemonIds` correctly (no change needed — it reads from the backend response)
|
||||
|
||||
## Checklist
|
||||
- [x] Update `advance_leg()` to prefer `hof_encounter_ids` over all-alive query
|
||||
- [x] Verify backwards compatibility when `hof_encounter_ids` is null
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
# nuzlocke-tracker-hit0
|
||||
title: Group parent/child routes in admin route table
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-13T13:33:36Z
|
||||
updated_at: 2026-02-13T13:34:42Z
|
||||
---
|
||||
|
||||
Visually indent child routes under their parent in the admin route table. Dragging a parent route moves all its children with it. Children cannot be independently dragged to a new position.
|
||||
|
||||
## Checklist
|
||||
- [x] Add organizeRoutes() function to AdminGameDetail.tsx
|
||||
- [x] Replace SortableRouteRow with SortableRouteGroup using multiple tbody elements
|
||||
- [x] Update SortableContext to only track group IDs
|
||||
- [x] Update handleDragEnd for group-aware reordering
|
||||
- [x] Handle edge cases (standalone routes, orphan children)
|
||||
- [x] Verify frontend build passes
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# nuzlocke-tracker-hjkk
|
||||
title: Unit tests for Pydantic schemas and model validation
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:03Z
|
||||
updated_at: 2026-02-10T09:33:03Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write unit tests for the Pydantic schemas in `backend/src/app/schemas/`. These are pure validation logic and can be tested without a database.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test `CamelModel` base class (snake_case → camelCase alias generation)
|
||||
- [ ] Test run schemas — creation validation, required fields, optional fields, serialization
|
||||
- [ ] Test game schemas — validation rules, field constraints
|
||||
- [ ] Test encounter schemas — status enum validation, field dependencies
|
||||
- [ ] Test boss schemas — nested model validation
|
||||
- [ ] Test genlocke schemas — complex nested structures
|
||||
- [ ] Test stats schemas — response model structure
|
||||
- [ ] Test evolution schemas — validation of evolution chain data
|
||||
|
||||
## Notes
|
||||
|
||||
- Focus on: valid input acceptance, invalid input rejection, serialization output format
|
||||
- The `CamelModel` base class does alias generation — verify both input (camelCase) and output (camelCase) work
|
||||
- Test edge cases like empty strings, negative numbers, missing required fields
|
||||
39
.beans/nuzlocke-tracker-hm6t--pokemon-status-management.md
Normal file
39
.beans/nuzlocke-tracker-hm6t--pokemon-status-management.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
# nuzlocke-tracker-hm6t
|
||||
title: Pokemon Status Management
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:44:37Z
|
||||
updated_at: 2026-02-05T16:47:18Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Implement the system for tracking Pokémon status (alive, dead, boxed).
|
||||
|
||||
## Checklist
|
||||
- [x] Create Pokémon card/tile component showing:
|
||||
- [x] Sprite, name, nickname
|
||||
- [x] Current status with visual indicator (green/red dot)
|
||||
- [x] Location caught
|
||||
- [x] Implement status transitions:
|
||||
- [x] Alive → Dead (fainted in battle) via StatusChangeModal with confirmation
|
||||
- [ ] Alive → Boxed (stored in PC) — deferred, no boxed tracking yet
|
||||
- [ ] Boxed → Alive (added to party) — deferred, no boxed tracking yet
|
||||
- [x] Add death recording:
|
||||
- [x] Optional: record cause of death (free text, max 100 chars)
|
||||
- [x] Optional: record level at death
|
||||
- [x] Create "Graveyard" view for fallen Pokémon (on RunDashboard)
|
||||
- [ ] Create "Box" view for stored Pokémon — deferred, no boxed tracking yet
|
||||
|
||||
## Implementation (death_cause feature)
|
||||
- Backend: Alembic migration adds `death_cause` VARCHAR(100) to encounters
|
||||
- Backend: Model + schemas updated with `death_cause` field
|
||||
- Frontend: `StatusChangeModal` for recording death with confirmation from RunDashboard
|
||||
- Frontend: `PokemonCard` now clickable with status indicator dot and death cause display
|
||||
- Frontend: `EncounterModal` includes death cause input alongside faint level
|
||||
- Frontend: `RunEncounters` shows death cause in route list
|
||||
|
||||
## Notes
|
||||
- Status changes should be confirmable (prevent accidental deaths) ✓
|
||||
- Consider undo functionality for misclicks — not implemented (Nuzlocke rules: death is permanent)
|
||||
17
.beans/nuzlocke-tracker-hwyk--set-up-portainer-on-unraid.md
Normal file
17
.beans/nuzlocke-tracker-hwyk--set-up-portainer-on-unraid.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# nuzlocke-tracker-hwyk
|
||||
title: Set up Portainer on Unraid
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:44Z
|
||||
updated_at: 2026-02-09T16:53:41Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
Install Portainer CE on the Unraid server for container/stack management.
|
||||
|
||||
- Run Portainer CE as a Docker container on Unraid
|
||||
- Configure it to manage the local Docker environment
|
||||
- Import/create a stack from the production docker-compose file
|
||||
- Verify the stack can be deployed and managed through the Portainer UI
|
||||
43
.beans/nuzlocke-tracker-hy41--admin-panel.md
Normal file
43
.beans/nuzlocke-tracker-hy41--admin-panel.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# nuzlocke-tracker-hy41
|
||||
title: Admin Panel
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:47:05Z
|
||||
updated_at: 2026-02-05T18:22:09Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Build an admin interface for managing reference data.
|
||||
|
||||
## Checklist
|
||||
- [x] Create admin routes/pages separate from tracker
|
||||
- [x] Game Management:
|
||||
- [x] List all games
|
||||
- [x] Add new game
|
||||
- [x] Edit game details
|
||||
- [x] Delete game (with cascade warning)
|
||||
- [x] Route Management:
|
||||
- [x] List routes for a game
|
||||
- [x] Add new route
|
||||
- [x] Edit route details (name, order)
|
||||
- [x] Delete route
|
||||
- [x] Reorder routes via drag-and-drop (implemented as up/down buttons)
|
||||
- [x] Route Pokémon Assignment:
|
||||
- [x] View Pokémon available on a route
|
||||
- [x] Add Pokémon to route
|
||||
- [x] Remove Pokémon from route
|
||||
- [x] Set encounter rates/methods
|
||||
- [x] Pokémon Management:
|
||||
- [x] List all Pokémon
|
||||
- [x] Add new Pokémon
|
||||
- [x] Edit Pokémon details
|
||||
- [x] Bulk import from CSV/JSON
|
||||
- [x] Admin API endpoints:
|
||||
- [x] POST/PUT/DELETE for games, routes, pokemon, route_pokemon
|
||||
|
||||
## Notes
|
||||
- Can be a simple CRUD interface
|
||||
- Consider using a UI library for tables/forms
|
||||
- No auth required for MVP (assume local/trusted use)
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# nuzlocke-tracker-i08l
|
||||
title: Implement Pinwheel Clause support
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T19:18:34Z
|
||||
updated_at: 2026-02-07T19:21:45Z
|
||||
---
|
||||
|
||||
Add pinwheel_zone column to routes, pinwheelClause toggle to NuzlockeRules, zone-aware encounter locking on frontend and backend.
|
||||
|
||||
## Checklist
|
||||
- [x] Alembic migration for pinwheel_zone column
|
||||
- [x] SQLAlchemy model update
|
||||
- [x] Pydantic schema updates
|
||||
- [x] Route list API helper update
|
||||
- [x] Encounter creation API zone-aware sibling check
|
||||
- [x] Seed loader update
|
||||
- [x] Seed data for Pinwheel Forest zones
|
||||
- [x] NuzlockeRules per-run toggle
|
||||
- [x] Frontend types (game.ts, admin.ts)
|
||||
- [x] Admin route form pinwheelZone input
|
||||
- [x] Encounter page zone-aware locking, counts, and filtering
|
||||
- [x] getZoneEncounters helper
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
# nuzlocke-tracker-iam7
|
||||
title: Unit tests for services layer
|
||||
status: draft
|
||||
type: task
|
||||
created_at: 2026-02-10T09:33:08Z
|
||||
updated_at: 2026-02-10T09:33:08Z
|
||||
parent: nuzlocke-tracker-yzpb
|
||||
---
|
||||
|
||||
Write unit tests for the business logic in `backend/src/app/services/`. Currently this is the `families.py` service which handles Pokemon evolution family resolution.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Test family resolution with simple linear evolution chains (e.g. A → B → C)
|
||||
- [ ] Test family resolution with branching evolutions (e.g. Eevee)
|
||||
- [ ] Test family resolution with region-specific evolutions
|
||||
- [ ] Test edge cases: single-stage Pokemon, circular references (if possible), missing data
|
||||
|
||||
## Notes
|
||||
|
||||
- `services/families.py` contains the core logic for resolving Pokemon evolution families
|
||||
- These tests may need mock database sessions or in-memory data depending on how the service queries data
|
||||
- If the service methods take a DB session, mock it; if they operate on data objects, pass test data directly
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-idh2
|
||||
title: Add PokeDB.org data attribution
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T14:52:22Z
|
||||
updated_at: 2026-02-10T14:56:25Z
|
||||
---
|
||||
|
||||
PokeDB.org requires attribution when their data is used. Implement visible attribution in the application UI. This is both a requirement of their terms of use and good practice.
|
||||
34
.beans/nuzlocke-tracker-igl3--name-generation.md
Normal file
34
.beans/nuzlocke-tracker-igl3--name-generation.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# nuzlocke-tracker-igl3
|
||||
title: Name Generation
|
||||
status: completed
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-05T13:45:15Z
|
||||
updated_at: 2026-02-11T20:48:02Z
|
||||
---
|
||||
|
||||
Implement a dictionary-based nickname generation system for Nuzlocke runs. Instead of using an LLM API to generate names on the fly, provide a static dictionary of words categorised by theme. A word can belong to multiple categories, making it usable across different naming schemes.
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
- **Dictionary storage**: Static JSON file in `backend/src/app/seeds/data/`, alongside other seed data. Not exposed to frontend directly.
|
||||
- **Dictionary format**: Category-keyed structure (`{ "mythology": ["Apollo", ...], "space": ["Nova", ...] }`) for fast lookup by naming scheme. Words may appear in multiple categories.
|
||||
- **Suggestion logic**: Backend service with API endpoint. Frontend calls the backend to get suggestions.
|
||||
- **Used-name tracking**: No new storage needed. The existing `Encounter.nickname` field already tracks assigned names. The suggestion engine queries encounter nicknames for the current run and excludes them.
|
||||
- **Naming scheme per run**: Dedicated nullable `naming_scheme` column on `NuzlockeRun` (not in the `rules` JSONB).
|
||||
|
||||
## Approach
|
||||
|
||||
- **Static dictionary**: A local data file (JSON) containing words organised by category (e.g. mythology, food, space, nature, warriors, music, etc.)
|
||||
- **~150-200 words per category**: A typical Nuzlocke has ~100 encounters, so this provides ample variety without repetition.
|
||||
- **Name suggestion UX**: When registering a new encounter, the user is shown 5-10 suggested names from their chosen naming scheme. They can click one to select it, or regenerate for a fresh batch.
|
||||
- **Naming scheme selection**: Users pick a naming scheme (category) per run, either at run creation or in run settings.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [x] Word dictionary data file exists with multiple categories, each containing 150-200 words
|
||||
- [x] Name suggestion engine picks random names from the selected category, avoiding duplicates already used in the run
|
||||
- [x] Encounter registration UI shows 5-10 clickable name suggestions
|
||||
- [x] User can regenerate suggestions if none fit
|
||||
- [x] User can select a naming scheme per run
|
||||
18
.beans/nuzlocke-tracker-iu5b--admin-ux-improvement-round.md
Normal file
18
.beans/nuzlocke-tracker-iu5b--admin-ux-improvement-round.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
# nuzlocke-tracker-iu5b
|
||||
title: Admin UX improvement round
|
||||
status: completed
|
||||
type: epic
|
||||
priority: normal
|
||||
created_at: 2026-02-08T12:32:43Z
|
||||
updated_at: 2026-02-08T19:32:28Z
|
||||
---
|
||||
|
||||
A round of UX improvements to the admin panel to make data editing more intuitive and efficient. The admin panel is the primary tool for populating game data (routes, encounters, bosses, evolutions), so friction here directly slows down adding support for new games.
|
||||
|
||||
## Key themes
|
||||
|
||||
- **Consistency**: Unify interaction patterns across all admin pages (click-to-edit, reordering, selectors)
|
||||
- **Efficiency**: Reduce clicks and navigation depth for common workflows
|
||||
- **Discoverability**: Surface related data (where a pokemon appears, its evolution chain) directly in context
|
||||
- **Bulk operations**: Enable importing all entity types, not just Pokemon
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# nuzlocke-tracker-izf6
|
||||
title: Configure Gitea container registry
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:40Z
|
||||
updated_at: 2026-02-09T16:53:09Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
Set up and verify the Gitea container registry for hosting Docker images as user-level packages.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Create a Gitea access token with `read:package` and `write:package` scopes
|
||||
- [ ] Verify `docker login gitea.nerdboden.de` works from the dev machine
|
||||
- [ ] Test pushing a Docker image as a user-level package (e.g., `gitea.nerdboden.de/thefurya/nuzlocke-tracker-api:latest`)
|
||||
- [ ] Verify the image appears under the user's Packages tab in Gitea
|
||||
- [ ] Test pulling the image back (from Unraid or dev machine)
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
# nuzlocke-tracker-j28y
|
||||
title: Curate route ordering to match game progression
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-05T13:37:39Z
|
||||
updated_at: 2026-02-07T12:30:17Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Routes are currently in alphabetical order from PokeAPI. Update the order field in each game's JSON seed file to reflect actual game progression (e.g., Pallet Town → Route 1 → Viridian City → Route 2 → ...).
|
||||
|
||||
## Automated Approach: Bulbapedia Walkthrough Scraping
|
||||
|
||||
We already have all location/encounter data from PokeAPI. The missing piece is progression order, which can be extracted from Bulbapedia walkthroughs.
|
||||
|
||||
### Data Source
|
||||
Every game has a Bulbapedia walkthrough with routes listed in progression order:
|
||||
- https://bulbapedia.bulbagarden.net/wiki/Walkthrough:Pokémon_FireRed_and_LeafGreen
|
||||
- https://bulbapedia.bulbagarden.net/wiki/Walkthrough:Pokémon_Emerald
|
||||
- https://bulbapedia.bulbagarden.net/wiki/Walkthrough:Pokémon_HeartGold_and_SoulSilver
|
||||
- (and so on for all games through Gen 8)
|
||||
|
||||
### Implementation Plan
|
||||
1. **Scrape walkthrough TOCs** - Parse the section headings from each game's walkthrough page to get route order
|
||||
2. **Normalize names** - Map Bulbapedia location names to PokeAPI location names (handle differences like "Route 1" vs "Kanto Route 1")
|
||||
3. **Generate ordering** - Create a JSON mapping of `{game: {location_name: order_number}}`
|
||||
4. **Update fetch_pokeapi.py** - Apply ordering when generating seed data
|
||||
|
||||
### Benefits
|
||||
- Automatable for all games (Gen 1-8)
|
||||
- Bulbapedia walkthroughs are community-maintained and accurate
|
||||
- Scales as we add more games
|
||||
- Only needs to run once per game (or when walkthroughs update)
|
||||
|
||||
### Considerations
|
||||
- Gen 9 (Scarlet/Violet) is open-world so ordering is less meaningful
|
||||
- Some games have branching paths - may need to pick a canonical order
|
||||
- Name matching between Bulbapedia and PokeAPI may need fuzzy matching
|
||||
|
||||
## Current Scope
|
||||
- FireRed and LeafGreen share the same route progression (Kanto)
|
||||
- HeartGold and SoulSilver share the same route progression (Johto + Kanto)
|
||||
- Emerald has its own progression (Hoenn)
|
||||
- So effectively 3 unique orderings to define for current games
|
||||
|
||||
## Files
|
||||
- `backend/src/app/seeds/data/firered.json`
|
||||
- `backend/src/app/seeds/data/leafgreen.json`
|
||||
- `backend/src/app/seeds/data/emerald.json`
|
||||
- `backend/src/app/seeds/data/heartgold.json`
|
||||
- `backend/src/app/seeds/data/soulsilver.json`
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
# nuzlocke-tracker-jain
|
||||
title: Handle Nincada split evolution (Ninjask + Shedinja)
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T19:38:55Z
|
||||
updated_at: 2026-02-08T20:47:50Z
|
||||
---
|
||||
|
||||
Nincada is a special case in Pokemon: when it evolves at level 20, the player gets both Ninjask (the normal evolution) AND Shedinja (if there's an empty party slot and a spare Poke Ball). This creates a unique situation for Nuzlocke tracking since one encounter effectively produces two usable Pokemon.
|
||||
|
||||
## Problem
|
||||
|
||||
The current evolution system assumes 1:1 evolution (one Pokemon evolves into one Pokemon). The Nincada line breaks this — a single caught Nincada can yield two team members. Nuzlocke rules vary on how to handle this:
|
||||
- Some players treat Shedinja as a free bonus (allowed to use both)
|
||||
- Some players must choose one and box/release the other
|
||||
- Some rulesets ban Shedinja entirely since it wasn't "encountered"
|
||||
|
||||
## Considerations
|
||||
|
||||
- The evolution data already has a `shed` trigger type for the Nincada → Shedinja evolution, separate from the `level-up` trigger for Nincada → Ninjask
|
||||
- This may need a rule option in run settings (e.g., "Allow Shedinja from Nincada evolution")
|
||||
- The encounter tracking may need to support creating a second encounter entry from the same route when a Nincada evolves
|
||||
- Consider whether this is purely a rules/UI concern or if the data model needs changes
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# nuzlocke-tracker-jlzs
|
||||
title: Implement Gitea Actions CI/CD pipeline
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T09:38:15Z
|
||||
updated_at: 2026-02-10T11:34:52Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
Set up Gitea Actions as the CI/CD pipeline for the nuzlocke-tracker. Gitea Actions uses the same syntax as GitHub Actions, making it portable if the project goes public on GitHub later.
|
||||
|
||||
## Context
|
||||
|
||||
- Gitea is already running on Unraid behind Nginx Proxy Manager (`gitea.nerdboden.de`)
|
||||
- Images are currently built locally and pushed to the Gitea container registry via `deploy.sh`
|
||||
- A Gitea Actions runner is already deployed on Unraid and connected to the Gitea instance
|
||||
- The workflow syntax is compatible with GitHub Actions, so the same `.github/workflows/` files work on both platforms
|
||||
|
||||
## Checklist
|
||||
|
||||
- [x] **Enable Gitea Actions on the Gitea instance** — Actions feature is enabled and runner is connected
|
||||
- [x] **Set up a Gitea Actions runner** — `act_runner` is deployed on Unraid and registered with Gitea
|
||||
- [x] **Create CI workflow** (`.github/workflows/ci.yml`) — on push to `develop` and PRs: run `ruff check` + `ruff format --check` for backend, `eslint` + `tsc` for frontend. Tests can be added later when they exist.
|
||||
- [x] **Create deploy workflow** (`.github/workflows/deploy.yml`) — triggered via `workflow_dispatch` on `main`: build Docker images (linux/amd64), push to the Gitea container registry, deploy to Unraid via SSH (`docker compose pull && docker compose up -d`)
|
||||
- [x] **Configure secrets in Gitea** — generate a new SSH keypair, add the public key to Unraid root user's `authorized_keys`, add the private key as a Gitea repo secret (`DEPLOY_SSH_KEY`). Also add any registry credentials or other sensitive values the workflows need.
|
||||
- [x] **Test the full pipeline** — push a change through `feature/*` → `develop` (verify CI runs), then merge `develop` → `main` and trigger the deploy workflow via `workflow_dispatch` to verify end-to-end
|
||||
- [x] **Update deployment docs** — document the Gitea Actions setup, how to manage the runner, and how CI/CD fits into the deployment workflow
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
# nuzlocke-tracker-jq50
|
||||
title: Add ability to end a run (success/failure)
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-06T10:22:00Z
|
||||
updated_at: 2026-02-07T12:12:42Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Add functionality to mark a Nuzlocke run as completed (success) or failed.
|
||||
|
||||
## Requirements
|
||||
|
||||
1. **Run status transitions**:
|
||||
- Active → Completed (player beat the game)
|
||||
- Active → Failed (all Pokemon fainted / player gave up)
|
||||
|
||||
2. **UI elements needed**:
|
||||
- "End Run" button on run dashboard
|
||||
- Confirmation modal with success/failure choice
|
||||
- Optional: Add notes/summary when ending
|
||||
- Display completion status prominently on ended runs
|
||||
|
||||
3. **Backend**:
|
||||
- Endpoint already supports status update via PATCH /runs/{id}
|
||||
- May need to set `completedAt` timestamp when ending
|
||||
|
||||
4. **Considerations**:
|
||||
- Should ended runs be editable? (probably lock encounters)
|
||||
- Show run duration (started → completed)
|
||||
- Victory/defeat visual treatment (colors, icons)
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-jrbc
|
||||
title: Fix doubled encounters in EncounterModal
|
||||
status: completed
|
||||
type: bug
|
||||
priority: normal
|
||||
created_at: 2026-02-08T11:16:35Z
|
||||
updated_at: 2026-02-08T11:17:25Z
|
||||
---
|
||||
|
||||
EncounterModal calls useRoutePokemon without gameId, so route encounters for all games in the version group are returned. Pass gameId through from RunEncounters.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# nuzlocke-tracker-jzqz
|
||||
title: Configure Portainer API for automated redeployment
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-09T15:30:45Z
|
||||
updated_at: 2026-02-09T17:28:22Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
blocking:
|
||||
- nuzlocke-tracker-hwyk
|
||||
---
|
||||
|
||||
Use the Portainer CE REST API to trigger stack redeployments from the deploy script.
|
||||
|
||||
Portainer webhooks are a Business-only feature, so we use the API directly instead.
|
||||
|
||||
## Approach
|
||||
|
||||
1. Authenticate with the Portainer API to get a JWT token
|
||||
2. Call the stack update endpoint with `pullImage: true` to pull latest images and recreate containers
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Identify the stack ID in Portainer (via API or UI)
|
||||
- [ ] Test API authentication (`POST /api/auth`)
|
||||
- [ ] Test triggering a stack redeploy via API
|
||||
- [ ] Integrate into the deploy script
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
# nuzlocke-tracker-jzw4
|
||||
title: Switch prod compose to bind mounts for persistent data
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-10T08:15:41Z
|
||||
updated_at: 2026-02-10T08:16:44Z
|
||||
parent: nuzlocke-tracker-ahza
|
||||
---
|
||||
|
||||
Replace named Docker volume with bind mount to ./data/postgres subfolder. The docker-compose.prod.yml will live at /mnt/user/appdata/nuzlocke-tracker/ on Unraid, so relative paths resolve to subfolders there.
|
||||
34
.beans/nuzlocke-tracker-k5lm--pokemon-game-database.md
Normal file
34
.beans/nuzlocke-tracker-k5lm--pokemon-game-database.md
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# nuzlocke-tracker-k5lm
|
||||
title: Initial Game Data Seeding
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:44:12Z
|
||||
updated_at: 2026-02-05T13:37:50Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
---
|
||||
|
||||
Create seed data for the database with initial games, routes, and Pokémon.
|
||||
|
||||
## Checklist
|
||||
- [x] Research and compile data for MVP games:
|
||||
- [x] Pokémon FireRed/LeafGreen (Gen 3 Kanto remakes - popular for Nuzlockes)
|
||||
- [x] Pokémon Emerald (Gen 3 Hoenn)
|
||||
- [x] Pokémon HeartGold/SoulSilver (Gen 4 Johto remakes)
|
||||
- [x] For each game, gather:
|
||||
- [x] All routes/areas in progression order
|
||||
- [x] Available wild Pokémon per route
|
||||
- [x] Encounter methods (grass, surf, fish, etc.)
|
||||
- [x] Create seed scripts/migrations to populate database
|
||||
- [x] Include Pokémon base data (national dex, names, types, sprite URLs)
|
||||
- [x] Document data sources for attribution
|
||||
- [x] Curate route ordering to match game progression — split to nuzlocke-tracker-j28y
|
||||
|
||||
## Notes
|
||||
- Admin panel allows adding more games later
|
||||
- Focus on accuracy for the 3 MVP games
|
||||
|
||||
## Data Sources
|
||||
- Game data (routes, encounters, Pokemon): [PokeAPI](https://pokeapi.co/) via [pokebase](https://github.com/PokeAPI/pokebase) Python wrapper
|
||||
- Sprites: [PokeAPI/sprites](https://github.com/PokeAPI/sprites) on GitHub
|
||||
11
.beans/nuzlocke-tracker-k60g--rewrite-fetch-pokeapi-in-go.md
Normal file
11
.beans/nuzlocke-tracker-k60g--rewrite-fetch-pokeapi-in-go.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-k60g
|
||||
title: Rewrite fetch_pokeapi in Go
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T15:38:58Z
|
||||
updated_at: 2026-02-07T15:44:25Z
|
||||
---
|
||||
|
||||
Rewrite the Python PokeAPI fetching tool in Go with custom HTTP client, disk caching, and zero external dependencies. Replace aiopoke dependency that crashes on newer PokeAPI fields.
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
# nuzlocke-tracker-k7ot
|
||||
title: Genlocke management in admin panel
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-09T08:38:13Z
|
||||
updated_at: 2026-02-09T09:51:51Z
|
||||
parent: nuzlocke-tracker-25mh
|
||||
---
|
||||
|
||||
Add genlocke management to the admin panel, allowing admins to view, edit, and delete genlockes and their legs.
|
||||
|
||||
## Admin Pages
|
||||
|
||||
### Genlocke List (`/admin/genlockes`)
|
||||
- Table of all genlockes: name, status, number of legs, created date
|
||||
- Status badge (active / completed / failed)
|
||||
- Click to view/edit details
|
||||
- Delete button with confirmation
|
||||
|
||||
### Genlocke Detail (`/admin/genlockes/:genlockeId`)
|
||||
- Edit genlocke name and status
|
||||
- View and manage legs: reorder, add, remove
|
||||
- Change the game assigned to a leg
|
||||
- View linked runs (with links to admin run detail)
|
||||
- Delete genlocke with cascade confirmation
|
||||
|
||||
## Backend
|
||||
- `GET /api/v1/genlockes` — List all genlockes with legs (may already exist from overview page bean)
|
||||
- `GET /api/v1/genlockes/{id}` — Get full genlocke detail
|
||||
- `PATCH /api/v1/genlockes/{id}` — Update genlocke name, status, rules
|
||||
- `DELETE /api/v1/genlockes/{id}` — Delete genlocke and cascade to legs
|
||||
- `POST /api/v1/genlockes/{id}/legs` — Add a leg
|
||||
- `DELETE /api/v1/genlockes/{id}/legs/{legId}` — Remove a leg
|
||||
- `PUT /api/v1/genlockes/{id}/legs/reorder` — Reorder legs
|
||||
|
||||
## Frontend
|
||||
- New admin routes: `/admin/genlockes`, `/admin/genlockes/:genlockeId`
|
||||
- Add "Genlockes" nav item to admin sidebar
|
||||
- Admin list and detail page components
|
||||
- API client functions and hooks for admin CRUD operations
|
||||
|
||||
## Checklist
|
||||
- [x] Implement `GET /api/v1/genlockes` list endpoint
|
||||
- [x] Implement `GET /api/v1/genlockes/{id}` detail endpoint
|
||||
- [x] Implement `PATCH /api/v1/genlockes/{id}` update endpoint
|
||||
- [x] Implement `DELETE /api/v1/genlockes/{id}` delete endpoint
|
||||
- [x] Implement leg management endpoints (add, remove)
|
||||
- [x] Build admin genlocke list page
|
||||
- [x] Build admin genlocke detail/edit page
|
||||
- [x] Add admin routes and sidebar navigation
|
||||
- [x] Add frontend API client and hooks for genlocke admin
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# nuzlocke-tracker-kghn
|
||||
title: Child route management from route detail
|
||||
status: completed
|
||||
type: feature
|
||||
priority: low
|
||||
created_at: 2026-02-08T12:33:53Z
|
||||
updated_at: 2026-02-08T19:31:57Z
|
||||
parent: nuzlocke-tracker-iu5b
|
||||
---
|
||||
|
||||
Allow adding/editing/deleting child routes (sub-areas) directly from the route detail page, instead of only from the game detail routes tab.
|
||||
|
||||
## Current state
|
||||
- Child routes can only be created from the game detail routes tab
|
||||
- The route detail page shows encounters but doesn't show or manage its children
|
||||
- To add a child route, you navigate away from the route detail back to the game
|
||||
|
||||
## Desired behavior
|
||||
- Route detail page shows a 'Sub-areas' section listing child routes (if any)
|
||||
- Can add new child routes from this view
|
||||
- Can click a child route to navigate to its encounter detail
|
||||
- Can delete child routes from this view
|
||||
|
||||
## Notes
|
||||
- This is lower priority since child routes are typically set up once during initial data entry and rarely changed afterward.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
# nuzlocke-tracker-kvmd
|
||||
title: Boss Battles, Level Caps & Badges
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T20:16:14Z
|
||||
updated_at: 2026-02-08T11:23:58Z
|
||||
---
|
||||
|
||||
Add boss battle tracking (Gym Leaders, Elite Four, Champion, rivals), badge progression, and level cap enforcement to the nuzlocke tracker.
|
||||
|
||||
## Context
|
||||
|
||||
The `levelCaps` rule toggle exists but has no data or enforcement behind it. Boss battles are core progression milestones in any nuzlocke run — defeating them earns badges, unlocks level cap increases, and marks key story moments. This feature adds the data model, import tooling, and UI to support all of this.
|
||||
|
||||
## Data Model
|
||||
|
||||
### `BossBattle` (new model, per-game)
|
||||
- `id`, `game_id` (FK)
|
||||
- `name` (e.g. "Brock", "Cynthia", "Rival 1")
|
||||
- `boss_type` — `gym_leader`, `elite_four`, `champion`, `rival`, `evil_team`, `other`
|
||||
- `badge_name` (nullable, e.g. "Boulder Badge" — only for gym leaders)
|
||||
- `level_cap` (SmallInteger — highest level on their team, used for level caps rule)
|
||||
- `order` (SmallInteger — progression order within the game)
|
||||
- `location` (string — where the fight happens, e.g. "Pewter City Gym")
|
||||
- `sprite_url` (nullable — trainer sprite)
|
||||
|
||||
### `BossPokemon` (new model, pokemon on a boss's team)
|
||||
- `id`, `boss_battle_id` (FK)
|
||||
- `pokemon_id` (FK)
|
||||
- `level` (SmallInteger)
|
||||
- `order` (SmallInteger — slot order)
|
||||
|
||||
### `BossResult` (new model, per-run tracking of boss outcomes)
|
||||
- `id`, `run_id` (FK), `boss_battle_id` (FK)
|
||||
- `result` — `won`, `lost`
|
||||
- `attempts` (int, default 1)
|
||||
- `deaths` — list of encounter IDs that died during this fight (optional JSON or relation)
|
||||
- `completed_at` (datetime)
|
||||
|
||||
## Checklist
|
||||
|
||||
### Backend
|
||||
- [x] Migration: Create `boss_battles`, `boss_pokemon`, and `boss_results` tables
|
||||
- [x] Models: `BossBattle`, `BossPokemon`, `BossResult`
|
||||
- [x] Schemas: Create/Response schemas for all three models
|
||||
- [x] API: CRUD endpoints for `boss_battles` (admin — per game)
|
||||
- [x] API: `GET /games/{game_id}/bosses` — list all bosses for a game with their pokemon teams
|
||||
- [x] API: `POST /runs/{run_id}/boss-results` — log a boss fight result
|
||||
- [x] API: `GET /runs/{run_id}/boss-results` — get all boss results for a run
|
||||
- [x] API: `GET /runs/{run_id}/level-cap` — level cap calculated client-side from bosses list
|
||||
- [x] Bulk import endpoint or script for boss data — managed via admin UI + export endpoint
|
||||
|
||||
### Frontend
|
||||
- [x] Types: `BossBattle`, `BossPokemon`, `BossResult` interfaces
|
||||
- [x] API + hooks: Fetch bosses, log results, get level cap
|
||||
- [x] Boss progression section on RunEncounters page — show next boss, badges earned, level cap
|
||||
- [x] Badge display: row of earned/unearned badge icons (greyed out until defeated)
|
||||
- [x] Level cap indicator: show current cap prominently when `levelCaps` rule is on, highlight team members over the cap
|
||||
- [x] Boss battle log modal: record fight result, mark deaths that occurred during the fight
|
||||
- [x] Boss detail view: show boss's team with pokemon sprites and levels
|
||||
|
||||
### Data
|
||||
- [x] Seed boss data for at least one game — managed via admin UI
|
||||
65
.beans/nuzlocke-tracker-kz5g--genlocke-creation-wizard.md
Normal file
65
.beans/nuzlocke-tracker-kz5g--genlocke-creation-wizard.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
# nuzlocke-tracker-kz5g
|
||||
title: Genlocke creation wizard
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-09T07:42:10Z
|
||||
updated_at: 2026-02-09T08:23:53Z
|
||||
parent: nuzlocke-tracker-25mh
|
||||
blocking:
|
||||
- nuzlocke-tracker-x4p6
|
||||
- nuzlocke-tracker-thbz
|
||||
---
|
||||
|
||||
Multi-step wizard UI for creating a new genlocke. This is the entry point for the entire genlocke feature.
|
||||
|
||||
## Steps
|
||||
|
||||
### Step 1: Name
|
||||
- User enters a name for the genlocke (e.g., "My First Genlocke")
|
||||
|
||||
### Step 2: Game Selection
|
||||
- Offer preset templates:
|
||||
- **True Genlocke** — slots for each region using original releases only
|
||||
- **Normal Genlocke** — slots for each region using the latest remake/enhanced version as the default pick
|
||||
- **Custom** — start with an empty list, add games freely
|
||||
- For preset templates, show one slot per region (Kanto, Johto, Hoenn, Sinnoh, Unova, Kalos, Alola, Galar, Paldea). Each slot shows available games for that region and lets the user pick one.
|
||||
- The user can add/remove/reorder legs after selecting a template.
|
||||
- Games are grouped by region (FireRed is a "Kanto" option, not "Gen 3").
|
||||
|
||||
### Step 3: Rules
|
||||
- **Nuzlocke rules** — standard rules configuration (reuse existing `RulesConfiguration` component). Set once, applied to all legs.
|
||||
- **Genlocke rules** — Keep HoF (default) vs Retire HoF. Radio select.
|
||||
|
||||
### Step 4: Confirm & Start
|
||||
- Summary of the genlocke: name, legs in order, rules.
|
||||
- "Start Genlocke" button creates the Genlocke entity, all GenlockeLeg records, and auto-creates + starts the first NuzlockeRun.
|
||||
|
||||
## Backend
|
||||
- `POST /api/v1/genlockes` — Create a genlocke with all legs and rules in one request. Should create the Genlocke, GenlockeLeg records, and the first NuzlockeRun.
|
||||
- Needs the `Genlocke` and `GenlockeLeg` database models + migration.
|
||||
|
||||
## Frontend
|
||||
- New route: `/genlockes/new`
|
||||
- Multi-step form component with back/next navigation
|
||||
- Reuse `GameCard`/`GameGrid` components for game selection
|
||||
- Reuse `RulesConfiguration` for nuzlocke rules step
|
||||
|
||||
## Dependencies
|
||||
- Needs generation/region metadata to power the preset templates (see nuzlocke-tracker-glh8)
|
||||
|
||||
## Checklist
|
||||
- [x] Create `Genlocke` SQLAlchemy model (name, status, genlocke_rules JSONB, nuzlocke_rules JSONB, created_at)
|
||||
- [x] Create `GenlockeLeg` SQLAlchemy model (genlocke_id FK, run_id FK nullable, leg_order, game_id FK)
|
||||
- [x] Create Alembic migration for both new tables
|
||||
- [x] Create Pydantic schemas for genlocke creation request/response
|
||||
- [x] Implement `POST /api/v1/genlockes` endpoint (creates genlocke, legs, and first run)
|
||||
- [x] Build the multi-step wizard shell component with back/next navigation and step indicator
|
||||
- [x] Build Step 1: Name input
|
||||
- [x] Build Step 2: Preset template selector (True / Normal / Custom) with region-grouped game picker
|
||||
- [x] Build Step 3: Rules configuration (reuse `RulesConfiguration` + genlocke rules radio)
|
||||
- [x] Build Step 4: Confirmation summary with "Start Genlocke" action
|
||||
- [x] Add `/genlockes/new` route to the React Router config
|
||||
- [x] Add TypeScript types for genlocke API responses
|
||||
- [x] Wire up the wizard to call the create endpoint and redirect to the genlocke overview on success
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# nuzlocke-tracker-kzd9
|
||||
title: Add option to randomize encounters
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-07T21:08:27Z
|
||||
updated_at: 2026-02-08T19:07:52Z
|
||||
---
|
||||
|
||||
Add an option to randomly select 1 Pokemon per location/encounter. This is primarily for open-world games (like Legends: Arceus, Legends: Z-A) where Pokemon are visible in the overworld rather than found through random encounters, but could also be used for other games.
|
||||
|
||||
## Checklist
|
||||
- [ ] Add UI toggle or button to randomize encounters when starting or managing a run
|
||||
- [ ] Implement random selection logic: pick 1 Pokemon per location from the available encounter list
|
||||
- [ ] Ensure the randomized selection respects existing Nuzlocke rules (dupes clause, etc.)
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# nuzlocke-tracker-l272
|
||||
title: Add boss data to seed files for all games
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-11T20:23:20Z
|
||||
updated_at: 2026-02-11T20:31:27Z
|
||||
---
|
||||
|
||||
Add gym leaders, Elite Four, champions and equivalents for all remaining games. Add kahuna and totem boss types for Alola games. Create 11 new seed files, complete 2 existing ones, and update frontend types/UI for new boss types.
|
||||
41
.beans/nuzlocke-tracker-l7e3--database-schema-design.md
Normal file
41
.beans/nuzlocke-tracker-l7e3--database-schema-design.md
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
# nuzlocke-tracker-l7e3
|
||||
title: Database Schema Design
|
||||
status: completed
|
||||
type: task
|
||||
priority: normal
|
||||
created_at: 2026-02-04T15:46:54Z
|
||||
updated_at: 2026-02-05T12:29:19Z
|
||||
parent: nuzlocke-tracker-f5ob
|
||||
blocking:
|
||||
- nuzlocke-tracker-bkhs
|
||||
- nuzlocke-tracker-k5lm
|
||||
- nuzlocke-tracker-hy41
|
||||
---
|
||||
|
||||
Design and implement the database schema for persistent storage.
|
||||
|
||||
## Decisions
|
||||
- **Database**: PostgreSQL 16 (already in docker-compose)
|
||||
- **ORM**: SQLAlchemy 2.0 (async) with asyncpg driver
|
||||
- **Migrations**: Alembic
|
||||
- **Async**: Full async — asyncpg + async SQLAlchemy sessions
|
||||
|
||||
## Checklist
|
||||
- [x] Choose database (PostgreSQL)
|
||||
- [x] Set up database connection and ORM/query builder (SQLAlchemy 2.0 async + asyncpg)
|
||||
- [x] Design and create tables/collections:
|
||||
- [x] Games (id, name, slug, generation, region, box_art_url, release_year)
|
||||
- [x] Routes (id, name, game_id, order)
|
||||
- [x] Pokemon (id, national_dex, name, types[], sprite_url)
|
||||
- [x] RouteEncounters (id, route_id, pokemon_id, encounter_method, encounter_rate) — unique(route, pokemon, method)
|
||||
- [x] NuzlockeRuns (id, game_id, name, status, rules jsonb, started_at, completed_at)
|
||||
- [x] Encounters (id, run_id, route_id, pokemon_id, nickname, status, catch_level, faint_level, caught_at)
|
||||
- [x] Set up migrations system (Alembic)
|
||||
- [ ] Add seed data for initial games/routes/Pokémon
|
||||
- [x] Create indexes for common queries (FK indexes on routes, route_encounters, nuzlocke_runs, encounters; status index on nuzlocke_runs)
|
||||
|
||||
## Notes
|
||||
- Use foreign keys for referential integrity
|
||||
- Status fields should be enums
|
||||
- Use PostgreSQL enums or check constraints for status/type fields
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# nuzlocke-tracker-lab1
|
||||
title: Add version_groups table, share routes & boss battles across version groups
|
||||
status: completed
|
||||
type: feature
|
||||
priority: normal
|
||||
created_at: 2026-02-08T10:39:00Z
|
||||
updated_at: 2026-02-08T10:46:43Z
|
||||
---
|
||||
|
||||
Introduce version_groups table and re-parent routes and boss_battles from game_id to version_group_id. Add game_id to route_encounters for per-game encounter data.
|
||||
|
||||
## Checklist
|
||||
- [x] Phase 1: Backend models (VersionGroup, Game, Route, RouteEncounter, BossBattle)
|
||||
- [x] Phase 2: Alembic migration
|
||||
- [x] Phase 3: Backend schemas
|
||||
- [x] Phase 4: Backend API updates
|
||||
- [x] Phase 5: Seed loader updates
|
||||
- [x] Phase 6: Frontend type/API/hook updates
|
||||
- [x] Verification: migration runs, TypeScript compiles
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user