Add naming scheme selection to run configuration

Add a nullable naming_scheme column to NuzlockeRun so users can pick a
themed word category for nickname suggestions. Includes Alembic migration,
updated Pydantic schemas, a GET /runs/naming-categories endpoint backed by
a cached dictionary loader, and frontend dropdowns in both the NewRun
creation flow and the RunDashboard for mid-run changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 21:36:50 +01:00
parent e61fce5f72
commit e324559476
15 changed files with 215 additions and 31 deletions

View File

@@ -3,8 +3,9 @@
title: Integrate name suggestions into encounter registration UI
status: todo
type: task
priority: normal
created_at: 2026-02-11T15:56:44Z
updated_at: 2026-02-11T15:56:44Z
updated_at: 2026-02-11T20:23:40Z
parent: nuzlocke-tracker-igl3
---
@@ -12,17 +13,23 @@ Show name suggestions in the encounter registration flow so users can pick a nic
## Requirements
- When a user clicks an encounter slot and registers a new Pokemon, display 5-10 name suggestions below/near the nickname input
- 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
- [ ] Add a name suggestions component (chips/buttons with regenerate)
- [ ] Integrate the component into the encounter registration modal/form
- [ ] Wire up the name suggestion engine to the component
- [ ] Wire up the backend API endpoint to the component via React Query
- [ ] Ensure clicking a suggestion populates the nickname field
- [ ] Ensure regenerate fetches a new batch without repeating prior suggestions
- [ ] Ensure regenerate fetches a new batch from the API
- [ ] Hide suggestions gracefully if no naming scheme is set on the run

View File

@@ -5,24 +5,32 @@ status: todo
type: task
priority: normal
created_at: 2026-02-11T15:56:44Z
updated_at: 2026-02-11T15:56:48Z
updated_at: 2026-02-11T20:23:35Z
parent: nuzlocke-tracker-igl3
blocking:
- nuzlocke-tracker-bi4e
---
Build the core logic that picks random name suggestions from the dictionary based on a selected naming scheme (category).
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 list of already-used names in the run, return 5-10 unique suggestions
- Suggestions must not include names already assigned to other Pokemon in the same run
- 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
- [ ] Create a service/utility module for name suggestion logic
- [ ] Create a service module for name suggestion logic (e.g. `services/name_suggestions.py`)
- [ ] Implement dictionary loading with in-memory caching
- [ ] Implement random selection from a category with exclusion of used names
- [ ] Implement regeneration that avoids repeating previous suggestions
- [ ] Add API endpoint for fetching suggestions
- [ ] Add unit tests for the suggestion logic

View File

@@ -5,14 +5,22 @@ status: todo
type: epic
priority: normal
created_at: 2026-02-05T13:45:15Z
updated_at: 2026-02-11T15:57:27Z
updated_at: 2026-02-11T20:23:14Z
---
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 tagged with categories (e.g. mythology, food, space, nature, warriors, music, etc.)
- **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.

View File

@@ -1,11 +1,11 @@
---
# nuzlocke-tracker-m86o
title: Add naming scheme selection to run configuration
status: todo
status: in-progress
type: task
priority: normal
created_at: 2026-02-11T15:56:44Z
updated_at: 2026-02-11T15:56:48Z
updated_at: 2026-02-11T20:35:59Z
parent: nuzlocke-tracker-igl3
blocking:
- nuzlocke-tracker-bi4e
@@ -15,14 +15,24 @@ Allow users to select a naming scheme (category) for their Nuzlocke run.
## Requirements
- Add a `namingScheme` field to the run model/settings (optional, nullable — user may not want auto-naming)
- Add a `naming_scheme` column to the NuzlockeRun model (nullable string — user may not want auto-naming)
- Provide a dropdown/selector in run creation and run settings where the user can pick a category
- List available categories dynamically from the dictionary data
- List available categories dynamically by querying a backend endpoint that reads the dictionary file
- Allow changing the naming scheme mid-run
## Implementation Notes
- **Storage**: Dedicated nullable `naming_scheme` column on `NuzlockeRun` (not in the `rules` JSONB). This is a first-class run setting.
- **Migration**: Add an Alembic migration for the new column.
- **API**: Add/update the run creation and update endpoints to accept `namingScheme`.
- **Categories endpoint**: Add a GET endpoint that returns the list of available category names from the dictionary file, so the frontend can populate the dropdown.
## Checklist
- [ ] Add `namingScheme` field to the NuzlockeRun type/model
- [ ] Add naming scheme selector to run creation UI
- [ ] Add naming scheme selector to run settings UI
- [ ] Persist the selected naming scheme with the run data
- [x] Add `naming_scheme` nullable column to NuzlockeRun model
- [x] Create Alembic migration for the new column
- [x] Update run Pydantic schemas to include `namingScheme`
- [x] Update run creation and update endpoints to persist the naming scheme
- [x] Add GET endpoint to list available naming categories from the dictionary
- [x] Add naming scheme selector to run creation UI
- [x] Add naming scheme selector to run settings UI

View File

@@ -5,25 +5,34 @@ status: todo
type: task
priority: normal
created_at: 2026-02-11T15:56:26Z
updated_at: 2026-02-11T15:56:48Z
updated_at: 2026-02-11T20:23:29Z
parent: nuzlocke-tracker-igl3
blocking:
- nuzlocke-tracker-c6ly
---
Create a JSON data file containing themed words for nickname generation.
Create a JSON data file containing themed words for nickname generation, stored in the backend alongside other seed data.
## Requirements
- Each word entry has: `word` (string) and `categories` (string array)
- Store at `backend/src/app/seeds/data/name_dictionary.json`
- Category-keyed structure for fast lookup:
```json
{
"mythology": ["Apollo", "Athena", "Loki", ...],
"space": ["Apollo", "Nova", "Nebula", ...],
"food": ["Basil", "Sage", "Pepper", ...]
}
```
- Words may appear in multiple categories
- Categories should include themes like: mythology, food, space, nature, warriors, music, literature, gems, ocean, weather, etc.
- Target 150-200 words per category
- Words can belong to multiple categories
- Words should be short, punchy, and suitable as Pokemon nicknames (ideally 1-2 words, max ~12 characters)
- This file is NOT seeded into the database — it is read directly by the backend service at runtime
## Checklist
- [ ] Define the data schema / TypeScript type for dictionary entries
- [ ] Create the JSON data file with initial categories
- [ ] Create `backend/src/app/seeds/data/name_dictionary.json` with the category-keyed structure
- [ ] Populate each category with 150-200 words
- [ ] Validate no duplicates exist within the file
- [ ] Validate no duplicates exist within a single category
- [ ] Add a utility function to load the dictionary from disk (with caching)