Files
nuzlocke-tracker/.beans/nuzlocke-tracker-g8zi--fix-pokemon-form-identification-separate-pokeapi-i.md
Julian Tabel d168d99bba Separate PokeAPI ID from national dex for correct form identification
Pokemon forms (e.g., Alolan Rattata) had their PokeAPI ID (10091) stored as
national_dex, causing them to display incorrectly. This renames the unique
identifier to pokeapi_id and adds a real national_dex field shared between
forms and their base species, so Alolan Rattata correctly shows as #19.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:55:06 +01:00

50 lines
2.7 KiB
Markdown

---
# 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.