Contributing

The source is on GitHub, MIT licensed.

Running the checks

pnpm lint
pnpm typecheck
pnpm test

The suite runs in three layers: pure unit tests, integration tests that exercise the scheduled sweep against a real database and real files, and end-to-end tests that drive a real Nuxt server over HTTP for the paths that only exist as a running request — the streamed upload, the streamed zip, magic-link sign-in and password reset.

It needs a MySQL you can create a database on, and unzip on the PATH. Tests use their own database and their own storage root, and refuse to start if the database name does not contain "test" — dropping tables is the first thing they do. Mail is rendered but never sent.

Screenshots

pnpm demo:screenshots

Builds the app, seeds a throwaway instance and captures every page in every language, with a browsable index. The README's screenshot is one of those captures and is refreshed on every run, so it cannot show an interface that no longer exists.

Migrations

Append a new entry to the ordered list in app/lib/databaseSetup.ts — never edit or remove an existing one, since it may already have run somewhere.

Runs are serialised with a MySQL advisory lock, so two containers starting at once cannot both apply the same migration. Column-adding migrations check for the column first, so a process killed between the ALTER and its bookkeeping does not brick the instance on the next boot.

Conventions

Comments explain why, not what. The code says what it does; a comment earns its place by recording the reasoning that is not visible — the failure it prevents, the alternative that was tried, the constraint that made the obvious approach wrong.