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,39 @@
|
||||
-- Print history: what was printed last --------------------------------------
|
||||
--
|
||||
-- Only the **recipe** is stored, not the result: the sheet settings, the
|
||||
-- references to the source images, and a few key figures. An A3 print sheet
|
||||
-- as a PDF is quickly 20–80 MB; a few dozen prints would fill the disk, and
|
||||
-- with files that can be regenerated in seconds at that. The sheet is simply
|
||||
-- recomputed on reprint — deterministic, from the same sources.
|
||||
--
|
||||
-- Row size: roughly 1–3 KB per entry. A thousand prints therefore cost a few
|
||||
-- megabytes instead of many gigabytes.
|
||||
CREATE TABLE IF NOT EXISTS print_runs (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
created_by uuid REFERENCES users(id) ON DELETE SET NULL,
|
||||
-- Where the print came from: 'web' | 'telegram' | 'mcp' | 'api'
|
||||
origin text NOT NULL DEFAULT 'web',
|
||||
-- Human-readable short form for the list ("13 × 18 cm ×1, 35 × 45 mm ×8").
|
||||
summary text,
|
||||
paper text, -- "A4 · 210 × 297 mm"
|
||||
pages integer NOT NULL DEFAULT 1,
|
||||
pieces integer NOT NULL DEFAULT 1,
|
||||
bytes integer, -- size of the generated PDF, informational only
|
||||
-- The full request that the sheet can be regenerated from.
|
||||
-- Deliberately the request body and not a bespoke format: what is stored
|
||||
-- here can be sent back to /api/print/sheet unchanged.
|
||||
config jsonb NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS print_runs_user_idx ON print_runs(created_by, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS print_runs_created_idx ON print_runs(created_at DESC);
|
||||
|
||||
-- Which library images went into a print. Only for images from the
|
||||
-- library — individually uploaded files have no durable identifier and are
|
||||
-- gone anyway once the sources are cleaned up.
|
||||
CREATE TABLE IF NOT EXISTS print_run_items (
|
||||
run_id uuid NOT NULL REFERENCES print_runs(id) ON DELETE CASCADE,
|
||||
item_id uuid NOT NULL REFERENCES items(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (run_id, item_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS print_run_items_item_idx ON print_run_items(item_id);
|
||||
Reference in new issue
Block a user