Label sheets printed on plain A4 are cut with a lever paper cutter. Each
template can now print small hairline cut marks in the sheet margin: one
at both ends of every cut line (left/right edge of each column, top/bottom
edge of each row), 1 mm away from the label and never closer than 2 mm to
the paper edge, so they print on normal printers and never touch a label.
Labels without a gap share one mark. Marks are drawn on every sheet for
the full grid, since the cutter cuts across the whole sheet.
On by default (new column cropMarks, default true); switch it off in the
template designer for pre-die-cut label sheets.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
renderLabelsPdf resolved the jarSize placeholder to "500 ml". Everywhere else
in the app jarSize is a fill weight in grams - the bottling forms label it
"Glasgröße (g)", the batch list and the public Herkunft page print "g", and
BottlingService divides by 1000 to get kilograms. Only the printed label said
millilitres, so every label produced so far declares the wrong net quantity for
a food sold by mass.
The placeholder mapping moved into an exported buildPlaceholderValues() so the
wording can be asserted directly. It could not be before: the render output is
a PDF buffer whose text a test cannot read, which is how the wrong unit shipped
unnoticed. Three tests now cover it, including one that rejects any volume unit
outright.
Labels already printed with "500 ml" have to be reprinted - the code change
does not correct paper.
Co-Authored-By: Claude Opus 5 <[email protected]>
The dashed rectangle drawn around every label slot (a cut/crop line)
wasn't needed and is gone, along with the width/height params that
existed only to draw it. Dates on the label (bottling date, MHD) now
use { day: '2-digit', month: '2-digit' } so single-digit values print
with a leading zero (05.03.2026, not 5.3.2026) - the default 'numeric'
formatting was dropping it.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Im automatischen Modus (Spalten/Zeilen leer) wird jetzt zusaetzlich
berechnet, wie viele Etiketten pro Blatt passen, wenn man sie um 90
Grad dreht (Breite/Hoehe vertauscht). Passt die gedrehte Anordnung mehr
drauf, wird sie verwendet - die Etiketten selbst bleiben inhaltlich
unveraendert (nur auf dem Blatt gedreht), jedes einzelne Etikett bleibt
beim Abziehen normal lesbar.
Bei explizit gesetzten Spalten/Zeilen (z.B. fuer ein vorgedrucktes
Avery-Raster) greift die Drehung nicht - ein reales Blatt hat feste,
nicht drehbare Felder.
Rotation erfolgt via pdfkit-Rotation um die Mitte des Feldes: ein
Etikett, exakt 90 Grad um seinen eigenen Mittelpunkt gedreht, ergibt
immer eine vertauschte Bounding-Box an derselben Stelle - unabhaengig
von der Drehrichtungskonvention. 2 neue Tests belegen ueber die
Seitenzahl, dass die Drehung greift, wenn sie mehr Etiketten
unterbringt, und dass ein explizites Raster unangetastet bleibt.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Ein zweiter, unabhaengiger Audit-Durchlauf (frischer Blick, keine
Vorkenntnis meiner eigenen Fixes) bestaetigte alle bisherigen Fixes als
korrekt verdrahtet und fand 3 LOW-severity Robustheitsluecken - keine
davon war ausnutzbar, aber alle sind jetzt behoben:
- HarvestsService.create/ExtractionsService.create pruefen jetzt, dass
referenzierte colonyIds/harvestIds tatsaechlich existieren, bevor die
Transaktion laeuft - vorher fuehrte eine unbekannte Id zu einem
ungefangenen 500 mit rohem Prisma-Fehler statt einer sauberen 400.
- Etiketten-Bildelemente durchlaufen jetzt denselben Magic-Byte-Check
wie Avatar-/Dokument-Uploads, statt pdfkits Bildparser ungepruefte
Bytes zu uebergeben.
- Webhook-Secret-Redaktion im Audit-Log nutzt jetzt explizites delete
statt sich auf Prismas JSON-Serialisierung zu verlassen, die
undefined-Werte verwirft (fragil, falls sich die Serialisierung mal
aendert).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Eine explizit im Etiketten-Designer eingetragene Spalten-/Zeilenzahl
wurde beim PDF-Rendern ungeprueft uebernommen. Passt sie nicht auf ein
A4-Blatt (z.B. 90mm breite Etiketten x 4 Spalten bei 5mm Rand), ragen
die hinteren Spalten/Zeilen ueber den Blattrand hinaus - der Drucker
schneidet sie dann einfach ab, statt sie zu drucken.
- Backend (label-templates.service.ts): Spalten/Zeilen werden jetzt auf
das tatsaechlich auf A4 passende Maximum begrenzt, bevor gerendert
wird - betrifft auch bereits gespeicherte Vorlagen mit zu grossen
Werten.
- Frontend (label-designer.tsx): zeigt die maximal passende Spalten-/
Zeilenzahl direkt im Seiten-Layout-Panel an und warnt inline, wenn
der eingetragene Wert das Blatt sprengen wuerde.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
- LabelTemplate bekommt columns/rows (optional, leer = automatisch
passend), plus konfigurierbare Raender/Abstaende - damit ein Etikett
exakt auf das vorgedruckte Raster eines physischen Etikettenbogens
(z.B. Avery) gelegt werden kann statt nur automatisch berechnet
- Startposition beim Drucken waehlbar, fuer bereits angebrochene Boegen
(erste Seite startet ab der gewaehlten Position, Folgeseiten wieder
von vorne)
git add -u im letzten Commit hat neue (untracked) Dateien übersprungen:
die Migration für LabelTemplate.elements, die neuen Typ-/DTO-Dateien und
den kompletten Drag-and-Drop-Editor fehlten dadurch im Build.