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>
2.7 KiB
title, status, type, priority, created_at, updated_at, blocking
| title | status | type | priority | created_at | updated_at | blocking | |
|---|---|---|---|---|---|---|---|
| Fix Pokemon form identification: separate PokeAPI ID from national dex | completed | bug | high | 2026-02-07T13:44:25Z | 2026-02-07T13:54:29Z |
|
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:
- Wrong display: Frontend shows "#10091" next to Alolan Rattata instead of "#19"
- Broken sorting: Forms sort at the end of the Pokemon list instead of next to their base species
- 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:
SmallIntegercolumn withUNIQUEconstraint (alembic/versions/03e5f186a9d5) - Models:
pokemon.py—mapped_column(SmallInteger, unique=True) - Seeder:
loader.py— upsert conflict resolution onnational_dex, builds{national_dex: id}mapping for linking encounters and evolutions - Seed data:
fetch_pokeapi.py— uses PokeAPI pokemon ID asnational_dexfor both base species and forms - API: All CRUD operations key on
national_dex, returned asnationalDexin JSON - Frontend: Displayed as
#nationalDexin 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_idcolumn (unique, not null), changenational_dexunique constraint to non-unique - Update Pokemon model to add
pokemon_idfield - Update seed data:
pokemon.jsonentries get bothpokemon_id(PokeAPI ID) andnational_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 onpokemon_idinstead ofnational_dex, update encounter/evolution linking - Update API schemas and endpoints to expose both fields
- Update frontend to display real
national_dexbut usepokemon_idinternally for uniqueness - Update encounter seed data to reference
pokemon_idinstead ofnational_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.