Commit Graph

254 Commits

Author SHA1 Message Date
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
eeb1609452 fix: enforce run ownership on all mutation endpoints
Add require_run_owner helper in auth.py that enforces ownership on
mutation endpoints. Unowned (legacy) runs are now read-only.

Applied ownership checks to:
- All 4 encounter mutation endpoints
- Both boss result mutation endpoints
- Run update/delete endpoints
- All 5 genlocke mutation endpoints (via first leg's run owner)

Also sets owner_id on run creation in genlockes.py (create_genlocke,
advance_leg) and adds 22 comprehensive ownership enforcement tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-21 13:28:47 +01:00
a12958ae32 update beans and postgres mount path
All checks were successful
CI / backend-tests (push) Successful in 27s
CI / frontend-tests (push) Successful in 29s
2026-03-21 12:51:35 +01: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
2364922b58 beans update 2026-03-20 21:59:43 +01:00
a6cb309b8b chore: archive 42 completed/scrapped beans
All checks were successful
CI / backend-tests (push) Successful in 28s
CI / frontend-tests (push) Successful in 28s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:31:23 +01:00
Julian Tabel
2f8b437c8a stopped talos
All checks were successful
CI / backend-tests (push) Successful in 26s
CI / frontend-tests (push) Successful in 27s
2026-03-20 16:40:15 +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
c9d42b091f Daedalus and Talos integration test
All checks were successful
CI / backend-tests (push) Successful in 26s
CI / frontend-tests (push) Successful in 29s
2026-03-20 16:31:19 +01:00
Julian Tabel
24c60e2e28 Add backend tool-versions and update bean status
All checks were successful
CI / backend-tests (push) Successful in 25s
CI / frontend-tests (push) Successful in 28s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:29:22 +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
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
1513bb3658 Split e2e tests into manual workflow_dispatch workflow
All checks were successful
CI / frontend-tests (push) Successful in 27s
CI / backend-tests (push) Successful in 26s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:54:25 +01:00
efa0b5f855 Add --prune flag to seed command to remove stale data
Without --prune, seeds continue to only upsert (add/update).
With --prune, routes, encounters, and bosses not present in the
seed JSON files are deleted from the database.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:33:54 +01:00
d535433583 Archive 23 completed beans
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:59:54 +01:00
b50e9160ba Add uv to PATH after install in CI
The uv installer places the binary in ~/.local/bin which isn't on
PATH by default in the act runner. Source the env file for the current
step and append to GITHUB_PATH for subsequent steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:32:51 +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
bf3a3d3329 Replace CI lint jobs with backend, frontend, and e2e test jobs
Some checks failed
CI / backend-tests (push) Failing after 37s
CI / frontend-tests (push) Successful in 28s
CI / e2e-tests (push) Failing after 1m42s
Lint, formatting, and type checks are already enforced by prek pre-commit
hooks, so CI now focuses on running the actual test suites instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 14:13:34 +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
ee5bf03f19 Add integration tests for Genlockes & Bosses API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:21:32 +01:00
34835abe0c Add integration tests for Pokemon & Evolutions API
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:15:00 +01:00
ca736e0f39 Add unit tests for services layer
36 tests covering build_families (linear chains, branching, disjoint,
Shedinja case), resolve_base_form, to_roman (parametrized), and
strip_roman_suffix including round-trip verification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:05:24 +01:00
d6a0b60585 Add integration tests for Runs & Encounters API
28 tests covering run CRUD, rules JSONB storage, encounter creation,
route-lock enforcement, shinyClause and giftClause bypasses, status
transitions (complete/fail), and encounter update/delete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:58:28 +01:00
79eabf4f9f Add integration tests for Games & Routes API
25 tests covering game CRUD (create/list/get/update/delete), slug
uniqueness enforcement, by-region grouping, and route operations
(create/update/delete/reorder). Verifies that list_game_routes
excludes routes with no Pokemon encounters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:51:37 +01:00
4aae12cd72 Add unit tests for Pydantic schemas
46 tests across 12 schema classes covering CamelModel alias generation,
required field validation, optional field defaults, camelCase input/output,
nested model coercion, and from_attributes support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:41:22 +01:00
b0ac3714a9 Set up backend test infrastructure
Add pytest fixtures (engine, db_session, client) with session-scoped
event loop to avoid asyncpg loop mismatch errors. Smoke tests verify
all three main API endpoints return empty results on a clean DB.
Test DB provided by docker-compose.test.yml on port 5433.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:35:22 +01:00
16f9e68821 Mark Overhaul Nuzlocke Rules System epic as completed
All child features are done.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 12:23:37 +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
aea5d1d84d Update bean 2026-02-20 22:03:52 +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
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
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
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
cb35bf161e Update bean 2026-02-20 19:27:46 +01:00
Julian Tabel
7ec43431e5 Add epic: Overhaul Nuzlocke Rules System
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:28:50 +01:00
Julian Tabel
4d097158bd Add new epic 2026-02-19 08:44:05 +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