pp-planer/.sisyphus/notepads/macros-and-labels-import/learnings.md
Thorsten Bus 860db0405f docs: record labels migration verification
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-03 22:10:46 +02:00

2.8 KiB

Learnings — macros-and-labels-import

[2026-05-03] Session ses_210cd1557ffeGs4SEGrt7hnvyS — Plan Created

Parser Library

  • Source at /Users/thorsten/AI/propresenter/src/ (NOT /Users/thorsten/AI/propresenter-work/php/ per stale AGENTS.md)
  • VCS repo: https://git.stadtmission-butzbach.de/public/propresenter-php.git (dev-master)
  • New classes (NOT yet in vendor/): MacrosFileReader, LabelsFileReader, Macro, MacroLibrary, MacroCollection, Label, LabelLibrary
  • MacrosFileReader::read(string $filePath): MacroLibrary — raw protobuf binary, no extension
  • LabelsFileReader::read(string $filePath): LabelLibrary — same
  • Label::getName() returns protobuf text field — name is the identity (no UUID for labels)
  • Macro::getColor() returns ?array{r,g,b,a} floats 0..1 — need MacroColorConverter to get hex
  • Label::getColorHex() already returns #RRGGBB — mirror its formula for macros
  • PHP 8.4 required by parser. App currently requires ^8.2 — BLOCKER for T0.1

DB Schema Key Facts

  • slides.type enum is [information, moderation, sermon] ONLY — no agenda_item
  • agenda_item part_type = slide where service_agenda_item_id IS NOT NULL at runtime
  • song_groups.color is NOT NULLABLE (migration says so) — new labels.color IS nullable
  • service_songs.song_id is cascadeOnDelete — wiping songs auto-cascades to service_songs

Export Flow

  • ProExportService::buildGroups() lines 38-69 — macro injection point
  • ProExportService::buildMacroData() lines 71-86 — reads 4 legacy settings keys
  • Currently injects macro ONLY when group name is "COPYRIGHT" (case-insensitive)
  • ProImportService::import(UploadedFile $file): array — method signature (NOT importFromFile)

Settings Pattern

  • Setting::get($key, $default) / Setting::set($key, $value) — simple key/value
  • settings table: key UNIQUE, value TEXT

Critical Decisions

  • song_groups → labels: global table, "drop all data" migration (no backwards compat)
  • Hybrid macro scope: global defaults in Settings; per-(service, part_type) override via "Anpassen"
  • Override = snapshot of globals at creation time; future global changes don't propagate
  • Stacking: all matching assignments fire, ordered by macro_assignments.order ASC
  • Hidden macros/labels: skip at export, warning badge in editor
  • Label colors: read-only in UI; Labels file import is sole authority; .pro auto-discovery only sets color on CREATE
  • FK rules: restrictOnDelete on macro/label refs (use hidden_at); cascadeOnDelete on service-scoped rows

Migration/Test Notes

  • tests/Pest.php already applies RefreshDatabase to all Feature tests; no extra setup needed for Feature/Migrations
  • SQLite unique constraint errors can be asserted with ->toThrow(\Exception::class) in migration tests