Commit Graph

159 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
d541b92253 Merge pull request 'chore(deps): update dependency @tanstack/react-query to v5.94.5' (#78) from renovate/tanstack-react-query-5.x into develop
Some checks failed
CI / frontend-tests (push) Has been cancelled
CI / backend-tests (push) Has been cancelled
Reviewed-on: #78
2026-03-22 09:25:37 +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
Renovate Bot
e279fc76ee chore(deps): update dependency @tanstack/react-query to v5.94.5
All checks were successful
CI / backend-tests (pull_request) Successful in 27s
CI / frontend-tests (pull_request) Successful in 28s
2026-03-21 16:01:57 +00: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
7cd3372c7e feat: add Supabase auth config to production Docker setup
All checks were successful
CI / backend-tests (pull_request) Successful in 26s
CI / frontend-tests (pull_request) Successful in 29s
- Pass SUPABASE_JWT_SECRET to backend in docker-compose.prod.yml
- Add build args (VITE_API_URL, VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY)
  to Dockerfile.prod so Vite inlines them at build time
- Pass build args from secrets in deploy workflow
- Add build section to frontend service in docker-compose.prod.yml

No GoTrue container needed in prod — Supabase Cloud hosts the auth
service. The backend only needs the JWT secret to verify tokens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:07:53 +01:00
d1d9a60134 Merge pull request 'chore(deps): update dependency jsdom to v29' (#62) from renovate/jsdom-29.x into develop
All checks were successful
CI / backend-tests (push) Successful in 27s
CI / frontend-tests (push) Successful in 28s
Reviewed-on: #62
2026-03-21 12:04:26 +01:00
Renovate Bot
ecff53ef58 chore(deps): update dependency jsdom to v29
All checks were successful
CI / backend-tests (pull_request) Successful in 27s
CI / frontend-tests (pull_request) Successful in 29s
2026-03-21 11:02:05 +00:00
100d2d72d0 Merge pull request 'chore(deps): update node docker tag to v25' (#65) from renovate/node-25.x into develop
Some checks failed
CI / backend-tests (push) Has been cancelled
CI / frontend-tests (push) Has been cancelled
2026-03-21 12:01:27 +01:00
Renovate Bot
99f2676c15 chore(deps): update dependency @vitejs/plugin-react to v6
All checks were successful
CI / backend-tests (pull_request) Successful in 27s
CI / frontend-tests (pull_request) Successful in 29s
2026-03-21 10:59:05 +00:00
Renovate Bot
e979b875ec chore(deps): update node docker tag to v25
All checks were successful
CI / backend-tests (pull_request) Successful in 28s
CI / frontend-tests (pull_request) Successful in 29s
2026-03-21 10:49:23 +00:00
Renovate Bot
5957ac5558 chore(deps): update dependency vite to v8
All checks were successful
CI / backend-tests (pull_request) Successful in 27s
CI / frontend-tests (pull_request) Successful in 29s
2026-03-21 10:49:08 +00:00
e8ded9184b feat: auth-aware UI and role-based access control (#67)
All checks were successful
CI / backend-tests (push) Successful in 32s
CI / frontend-tests (push) Successful in 29s
## Summary

- Add `is_admin` column to users table with Alembic migration and a `require_admin` FastAPI dependency that protects all admin-facing write endpoints (games, pokemon, evolutions, bosses, routes CRUD)
- Expose admin status to frontend via user API and update AuthContext to fetch/store `isAdmin` after login
- Make navigation menu auth-aware (different links for logged-out, logged-in, and admin users) and protect frontend routes with `ProtectedRoute` and `AdminRoute` components, preserving deep-linking through redirects
- Fix test reliability: `drop_all` before `create_all` to clear stale PostgreSQL enums from interrupted test runs
- Fix test auth: add `admin_client` fixture and use valid UUID for mock user so tests pass with new admin-protected endpoints

## Test plan

- [x] All 252 backend tests pass
- [ ] Verify non-admin users cannot access admin write endpoints (games, pokemon, evolutions, bosses CRUD)
- [ ] Verify admin users can access admin endpoints normally
- [ ] Verify navigation shows correct links for logged-out, logged-in, and admin states
- [ ] Verify `/admin/*` routes redirect non-admin users with a toast
- [ ] Verify `/runs/new` and `/genlockes/new` redirect unauthenticated users to login, then back after auth

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #67
Co-authored-by: Julian Tabel <juliantabel.jt@gmail.com>
Co-committed-by: Julian Tabel <juliantabel.jt@gmail.com>
2026-03-21 11:44:05 +01:00
f7731b0497 Fix local login flow, add new auth epic
Some checks failed
CI / backend-tests (push) Failing after 31s
CI / frontend-tests (push) Successful in 29s
2026-03-21 11:06:53 +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
Renovate Bot
a4f2f52c10 chore(deps): update dependency oxlint to v1.56.0
All checks were successful
CI / backend-tests (pull_request) Successful in 26s
CI / frontend-tests (pull_request) Successful in 27s
2026-03-20 19:03:33 +00:00
b82e55c8de Merge pull request 'chore(deps): update dependency tailwindcss to v4.2.2' (#53) from renovate/tailwindcss-4.x into develop
Some checks failed
CI / backend-tests (push) Has been cancelled
CI / frontend-tests (push) Has been cancelled
Reviewed-on: #53
2026-03-20 19:58:34 +01:00
Renovate Bot
803f5bb8be chore(deps): update dependency vitest to v4.1.0
All checks were successful
CI / backend-tests (pull_request) Successful in 25s
CI / frontend-tests (pull_request) Successful in 27s
CI / backend-tests (push) Successful in 31s
CI / frontend-tests (push) Successful in 28s
2026-03-20 18:02:55 +00:00
Renovate Bot
b9d457d3a1 chore(deps): update dependency tailwindcss to v4.2.2
All checks were successful
CI / backend-tests (pull_request) Successful in 25s
CI / frontend-tests (pull_request) Successful in 27s
2026-03-20 17:02:26 +00: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
6c36cbfe12 chore(errors): Errors
Container for crash and blocker beans created by Talos.

Bean: nuzlocke-tracker-bw1m
2026-03-20 16:39:28 +01:00
Julian Tabel
5bd4ca7d3e add Ko-fi bean 2026-03-20 16:38:54 +01:00
Renovate Bot
634e957bb8 Update dependency oxfmt to v0.41.0
All checks were successful
CI / backend-tests (pull_request) Successful in 24s
CI / frontend-tests (pull_request) Successful in 28s
2026-03-20 15:02:02 +00:00
Renovate Bot
b413f5e4e4 Update dependency node to v24.14.0
Some checks failed
CI / backend-tests (pull_request) Successful in 24s
CI / backend-tests (push) Has been cancelled
CI / frontend-tests (push) Has been cancelled
CI / frontend-tests (pull_request) Successful in 30s
2026-03-20 15:52:17 +01:00
Julian Tabel
77900ba045 Update dependencies from Renovate PRs
All checks were successful
CI / backend-tests (push) Successful in 28s
CI / frontend-tests (push) Successful in 29s
Backend: python-dotenv 1.2.1→1.2.2, sqlalchemy 2.0.46→2.0.48, ty 0.0.17→0.0.24
Frontend: react-router-dom 7.13.0→7.13.1, @tanstack/react-query 5.90.20→5.91.3, @vitejs/plugin-react 5.1.3→5.2.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:26:08 +01:00
Julian Tabel
869d28ab84 remove playstyle section from test
All checks were successful
CI / backend-tests (push) Successful in 28s
CI / frontend-tests (push) Successful in 27s
2026-03-20 15:13:25 +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
4f0f881736 Update remaining FireRed boss sprites
All checks were successful
CI / backend-tests (push) Successful in 25s
CI / frontend-tests (push) Successful in 27s
CI / e2e-tests (push) Successful in 5m29s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:39:14 +01:00
dde20c932b Update Brock and Misty boss sprites
Some checks failed
CI / backend-tests (push) Successful in 26s
CI / frontend-tests (push) Successful in 27s
CI / e2e-tests (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:37:29 +01:00
00734ee233 Use host IP for e2e test API in CI
Some checks failed
CI / backend-tests (push) Failing after 26s
CI / frontend-tests (push) Successful in 29s
CI / e2e-tests (push) Successful in 5m37s
The act runner executes steps inside a container where localhost does
not reach the Docker host. Use E2E_API_URL env var (set to the host IP
192.168.1.10:8100 in CI) so both the global setup and Vite proxy can
reach the test API container.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:38:29 +01:00
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