# 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

### Macros Tables Task
- Keep all three tables in one migration file so the schema lands together and the junction FKs resolve cleanly during `migrate:fresh`
- Store `last_imported_filename` as nullable text metadata on `macros`; no separate import log table for this task
