Commit Graph

123 Commits

Author SHA1 Message Date
f6bcb1fbe5 Fix CI failures for backend and e2e test jobs
Some checks failed
CI / backend-tests (push) Failing after 9s
CI / frontend-tests (push) Successful in 27s
CI / e2e-tests (push) Failing after 2m6s
Replace astral-sh/setup-uv action with direct curl install to avoid
Node.js 18 incompatibility (setup-uv v6+ requires Node 20+). Change
e2e test API host port from 8000 to 8100 to avoid conflict with
existing service on the CI runner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:29:04 +01:00
9aaa95a1c7 Add component tests for EndRunModal, GameGrid, RulesConfiguration, Layout
33 tests covering rendering, user interactions (userEvent clicks), prop
callbacks, filter state, and conditional description text. Adds a
matchMedia stub to the vitest setup file so components importing
useTheme don't throw in jsdom. Also adds actionlint and zizmor
pre-commit hooks for GitHub Actions linting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:57:12 +01:00
0d2f419c6a Add unit tests for frontend utilities and hooks
82 tests covering download.ts and all React Query hooks. API modules are
mocked with vi.mock; mutation tests spy on queryClient.invalidateQueries
to verify cache invalidation. Conditional queries (null id) are verified
to stay idle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:47:55 +01:00
c80d7d0802 Set up frontend test infrastructure
Install @testing-library/react, @testing-library/jest-dom,
@testing-library/user-event, and jsdom. Configure Vitest with globals,
jsdom environment, and a setup file importing jest-dom matchers. Add a
custom render helper wrapping components with QueryClientProvider and
MemoryRouter. Exclude e2e/ from vitest. Smoke test covers
formatEvolutionMethod.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:35:15 +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
ed1f7ad3d0 Increase encounter method badge sizes for readability
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
Bump xs from 8px to 10px and sm from 9px to 12px so the route-list
badges (Grass, Surfing, Gift, etc.) are legible at a glance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:35:54 +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
e25d1cf24c Remove unused nuzlocke rules, reorganize into core and playstyle
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
Remove firstEncounterOnly, permadeath, nicknameRequired, and
postGameCompletion from the rules system — they are either implicit
(it's a nuzlocke tracker) or not enforced. Move levelCaps to core
(it's displayed in the sticky bar). Create a new "playstyle" category
for hardcoreMode and setModeOnly — informational rules useful for
stats but not enforced by the tracker. Remove the completion category
entirely. Add sub-task beans for the rules overhaul epic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:20:23 +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
a12478f24b Fix e2e tests for ESM and podman-compose compatibility
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
Replace __dirname with import.meta.url (required by "type": "module").
Replace --wait flag with manual health polling (unsupported by
podman-compose). Use explicit -p project name to isolate test
containers from dev environment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:19:17 +01:00
a7ec49fcad Add Playwright accessibility and mobile layout e2e tests
All checks were successful
CI / backend-lint (push) Successful in 49s
CI / actions-lint (push) Successful in 15s
CI / frontend-lint (push) Successful in 1m2s
Set up end-to-end test infrastructure with Docker Compose test
environment, Playwright config, and automated global setup/teardown
that seeds a test database and creates fixtures via the API.

Tests cover 11 pages across both dark/light themes for WCAG 2.0 AA
accessibility (axe-core), and across 3 viewports (mobile, tablet,
desktop) for horizontal overflow and touch target validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:08:17 +01:00
a381633413 Add dark/light mode toggle with adaptive badge colors
Implement theme switching via sun/moon toggle in nav bar. Dark
remains the default; light mode overrides surface, text, border,
accent, and status color tokens. Preference persists in localStorage
and falls back to prefers-color-scheme. An inline script in
index.html prevents flash of wrong theme on load.

Define a Tailwind v4 @custom-variant for light mode and update all
badge components (encounter method, rule, condition) to use
light:bg-{color}-100 / light:text-{color}-700 for readable contrast
on light surfaces.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:45:12 +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
eff67a0ad5 Add new Boss sprites
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / frontend-lint (push) Successful in 33s
2026-02-14 22:15:57 +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
c4ed232996 Refine seed data: route ordering and boss configs up to gen 8 (WIP)
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / frontend-lint (push) Successful in 31s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 16:28:27 +01:00
bb3794a276 Update Cilan/Chill/Cress sprite
All checks were successful
CI / backend-lint (push) Successful in 8s
CI / frontend-lint (push) Successful in 30s
2026-02-14 13:11:06 +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
7a4d5d26b5 Update Seed data (Gen1-3)
All checks were successful
CI / backend-lint (push) Successful in 8s
CI / frontend-lint (push) Successful in 32s
2026-02-13 15:41:15 +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
Julian Tabel
29a5c84651 Fix footer floating mid-page on short content pages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 13:59:18 +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
174b145e84 Fix webp sprites not loading in production nginx
All checks were successful
CI / backend-lint (push) Successful in 7s
CI / frontend-lint (push) Successful in 30s
Include mime.types at the server block level to ensure .webp files
are served with the correct Content-Type (image/webp).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 13:23:58 +01:00
Julian Tabel
42764b2485 Add sprites 2026-02-11 13:02:18 +01:00
5151be785b feature/pokedb-attribution (#5)
All checks were successful
CI / backend-lint (push) Successful in 7s
CI / frontend-lint (push) Successful in 29s
Co-authored-by: Julian Tabel <julian.tabel@synvert.com>
Reviewed-on: TheFurya/nuzlocke-tracker#5
2026-02-10 16:01:14 +01:00
Julian Tabel
03b5572429 Clean up frontend branding and metadata
All checks were successful
CI / backend-lint (pull_request) Successful in 7s
CI / frontend-lint (pull_request) Successful in 31s
Replace Vite defaults with Nuzlocke Tracker branding: custom pokeball-
skull favicon (SVG + PNG + ICO), page title, meta description, Open
Graph tags, theme-color, web manifest, and package.json name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:44:09 +01:00
Julian Tabel
e4111c67bc Fix linting errors across backend and frontend
All checks were successful
CI / backend-lint (push) Successful in 7s
CI / frontend-lint (push) Successful in 29s
Backend: auto-fix and format all ruff issues, manually fix B904/B023/
SIM117/B007/E741/F841 errors, suppress B008 (FastAPI Depends) and F821
(SQLAlchemy forward refs) in config. Frontend: allow constant exports,
disable React compiler-specific rules (set-state-in-effect,
preserve-manual-memoization).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 12:26:57 +01:00
972137acfb Fix TypeScript errors in frontend build
Cast boss type select value to union type and remove unused
AdvanceLegInput import.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:10:38 +01:00
fd23d89e71 Add production Dockerfiles and nginx config
Backend: installs non-editable, runs uvicorn without reload.
Frontend: multi-stage build, serves static files via nginx with
API proxy to the backend service and SPA fallback routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 18:00:28 +01:00
Julian Tabel
f9f94e5e9c Add post-game completion rule option
Add postGameCompletion toggle to nuzlocke rules so players can indicate
whether a run ends after the Champion or continues into post-game. Adds
a new "Completion" category section in rules configuration with a green
badge color.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 12:24:06 +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