lila/documentation/backlog.md
lila 5b266d7435
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m13s
adding task to test gameservice
2026-04-24 09:15:59 +02:00

8.1 KiB
Raw Blame History

lila — backlog

Labels: [feature] [infra] [security] [ux] [debt]


now

Things that are actively in progress or should be picked up immediately. Mostly operational risk and the remaining phase 7 hardening work.

  • 404 and redirect handling [ux] Unknown routes return raw errors. Add a catch-all route on the frontend for client-side 404s. Consider a Caddy fallback for unrecognized subdomains.

  • React error boundaries [ux] Catch and display runtime errors gracefully instead of crashing the entire app.

  • Pin dependencies in package.json [debt] [infra] Unpinned deps in a CI/CD pipeline are a real risk. Pin all versions to exact values to prevent unexpected breakage on build.

  • Docker credential helper [debt] [infra] Credentials are stored unencrypted in ~/.docker/config.json. Set up a credential helper. See https://docs.docker.com/go/credential-store/

  • Google OAuth publishing [infra] Only test users can currently log in via Google. Publish the OAuth consent screen so any Google user can sign in — requires branding verification in Google Cloud Console.

  • Hetzner domain migration check [infra] Verify whether the lilastudy.com domain needs to be migrated following a Hetzner DNS change. Check Hetzner dashboard for any pending migration notice.

  • Security headers with helmet [security] Add helmet middleware to set secure HTTP response headers. One-liner: app.use(helmet()). Covers headers like X-Content-Type-Options, X-Frame-Options, and Content-Security-Policy.

  • Conditionally register OAuth providers [debt] Better Auth logs warnings when social providers are registered without credentials (Social provider google is missing clientId or clientSecret). Instead of registering all providers unconditionally, only add a provider to the config when its credentials are present in the environment. Keeps local dev clean for contributors who don't have OAuth apps set up.

  • Multiplayer GameService unit tests [debt] round evaluation, scoring, tie-breaking, timeout handling


next

Clearly planned work, not yet started. No hard ordering — sequence based on what unblocks real users first.

  • Guest / try-now flow [feature] Allow users to play a quiz without signing in so they can see what the app offers before creating an account. Make auth middleware optional on game routes, add a "Try without account" button on the landing/login page.

  • Favicon, page titles, Open Graph meta [ux] Add favicon, set proper per-route page titles, add Open Graph meta tags for link previews.

  • Accessibility pass [ux] Keyboard navigation for quiz buttons, ARIA labels on interactive elements, focus management during quiz flow.

  • Monitoring and logging [infra] Uptime monitoring and centralized logging on the VPS. Options: chkrootkit/rkhunter for security, logwatch/monit for daily summaries.

  • Offsite backup storage [infra] Database backups currently live on the same VPS. Add offsite copies to Hetzner Object Storage or an S3-compatible service to protect against VPS failure.

  • Valkey for game session store [infra] Add Valkey to the production Docker stack. Implement ValkeyGameSessionStore against the existing GameSessionStore interface. Required before multiplayer scales. NOTE: the rate limiting middleware needs to be adjusted for valkey, see todo comment

  • User stats endpoint + profile page [feature] GET /users/me/stats returning games played, score history, etc. Frontend profile page displaying the stats.

  • Admin dashboard [feature] User management, overview of words and languages, and per-term stats. Not urgent but has real operational value once real users are present.

  • Email + password login [feature] Traditional email/password auth as an alternative to social login. Configure via Better Auth.

  • Apple login [feature] Add Apple as a social login option via Better Auth. Requires Apple Developer account and Sign in with Apple configuration.

  • Graceful WS reconnect [infra] Handle WebSocket disconnections gracefully. Reconnect with exponential back-off. Restore game state on reconnection if a game is still in progress.

  • Configurable game settings in multiplayer lobby [feature] Game settings (mode, round count, timer duration, target score) are currently hardcoded. The host should be able to configure these when creating a lobby. Settings should be stored in the settings jsonb column on the lobbies table and passed through to the game service at start.

  • Tighten CSP to remove unsafe-inline [security] Current script-src uses 'unsafe-inline' to accommodate framework-injected inline scripts (likely TanStack Router hydration). Tightening this would require nonce-based CSP, which needs server-rendered HTML or a Caddy layer that injects per-request nonces. Not urgent — pragmatic CSP with 'unsafe-inline' is mainstream for SPAs at this scale. Revisit if the app handles more sensitive data or grows a meaningful user base


later

Directionally right, timing is unclear. Revisit when the next/now work is done.

  • Game modes [feature] Five modes are designed in game_modes.md — TV Quiz Show, Race to the Top, Chain Link, Elimination Round, Cooperative Challenge. The lobby infrastructure is mode-agnostic; each mode adds game logic only. First mode to implement is TBD. This is effectively a new phase.

  • Single Player Extended [feature] Expanded singleplayer flow. Possible directions: longer sessions with increasing difficulty, streak bonuses, mixed POS/language rounds, progress tracking across sessions, timed challenge mode.

  • Users in a separate database [infra] Architectural separation of auth/user data from vocabulary and game data. No immediate benefit — revisit after hardening is complete and user growth justifies the complexity.

  • Modern env management [debt] Replace .env files with a more robust approach (e.g. dotenvx, infisical). Current setup works but is error-prone and not versioned.

  • Reorganize datafiles and wordlists [debt] The current layout of data-sources/, scripts/datafiles/, scripts/data-sources/, and packages/db/src/data/ is confusing with overlapping content. Consolidate into a clear structure.

  • Resolve eslint peer dependency warning [debt] eslint-plugin-react-hooks 7.0.1 expects eslint ^3.0.0^9.0.0 but found 10.0.3. Low impact but worth cleaning up when nearby.

  • husky + lint-staged [debt] Set up husky and lint-staged to run linting and formatting checks before every commit. Prevents CI failures from formatting or lint issues that slipped through locally.

  • OpenAPI documentation for REST endpoints [feature] Document the API surface using OpenAPI/Swagger. Covers all REST endpoints with request/response shapes. Useful groundwork for the admin dashboard and any future contributors.

  • Frontend tests [debt] component tests for QuestionCard, OptionButton, ScoreScreen; consider Playwright or Vitest browser mode for e2e


changelog

Shipped milestones, newest first.

  • 04 - 2026 - Rate limiting on API endpoints - At minimum: auth endpoints (brute force prevention) and game endpoints (spam prevention)
  • 04 - 2026 — Migrations in deploy pipeline — Drizzle migrate runs as a CI/CD step before the API container restarts
  • 04 - 2026 — Phase 6: Production deployment — Hetzner VPS, Caddy HTTPS, Forgejo CI/CD, daily DB backups, cross-subdomain auth
  • 04 - 2026 — Phase 5: Multiplayer game — real-time simultaneous play, 15s server timer, live scoring, winner screen
  • 04 - 2026 — Phase 4: Multiplayer lobby — WebSocket server, lobby create/join, real-time player list
  • 04 - 2026 — Phase 3: Auth — Better Auth, Google + GitHub social login, session middleware, auth guard
  • 04 - 2026 — Phase 2: Singleplayer UI — full quiz loop in browser, game setup, question card, score screen
  • 04 - 2026 — Phase 1: Vocabulary data + API — WordNet/OMW data pipeline, CEFR enrichment, game session endpoints
  • 04 - 2026 — Phase 0: Foundation — pnpm monorepo, TypeScript, ESLint, Vitest, Drizzle, Docker Compose