A self-hosted print studio: images at exact physical sizes, sheet layout with crop marks, tiling, 1:1 PDF. Everything else — image generation, delivery, share links, mail, Telegram — is an optional module that is off by default. This is the neutral public twin of a private tool. Compared to that original: - optional modules behind KLARBILD_MODULES; the default install is print-only - English interface with German as a full second language (1,038 strings); the English sentence is the translation key - no built-in accounts — first boot creates one admin from ADMIN_USERNAME / ADMIN_PASSWORD, or generates a password and logs it once - delivery and backup targets are generic SFTP/FTPS endpoints, off by default - English routes, English identifiers, English comments throughout - two compose files: print-only by default, everything in the full one - AGPL-3.0, CI (build, tests, type check, secret scan), CONTRIBUTING, SECURITY 124 tests green, type check clean, verified end to end against a live instance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nh4A79bbqT9dcd2inzYUdg
This commit is contained in:
164 files changed
+27190
No files matched your search
@@ -0,0 +1,79 @@
|
||||
# Contributing
|
||||
|
||||
Thanks for looking. Klarbild is a small project with one maintainer, so the most
|
||||
useful contributions are the ones that arrive ready to merge: a clear problem, a
|
||||
minimal change, and a test where a test is possible.
|
||||
|
||||
## Getting it running
|
||||
|
||||
```bash
|
||||
npm install
|
||||
cp .env.example .env # DATABASE_URL, SESSION_SECRET, ENCRYPTION_KEY
|
||||
npm run dev
|
||||
```
|
||||
|
||||
You need a PostgreSQL to point `DATABASE_URL` at; `docker compose up db` gives you
|
||||
one. Migrations run themselves on the first request.
|
||||
|
||||
```bash
|
||||
npm test # 124 tests, no database needed
|
||||
npx tsc --noEmit # must be clean
|
||||
npm run build
|
||||
```
|
||||
|
||||
Both `npm test` and `tsc` run in CI and both must be green.
|
||||
|
||||
## How the code is laid out
|
||||
|
||||
```
|
||||
src/lib/print*.ts the print engine — pure arithmetic, heavily tested
|
||||
src/lib/paper.ts 86 image sizes, 19 paper formats, the size parser
|
||||
src/lib/modules.ts which optional modules are switched on
|
||||
src/lib/i18n.ts translation; the English sentence is the key
|
||||
src/components/ React islands, one per screen
|
||||
src/pages/ Astro pages and the API under src/pages/api/
|
||||
migrations/ numbered SQL, forward-only, idempotent, run on boot
|
||||
tests/ node:test, no framework
|
||||
```
|
||||
|
||||
The rule that matters most: **the browser preview and the server-side PDF use the
|
||||
same layout code.** If you change how a sheet is laid out, change it in
|
||||
`src/lib/printlayout.ts` and both follow. Anything that recomputes geometry in a
|
||||
component is a bug waiting to happen.
|
||||
|
||||
## House style
|
||||
|
||||
- Comments explain **why**, and carry the number that justifies the decision.
|
||||
"Measured: 440 MB of images peaked at 196 MB of memory" is worth more than
|
||||
"stream the files". Please keep that habit; it is most of what makes this
|
||||
codebase navigable.
|
||||
- No new dependency without a reason in the pull request. There are 20 runtime
|
||||
dependencies and that is already plenty.
|
||||
- Two-space indent, no semicolon crusade, no reformatting of files you did not
|
||||
otherwise touch.
|
||||
- Metric units. English decimal point in English strings.
|
||||
|
||||
## Translation
|
||||
|
||||
The English string in the source **is** the key. To add a language:
|
||||
|
||||
1. Copy `src/locales/de.json` to `src/locales/<code>.json` and translate the values.
|
||||
2. Add the code to `LOCALES` and `LOCALE_NAMES` in `src/lib/i18n.ts`, and to
|
||||
`DICTS` in `src/lib/i18n.server.ts`.
|
||||
|
||||
A missing key falls back to English, so a partial translation is still useful. Never
|
||||
build a sentence by concatenation — use a named placeholder: `t('{done} of {total}
|
||||
done', { done, total })`.
|
||||
|
||||
## Adding a module
|
||||
|
||||
Optional features live behind `src/lib/modules.ts`. A new one needs: an entry in
|
||||
`MODULE_IDS` and `MODULE_INFO`, a `has('yours')` guard on its navigation entry and
|
||||
its settings card, and `if (!has('yours')) return moduleOff('yours')` at the top of
|
||||
every API route it owns. The test is simple — with the module off, the instance
|
||||
should not hint that the feature exists.
|
||||
|
||||
## Pull requests
|
||||
|
||||
One change per pull request. Say what breaks if it is wrong. If you found a bug you
|
||||
are not fixing, an issue with a reproduction is genuinely useful on its own.
|
||||
Reference in new issue
Block a user