# Decisions — macros-and-labels-import ## [2026-05-03] Architectural Decisions ### Schema - **labels table**: global, unique by name, nullable color, hidden_at (NOT deleted_at) - **macros table**: unique by uuid (uppercase), hidden_at (NOT deleted_at) - **macro_assignments**: restrictOnDelete on macro_id and label_id FKs - **service_macro_overrides**: existence of row = override active; no extra boolean - **song_arrangement_labels**: replaces song_arrangement_groups; references global label_id ### Macro Assignment Semantics - `part_type` enum: `information | moderation | sermon | song | agenda_item` - `position` enum: `all_slides | first_slide | last_slide | by_label` - `by_label` is valid for ALL part_types (not songs-only) — validated at app level if restriction needed - Stacking: multiple assignments can fire on same slide — all applied in `order ASC` - Override wins 100% — no globals bleed through when override exists ### Override Semantics - "Anpassen" snapshots current globals into `service_macro_assignments` rows - "Auf Standard zurücksetzen" deletes the override row + cascades service_macro_assignments - German tooltip: "Erstellt eine Kopie der aktuellen globalen Zuweisungen für diesen Gottesdienst. Spätere Änderungen an den globalen Zuweisungen wirken sich auf diesen Gottesdienst NICHT mehr aus." ### Data Migration - Destructive: `up()` deletes songs, song_groups, song_slides, song_arrangements, song_arrangement_groups - `down()` throws RuntimeException (irreversible) - Guard: `if (!Schema::hasTable('song_groups') || !DB::table('song_groups')->exists()) return;` - Old 4 macro settings keys → migrated to global assignment if all present; then deleted ### Label Color Priority 1. Labels file import → always sets/overwrites color 2. .pro song import → only sets color on CREATE (new label); existing color preserved 3. UI → read-only (no manual edit) ### Current Migration Scope - `labels` migration only defines the schema; no model or business logic belongs in this task - Use `hidden_at` instead of `deleted_at` to align with soft-hide semantics