Skip to content

Latest commit

 

History

History
114 lines (88 loc) · 10.6 KB

File metadata and controls

114 lines (88 loc) · 10.6 KB

RomM - Repository Guide for Contributors & Agents

RomM is a self-hosted ROM manager and player: scan a game library off disk, enrich it with metadata from 10+ providers, browse it in a web UI, and play in the browser.


The stack at a glance

Backend Frontend
Path backend/ frontend/
Language Python 3.14+ TypeScript 5.9 (Vue 3)
Framework FastAPI, SQLAlchemy 2.0, Alembic Vue 3 + Vite, Vuetify, Pinia, Vue Router
Infra Redis + RQ (jobs/cache/sessions), Socket.IO vue-i18n, Socket.IO client
DB MariaDB (default), MySQL, PostgreSQL -
Tooling uv, pytest, Trunk (ruff/black/isort/mypy) npm, vue-tsc, ESLint, Vitest, Storybook

The frontend talks to the backend over /api/* (REST) and /ws (Socket.IO). TypeScript types are generated from the backend's OpenAPI schema into frontend/src/__generated__/ - the backend is the single source of truth for API shapes.

Deep-dive references

  • docs/BACKEND_ARCHITECTURE.md - directory map, ER diagram, every endpoint, auth/scopes, tasks.
  • docs/FRONTEND_ARCHITECTURE.md - routing, stores, services, theming, build tooling.
  • DEVELOPER_SETUP.md - Docker and manual local setup (mock library, .env, services).
  • CONTRIBUTING.md - contribution flow, AI-assistance disclosure, translations.

The frontend has two UIs - know which you're in

  • v1 is frozen. Everything under frontend/src/views/, src/components/, src/console/, src/layouts/ is legacy and will be deleted wholesale in a final wave. Do not refactor v1. Only touch it for a critical bug, and when a v2 fork exists, mark the v1 export @deprecated.
  • v2 is the active rewrite under frontend/src/v2/, gated by user.ui_settings.uiVersion. It has its own design system (tokens), primitive library (R* components in src/v2/lib/), universal input (mouse/touch/keyboard/gamepad), and responsive system. New frontend work goes in v2.

v2 has a detailed constitution, split across focused skills (below). Read the relevant skill before editing v2 code.


Skills - load the focused guide for your task

These live in .claude/skills/ and carry the detailed rules. Invoke the one that matches what you're doing:

Skill When
knowledge-base Understanding how part of the codebase works or where it lives, via Greptile's synthesized knowledge base. Verify what it says against the code.
frontend-v2-components Building/editing any v2 component - tiers (lib/shared/feature), file & SFC conventions, barrels, anti-patterns.
frontend-v2-theming Colors, tokens, light/dark themes, visual language - and the zero-hex-literal policy.
frontend-v2-input Interactive components, focus/spatial navigation, gamepad/keyboard, breakpoints & responsive layout.
frontend-v2-patterns Feature behavior - errors/snackbars, loading, sockets, state persistence, pagination, forms, permissions, destructive confirmations.
frontend-i18n Any user-visible string or change under frontend/src/locales/**.
backend-development Endpoints, handlers, models, schemas, metadata adapters, tasks, migrations under backend/.
review-polish Before committing / opening a PR / declaring done - the self-review pass (comments, duplication, naming, test typing) plus the checks that keep CI green.
security-audit Vetting a diff (release tag range or PR) for anything malicious or a security regression - supply chain, egress, auth/injection, CI, provenance.
pr-ready Before opening a PR - the four passes in order: security-audit, code-review xhigh --fix, simplify, review-polish. Not auto-invoked.
address-bot-reviews After Greptile and Copilot review a PR - triage each finding, fix what holds up, reply with the fix or the reason, and resolve the threads. Not auto-invoked.
draft-release-notes Drafting the GitHub release notes for a release, stable or alpha/beta, from the diff since the previous stable tag.
draft-announcement Drafting the Discord announcement for a release, from the release notes plus an interview about community news. Not auto-invoked.

Repo-wide rules

Disclose AI assistance in the PR. RomM requires it (see CONTRIBUTING.md): state that AI was used and to what extent. This is mandatory and non-negotiable for agent-written contributions. Branch off master; open PRs against master. Fork → feature branch → PR. Don't push to master. Linting is via Trunk (trunk fmt && trunk check) — it wraps ruff, black, isort, mypy, ESLint, Prettier, and more, and runs in CI on every PR. Never commit with --no-verify. The backend owns the API contract. Changed a response schema or route? Regenerate frontend types (npm run generate) and re-typecheck. Tests travel with code. New logic gets a test; new endpoints get endpoint tests; new v2 primitives get a Storybook story (+ play() if interactive). Verify before handoff. Don't say "done" on UI work without testing it in the browser in both themes and all input modalities. See review-polish. English first. Outside of language files, all code, comments, identifiers, .md files, and commit/PR messages are in English. No em-dashes. Never use em-dashes (—) when writing comments or text. Use commas, parentheses, or separate sentences instead. Keep comments short. Comments should be concise, and focus on the "why" rather than the "what" (the code itself is the "what"). A comment is one or two lines; a docstring is one sentence plus Args:/Returns: when the signature needs it. Three or more lines of prose means you are explaining, not commenting. See review-polish for what to cut. Don't restate the code. The code is self-documenting, so skip comments that narrate what a reader can already see (which button sits where, that something is disabled when empty, obvious ordering). Comment only non-obvious "why" that the code can't convey on its own. One home per value. Before declaring a constant, type, limit, regex, or store getter, search for an existing one and import it. Validation limits live on the model and are imported by endpoints; a type lives in the component that owns it and is exported. Don't add a near-duplicate that differs only by sorting, and don't invent an identity scheme where a foreign key already exists. Never commit secrets. Never commit secrets (API keys, passwords, tokens, etc.) to the repo. Use environment variables or secret management tools instead. Don't explain a change. Avoid comments that explain why a change was made to the code, or that record what the code used to do. Focus instead on the current behaviour of the code and how it works. Reasons for a change go in the commit message and the PR body. Python tools live in backend/tools/. Standalone dev/test utilities and scripts (not part of the app runtime) go in backend/tools/, not scattered across backend/. Link PRs to issues. In the PR description, use Fixes #XXXX for issue/bug fixes and Closes #XXXX for feature implementations. Use the PR template. Base every PR description on .github/PULL_REQUEST_TEMPLATE.md. Show UI changes in the PR. A PR that touches anything visible ships with at least one screenshot under the template's Screenshots heading, captured from the running app during the review-polish browser pass. Enough shots to convey what changed, not a catalogue of every state. Save the files outside the repo and never commit them, and upload them with gh pr create --attach (or gh pr edit --attach on an existing PR) rather than handing the paths to the user. Diagram architectural changes in the PR. When a change moves a boundary (a new service, task, or provider in a path, a model relationship, a different call path across layers, an auth or socket flow), the PR description carries a mermaid block showing it. GitHub renders them. Draw what changed, not the whole system. See review-polish.


Quick command reference

Setup: see DEVELOPER_SETUP.md. Docker path is cp env.template .env → docker compose build → docker compose up -d (app at http://localhost:3000).

Backend (cd backend):

uv sync --all-extras --dev          # install
uv run main.py              # run (migrations auto-apply)
uv run pytest <path/file>           # test - affected files only, NEVER the whole suite
uv run alembic revision --autogenerate -m "msg"   # new migration (then HAND-REVIEW)
uv run alembic upgrade head         # apply migrations

Frontend (cd frontend):

npm install                         # install (Node 24)
npm run dev                         # dev server :3000
npm run typecheck                   # vue-tsc
npm run typecheck:scripts           # tsc on the Node/Vite tooling in scripts/
npm run test                        # vitest (+ Storybook play() tests)
npm run test:e2e                    # playwright (needs a running app + seeded e2e users)
npm run build                       # production build
npm run generate                    # regenerate types from backend OpenAPI (backend must be running)
npm run build:tokens                # regenerate v2 tokens.css (auto on predev/prebuild)
npm run storybook                   # component library on :6006
python3 src/locales/check_i18n_locales.py   # i18n parity check
python3 src/locales/check_i18n_sorted.py    # locale keys sorted (--fix to sort)

Lint (both stacks): trunk fmt && trunk check.