Parent
Phase 1k Umbrella: #101
Depends-on
Phase 1k.2 (#102) ist parallel/davor lauffähig — Layout-Engine baut auf gleicher Render-Pipeline auf
Problem
Aktuell: 21 YAML-Templates (hangar/grocy/snipeit/spoolman/qr-only × 12/18/24mm + 6 Samla × 12/24/62mm) mit hartcodierten x/y/size/font_size Element-Listen pro Template.
Konsequenzen:
- Layout-Korrektur (z.B. QR-Größe oder Font-Größe) erfordert N YAML-Anpassungen statt EINER zentralen Korrektur
- DPI-Wechsel (PT 180 vs QL 300) erforderte 21 Templates per scale_y manuell anzupassen (siehe Phase 1i A-Diagnose Fix)
- Neue Tape-Größe einführen = N neue Templates schreiben
- Neue Content-Variante = N×Tape-Größen Files
Lösung — Engine + Tape-Geometrie-Tabelle
Zentralisierte Geometrie-Definition pro Tape-Größe:
# TapeGeometry — eine Stelle, alle Templates profitieren
12mm:
printable_px: 70
qr_max_px: 66
qr_padding_px: 2
text_start_x: 72
fonts:
xl: 22 # primary_id
l: 18 # title
m: 14 # subtitle (3-line layouts)
s: 10 # secondary
y_positions:
line1_top: 2
line2_below: 42
18mm: # extrapoliert + empirisch zu validieren
24mm: # extrapoliert + empirisch zu validieren
62mm: # QL-820NWB Endless-Tape, anderes Layout (mehr Höhe verfügbar)
Zentralisierte Content-Types (ersetzen pro-App Templates):
ContentType:
- qr_only # nur QR, zentriert auf Tape-Höhe
- qr_one_line # QR + 1 Text-Zeile
- qr_two_lines # QR + primary_id + title (häufigster Fall)
- text_one_line # nur primary_id, groß
- text_two_lines # primary_id + title (ohne QR)
Engine-API:
LayoutEngine.render(
tape_mm: int,
content_type: ContentType,
data: LabelData,
) -> Image
Migration: bestehende 21 Templates werden auf Engine-Calls gemappt. Z.B. hangar-furniture-12mm = (tape_mm=12, content_type=qr_two_lines, data={primary_id, title, qr_payload}). Hangar-Code muss minimal angepasst werden (oder bleibt via Compatibility-Layer der die alten template_ids auf Engine-Calls umsetzt).
Empirische Baseline (Phase 1i V4-Winner)
12mm — verifiziert auf PT-P750W:
- QR x=2 y=2 max_size=66 — Smartphone-Scan funktioniert
- text_start_x=72
- primary font_size=22 (lesbar)
- title font_size=18 (lesbar)
- y_positions: primary_top=2, title_below=42
18mm und 24mm: extrapolieren via Pixel-Ratio (printable_px Verhältnis 70:112:128 = 1:1.6:1.83), dann empirisch validieren in einem Smoke-Test analog zu Phase 1i.
62mm QL: separates Design, viel mehr Höhe verfügbar — vermutlich mehr Content-Types möglich (z.B. qr_three_lines, qr_with_secondary).
Scope
In:
- Neue Module:
app/services/layout_engine.py, app/schemas/tape_geometry.py, app/schemas/content_type.py
- TapeGeometry-Tabelle für 12/18/24/62mm
- 5 ContentTypes (qr_only, qr_one_line, qr_two_lines, text_one_line, text_two_lines)
- Migration der 21 bestehenden Templates auf Engine-Calls (Compatibility-Layer)
- Tests pro ContentType × Tape-Größe
Out:
Akzeptanzkriterien
Referenzen
- Empirische Daten: docs/site/operations/protokolle/2026-06-04-phase1i-smoke-test-empirie.md
- Phase 1i Templates: backend/app/seed/templates/*.yaml
- Phase 1i LabelRenderer: backend/app/services/label_renderer.py
- A-Diagnose: docs/research/2026-06-02-pt750w-layout-diagnose.md
Parent
Phase 1k Umbrella: #101
Depends-on
Phase 1k.2 (#102) ist parallel/davor lauffähig — Layout-Engine baut auf gleicher Render-Pipeline auf
Problem
Aktuell: 21 YAML-Templates (hangar/grocy/snipeit/spoolman/qr-only × 12/18/24mm + 6 Samla × 12/24/62mm) mit hartcodierten x/y/size/font_size Element-Listen pro Template.
Konsequenzen:
Lösung — Engine + Tape-Geometrie-Tabelle
Zentralisierte Geometrie-Definition pro Tape-Größe:
Zentralisierte Content-Types (ersetzen pro-App Templates):
Engine-API:
Migration: bestehende 21 Templates werden auf Engine-Calls gemappt. Z.B.
hangar-furniture-12mm=(tape_mm=12, content_type=qr_two_lines, data={primary_id, title, qr_payload}). Hangar-Code muss minimal angepasst werden (oder bleibt via Compatibility-Layer der die alten template_ids auf Engine-Calls umsetzt).Empirische Baseline (Phase 1i V4-Winner)
12mm — verifiziert auf PT-P750W:
18mm und 24mm: extrapolieren via Pixel-Ratio (printable_px Verhältnis 70:112:128 = 1:1.6:1.83), dann empirisch validieren in einem Smoke-Test analog zu Phase 1i.
62mm QL: separates Design, viel mehr Höhe verfügbar — vermutlich mehr Content-Types möglich (z.B. qr_three_lines, qr_with_secondary).
Scope
In:
app/services/layout_engine.py,app/schemas/tape_geometry.py,app/schemas/content_type.pyOut:
Akzeptanzkriterien
Referenzen