Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2.1 KiB
2.1 KiB
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_typeenum:information | moderation | sermon | song | agenda_itempositionenum:all_slides | first_slide | last_slide | by_labelby_labelis 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_assignmentsrows - "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
- Labels file import → always sets/overwrites color
- .pro song import → only sets color on CREATE (new label); existing color preserved
- UI → read-only (no manual edit)
Current Migration Scope
labelsmigration only defines the schema; no model or business logic belongs in this task- Use
hidden_atinstead ofdeleted_atto align with soft-hide semantics