Commit Graph

90 Commits

Author SHA1 Message Date
4d6e1dc5b2 feat: make level field optional in boss defeat modal
All checks were successful
CI / backend-tests (pull_request) Successful in 29s
CI / frontend-tests (pull_request) Successful in 39s
Remove the level input from the boss defeat modal since the app doesn't
track levels elsewhere. Team selection is now just checkboxes without
requiring level entry.

- Remove level input UI from BossDefeatModal.tsx
- Add alembic migration to make boss_result_team.level nullable
- Update model and schemas to make level optional (defaults to null)
- Conditionally render level in boss result display

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 10:16:15 +01:00
3dbc3f35ba feat: make team section a floating sidebar on desktop
Add responsive 2-column layout for the encounters page:
- Desktop (lg, ≥1024px): Encounters on left, team in sticky right sidebar
- Mobile/tablet: Keep current stacked layout

The sidebar scrolls independently when team exceeds viewport height.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 10:11:40 +01:00
50ed370d24 Merge pull request 'Add optional TOTP MFA for email/password accounts' (#76) from feature/optional-totp-mfa into develop
All checks were successful
CI / backend-tests (push) Successful in 31s
CI / frontend-tests (push) Successful in 29s
Reviewed-on: #76
2026-03-22 09:21:33 +01:00
7a828d7215 feat: add optional TOTP MFA for email/password accounts
All checks were successful
CI / backend-tests (pull_request) Successful in 26s
CI / frontend-tests (pull_request) Successful in 28s
- Add MFA enrollment UI in new Settings page with QR code and backup secret
- Add TOTP challenge step to login flow for enrolled users
- Check AAL after login and show TOTP input when aal2 required
- Add disable MFA option with TOTP re-verification
- Only show MFA options for email/password users (not OAuth)
- Add Settings link to user dropdown menu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 13:56:48 +01:00
a3f332f82b feat: show owner info in admin pages
All checks were successful
CI / backend-tests (pull_request) Successful in 29s
CI / frontend-tests (pull_request) Successful in 29s
- Add Owner column to AdminRuns.tsx and AdminGenlockes.tsx
- Add owner filter dropdown to both admin pages
- Add owner field to GenlockeListItem schema (resolved from first leg's run)
- Update frontend types for GenlockeListItem

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 13:38:08 +01:00
3bd24fcdb0 fix: hide edit controls for non-owners in frontend
- Add useAuth and canEdit logic to RunEncounters.tsx
- Guard all mutation triggers (Log Shiny, Log Egg, End Run, Randomize All,
  HoF Edit, Boss Battle, route/team clicks, Advance to Next Leg)
- Update RunDashboard.tsx canEdit to be isOwner only (no unowned fallback)
- Add read-only banner for non-owner viewers in both pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 13:33:04 +01:00
5c10041b8b fix: TypeScript build errors in RunEncounters.tsx
All checks were successful
CI / backend-tests (pull_request) Successful in 27s
CI / frontend-tests (pull_request) Successful in 29s
Use explicit BossResult type instead of indexing potentially undefined
typeof bossResults. Add BossResultTeamMember type to tm parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:25:20 +01:00
3d362a8314 Last weird branch commit
Some checks failed
CI / backend-tests (pull_request) Failing after 1m16s
CI / frontend-tests (pull_request) Successful in 28s
2026-03-20 22:11:39 +01:00
0a519e356e feat: add auth system, boss pokemon details, moves/abilities API, and run ownership
Some checks failed
CI / backend-tests (push) Failing after 1m16s
CI / frontend-tests (push) Successful in 57s
Add user authentication with login/signup/protected routes, boss pokemon
detail fields and result team tracking, moves and abilities selector
components and API, run ownership and visibility controls, and various
UI improvements across encounters, run list, and journal pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:41:38 +01:00
Julian Tabel
088cd35002 add Ko-fi bean
Some checks failed
CI / frontend-tests (push) Has been cancelled
CI / backend-tests (push) Has been cancelled
2026-03-20 16:39:52 +01:00
Julian Tabel
5bd4ca7d3e add Ko-fi bean 2026-03-20 16:38:54 +01:00
Julian Tabel
1cd1389408 Replace playstyle rules with free-text custom rules markdown field
Some checks failed
CI / backend-tests (push) Successful in 28s
CI / frontend-tests (push) Failing after 28s
Remove hardcoreMode, setModeOnly, and bossTeamMatch toggles which had
no mechanical impact on the tracker. Replace them with a customRules
markdown field so users can document their own rules (especially useful
for genlockes). Add react-markdown + remark-gfm for rendering and
@tailwindcss/typography for prose styling. The custom rules display is
collapsible and hidden by default.

Also simplifies the BossDefeatModal by removing the Lost result and
attempts counter, and always shows boss team size in the level cap bar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:09:02 +01:00
Julian Tabel
535154a056 Allow multiple games per region in Custom genlocke
All checks were successful
CI / backend-tests (push) Successful in 25s
CI / frontend-tests (push) Successful in 27s
In custom mode, the region picker no longer filters out already-used
regions, letting users add multiple legs from the same region (e.g.
Black + Black 2 in Unova). Preset modes keep the one-per-region
behavior. Already-used regions show a subtle dot indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:32:42 +01:00
993ad09d9c Add type restriction rule (monolocke)
All checks were successful
CI / backend-lint (push) Successful in 10s
CI / actions-lint (push) Successful in 14s
CI / frontend-lint (push) Successful in 22s
Adds allowedTypes: string[] to NuzlockeRules. When set, the encounter
selector hides non-matching Pokemon and the routes endpoint filters out
routes with no matching encounters, so only eligible locations appear.

Type picker UI in RulesConfiguration; active restriction shown in
RuleBadges. Backend accepts allowed_types query param and joins through
RouteEncounter.pokemon to filter by type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:22:05 +01:00
85fef68dae Add static clause rule for encounter selector filtering
All checks were successful
CI / backend-lint (push) Successful in 10s
CI / actions-lint (push) Successful in 15s
CI / frontend-lint (push) Successful in 23s
When disabled, static encounters (legendaries, scripted Pokémon) are
grayed out and unselectable in the encounter selector. Enabled by default.
Adds 'static' to METHOD_CONFIG/METHOD_ORDER with a teal badge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:04:39 +01:00
347c25e8ed Add boss team match playstyle rule
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 16s
CI / frontend-lint (push) Successful in 21s
When enabled, the sticky boss banner shows the next boss's team size
as a hint for players who voluntarily match the boss's party count.
Handles variant boss teams by using the auto-detected starter variant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:03:11 +01:00
6968d35a33 Fix boss banner sticking behind nav header on scroll
The sticky level cap banner had z-10 and top-0, placing it behind the
nav (z-40) and overlapping it. Use top-14 to clear the nav height and
z-30 to layer correctly below the nav but above page content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:59:46 +01:00
18cc116348 Add gift clause rule for free gift encounters
When enabled, in-game gift Pokemon (starters, trades, fossils) do not
count against a location's encounter limit. Both a gift encounter and
a regular encounter can coexist on the same route, in any order.

Persists encounter origin on the Encounter model so the backend can
exclude gift encounters from route-lock checks bidirectionally, and the
frontend can split them into a separate display layer that doesn't lock
the route for regular encounters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:55:16 +01:00
2298c32691 Add egglocke, wonderlocke, and randomizer variant rules
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 14s
CI / frontend-lint (push) Successful in 21s
When any variant rule is enabled, the encounter modal switches from
the game's regional dex to an all-Pokemon search (same debounced
API pattern as EggEncounterModal). A new "Run Variant" section in
rules configuration groups these rules, and badges render in amber.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:33:01 +01:00
4fbfcf9b29 Fix WCAG AA color contrast violations across all pages
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 15s
CI / frontend-lint (push) Successful in 21s
Replace incorrect perceived-brightness formula in Stats progress bars
with proper WCAG relative luminance calculation, and convert type bar
colors to hex values for reliable contrast detection. Add light: variant
classes to status badges, yellow/purple text, and admin nav links across
17 files. Darken light-mode status-active token and text-tertiary/muted
tokens. Add aria-labels to admin filter selects and flex-wrap for mobile
overflow on AdminEvolutions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:48:16 +01:00
92dad22981 Simplify modal, badge, and component styles to dark-first (#29)
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 16s
CI / frontend-lint (push) Successful in 20s
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-02-17 21:08:53 +01:00
42b66ee9a2 Implement dark-first design system with Geist typography (#28)
All checks were successful
CI / backend-lint (push) Successful in 10s
CI / actions-lint (push) Successful in 16s
CI / frontend-lint (push) Successful in 21s
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-02-17 20:48:42 +01:00
e3b3dc5317 Rebrand to Another Nuzlocke Tracker (ANT) (#27)
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 14s
CI / frontend-lint (push) Successful in 21s
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-02-17 20:17:07 +01:00
7df56325a8 Add per-condition encounter rates to seed data (#26)
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 15s
CI / frontend-lint (push) Successful in 20s
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-02-17 19:38:29 +01:00
8f4ee8f239 Add condition badges for boss Pokemon mechanics
Some checks failed
CI / backend-lint (push) Failing after 9s
CI / actions-lint (push) Failing after 7s
CI / frontend-lint (push) Successful in 21s
Show colored pill badges (Mega, G-Max, D-Max, Tera) on boss Pokemon
in BossDefeatModal and BossTeamPreview. Starter-dependent condition
labels are ignored. Follows EncounterMethodBadge pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 21:17:32 +01:00
3a64661760 Align repo config with global development standards
Some checks failed
CI / backend-lint (push) Failing after 1m4s
CI / actions-lint (push) Failing after 6s
CI / frontend-lint (push) Successful in 59s
- Add missing tsconfig strictness flags (noUncheckedIndexedAccess,
  exactOptionalPropertyTypes, noImplicitOverride,
  noPropertyAccessFromIndexSignature) and fix all resulting type errors
- Replace ESLint/Prettier with oxlint 1.48.0 and oxfmt 0.33.0
- Pin all frontend and backend dependencies to exact versions
- Pin GitHub Actions to SHA hashes with persist-credentials: false
- Fix CI Python version mismatch (3.12 -> 3.14) and ruff target-version
- Add vitest 4.0.18 with jsdom environment for frontend testing
- Add ty 0.0.17 for Python type checking (non-blocking in CI)
- Add actionlint and zizmor CI job for workflow linting and security audit
- Add Dependabot config for npm, pip, and github-actions
- Update CLAUDE.md and pre-commit hooks to reflect new tooling
- Ignore Claude Code sandbox artifacts in gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 20:39:41 +01:00
2963f16aa4 Add pre-commit hooks for linting and formatting
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / frontend-lint (push) Successful in 33s
Set up pre-commit framework with ruff (backend) and ESLint/Prettier/tsc
(frontend) hooks to catch issues locally before CI. Auto-format all
frontend files with Prettier to comply with the new check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:41:24 +01:00
ebdc9b2f28 feature/boss-sprites-and-badges (#22)
All checks were successful
CI / backend-lint (push) Successful in 8s
CI / frontend-lint (push) Successful in 32s
Reviewed-on: TheFurya/nuzlocke-tracker#22
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-02-14 11:04:08 +01:00
3412d6c6fd Add naming scheme support for genlockes with lineage-aware suggestions (#20)
All checks were successful
CI / backend-lint (push) Successful in 8s
CI / frontend-lint (push) Successful in 33s
Genlockes can now select a naming scheme at creation time, which is
automatically applied to every leg's run. When catching a pokemon whose
evolution family appeared in a previous leg, the system suggests the
original nickname with a roman numeral suffix (e.g., "Heracles II").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Reviewed-on: TheFurya/nuzlocke-tracker#20
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-02-14 10:00:36 +01:00
Julian Tabel
1b6970a982 Group parent/child routes in admin route table
Visually indent child routes under their parent with tree connectors,
and make dragging a parent move all its children as a unit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:37:35 +01:00
Julian Tabel
867ded8fa2 Add pinwheel, encounters link, and boss position columns to admin tables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:10:28 +01:00
dbddee4d92 Merge branch 'develop' into feature/add-boss-data
Some checks failed
CI / backend-lint (pull_request) Failing after 8s
CI / frontend-lint (pull_request) Successful in 31s
2026-02-11 21:52:41 +01:00
39d18c241e Integrate name suggestions into encounter registration UI
Add clickable suggestion chips below the nickname input in the encounter
modal. Chips are fetched from GET /runs/{id}/name-suggestions via React
Query, shown only when a naming scheme is set. Clicking a chip fills in
the nickname; a regenerate button fetches a fresh random batch. Completes
the Name Generation epic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 21:48:29 +01:00
e324559476 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>
2026-02-11 21:36:50 +01:00
f71db65642 Add Boss list for all games and more boss types
All checks were successful
CI / backend-lint (pull_request) Successful in 8s
CI / frontend-lint (pull_request) Successful in 30s
2026-02-11 21:33:55 +01:00
Julian Tabel
6d955439eb Fix team sort: add to RunEncounters and fix hook ordering
Add sort dropdown to RunEncounters (the encounters page with the
expandable team section) and move all useMemo hooks before early
returns in both RunDashboard and RunEncounters to fix React hook
ordering violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 12:21:07 +01:00
Julian Tabel
bc9bcf4c4b Add sort options to run team overview
Add a dropdown to sort Active Team and Graveyard by route order,
catch level, species name, or national dex number.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 12:11:54 +01:00
Julian Tabel
924efa9073 Show error feedback when run deletion is blocked
Add optional error prop to DeleteConfirmModal and wire it into AdminRuns
so the backend's rejection message is displayed to the user.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 12:07:09 +01:00
Julian Tabel
d3b65e3c79 Add genlocke lineage tracking with aligned timeline view
Implement read-only lineage view that traces Pokemon across genlocke legs
via existing transfer records. Backend walks transfer chains to build
lineage entries; frontend renders them as cards with a column-aligned
timeline grid so leg dots line up vertically across all lineages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:58:38 +01:00
Julian Tabel
4e00e3cad8 Fix HoF display for transfers/shinies and hook ordering
Move alive and hofTeam into useMemo hooks above early returns to fix
React hook ordering violation. Include transfer and shiny encounters
in alive so they appear in the team section and can be selected for
the Hall of Fame.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:45:29 +01:00
Julian Tabel
c2e946f500 Restrict transfers to HoF team and prevent blocking starter route
Transfer modal now only appears when a Hall of Fame team is selected,
using the existing hofTeam data instead of the survivors endpoint.
Without a HoF selection, advance proceeds directly with no transfer step.

Transferred encounters are now a separate category: they appear in their
own "Transferred Pokemon" section, don't occupy route slots in the
encounter map, and don't block the route-lock check (excluded via
genlocke_transfers subquery). The run detail endpoint returns
transferEncounterIds so the frontend can distinguish them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:35:05 +01:00
Julian Tabel
e1dac10d27 Fix run deletion crash and transfer modal initialization error
Run deletion now properly cleans up boss_results, genlocke_transfers,
and genlocke_leg references before deleting the run. Also fix
showTransferModal being referenced before initialization in
RunEncounters by moving its useState declaration above useLegSurvivors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:28:22 +01:00
Julian Tabel
c5910ec75c Add genlocke transfer UI with transfer selection modal and backend support
When advancing to the next genlocke leg, users can now select surviving
Pokemon to transfer. Transferred Pokemon are bred down to their base
evolutionary form and appear as level-1 egg encounters in the next leg.
A GenlockeTransfer record links source and target encounters for lineage tracking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:20:49 +01:00
Julian Tabel
3bd4250305 Add genlocke cumulative graveyard with backend endpoint and UI
Aggregates all fainted encounters across every leg of a genlocke into a
unified graveyard view. Backend serves GET /genlockes/{id}/graveyard with
per-entry leg/game context and summary stats (total deaths, deaths per
leg, deadliest leg). Frontend adds a toggle button on the genlocke detail
page that reveals a filterable/sortable grid of grayscale Pokemon cards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:00:37 +01:00
Julian Tabel
a81a17c485 Add genlocke admin panel with CRUD endpoints and UI
Backend: PATCH/DELETE genlocke, POST/DELETE legs with order
re-numbering. Frontend: admin list page with status filter,
detail page with inline editing, legs table, and stats display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:51:47 +01:00
Julian Tabel
08f6857451 Add genlocke list and detail pages
Add GET /genlockes and GET /genlockes/{id} endpoints with aggregate
encounter/death stats per leg, and a frontend list page at /genlockes
plus a detail page at /genlockes/:genlockeId showing progress timeline,
cumulative stats, configuration, retired families, and quick actions.
Update nav link to point to the list page instead of /genlockes/new.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:39:59 +01:00
Julian Tabel
58d36c4433 Fix hooks order violation in RunEncounters
Move hofTeam useMemo before early returns to comply with Rules of Hooks.
It was placed after the loading/error guards, causing a "rendered more
hooks than during the previous render" crash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:22:54 +01:00
Julian Tabel
08a5e5c621 Add Hall of Fame team selection for completed runs
After marking a run as completed, a modal prompts the player to select
which Pokemon (up to 6) entered the Hall of Fame. The selection is stored
as hof_encounter_ids on the run, displayed in the victory banner, and
can be edited later. This lays the foundation for scoping genlocke
retireHoF to only the actual HoF team.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:19:56 +01:00
Julian Tabel
48b56f9360 Implement Retire HoF (Gauntlet) rule enforcement for genlockes
When retireHoF is enabled, surviving HoF Pokemon and their evolutionary
families are retired at leg advancement and treated as duplicates in all
subsequent legs — both in the encounter modal and bulk randomize.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 10:05:03 +01:00
Julian Tabel
07343e94e2 Add genlocke leg progression with advance endpoint and run context
When a run belonging to a genlocke is completed or failed, the genlocke
status updates accordingly. The run detail API now includes genlocke
context (leg order, total legs, genlocke name). A new advance endpoint
creates the next leg's run, and the frontend shows genlocke-aware UI
including a "Leg X of Y" banner, advance button, and contextual
messaging in the end-run modal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:47:28 +01:00