feat(setup): event-types step in first-run wizard + un-hardcode event type deps (#800)

Fresh installs can now shape the event-type catalog during the setup
wizard — rename, delete or replace the seeded defaults while nothing
references them. On existing installs system types stay protected.

- New wizard step between features and config: edit name/URL prefix,
  remove, or add types; defaults shown as recommendations
- setup_wizard_completed app setting (migration 161): seeded true when
  an admin already exists, false on fresh installs; POST /api/setup/
  complete (adminAuth) flips it when the wizard finishes
- deleteEventType: system types deletable only while the flag is unset;
  in-use check extended to quotes; per-type reminder template
  (event_reminder_<slug>) is deleted with the type
- reminder-template self-heal no longer resurrects templates for slugs
  removed from the catalog
- v1 API event creation validates event_type against the live catalog
  instead of a hardcoded whitelist (custom types were rejected; the
  never-seeded 'family' slug is no longer silently accepted)
- contract→event conversion resolves the event type via
  crm_default_event_type / resolveDefaultEventType instead of
  hardcoding 'wedding' (resolveDefaultEventType moved from quoteService
  to eventTypeService for reuse)
This commit is contained in:
Paul Nothaft
2026-07-15 21:30:23 +02:00
parent aab9e1a937
commit 7eb6357b4a
14 changed files with 573 additions and 47 deletions
+13
View File
@@ -3611,6 +3611,19 @@
"finish": "Einrichtung abschließen",
"saveFailed": "Einige Einstellungen konnten nicht gespeichert werden — Sie können sie in den Einstellungen abschließen."
},
"eventTypes": {
"subtitle": "Welche Veranstaltungen fotografieren Sie?",
"intro": "Veranstaltungsarten ordnen Ihre Galerien — jede Art erhält ein eigenes URL-Präfix und Standard-Theme. Die Vorschläge unten sind nur ein Startpunkt: Benennen Sie sie um, entfernen Sie Unnötiges oder fügen Sie eigene hinzu. Nur jetzt können die mitgelieferten Arten gelöscht werden; später lassen sie sich nur umbenennen oder deaktivieren.",
"nameLabel": "Anzeigename",
"namePlaceholder": "z.B. Familienshooting",
"slugLabel": "URL-Präfix",
"slugPlaceholder": "z.B. familie",
"add": "Veranstaltungsart hinzufügen",
"hint": "Das URL-Präfix erscheint in Galerie-Links (z.B. familie-mueller-2025-06-01). Symbole, Themes und Reihenfolge können Sie später unter Einstellungen → Veranstaltungsarten anpassen.",
"atLeastOne": "Behalten Sie mindestens eine Veranstaltungsart — jede Galerie braucht eine.",
"loadFailed": "Veranstaltungsarten konnten nicht geladen werden — Sie können sie später unter Einstellungen → Veranstaltungsarten anpassen.",
"saveFailed": "Einige Änderungen konnten nicht gespeichert werden — Sie können sie unter Einstellungen → Veranstaltungsarten abschließen."
},
"community": {
"subtitle": "Alles bereit",
"mission": "PicPeak gibt es, damit Fotografinnen und Fotografen ihre Galerien und Kundendaten selbst besitzen — auf dem eigenen Server, ohne monatliche SaaS-Gebühren. Danke, dass du es ausprobierst.",
+13
View File
@@ -3500,6 +3500,19 @@
"finish": "Finish setup",
"saveFailed": "Some settings could not be saved — you can finish them in Settings."
},
"eventTypes": {
"subtitle": "Which events do you photograph?",
"intro": "Event types organize your galleries — each one gets its own URL prefix and default theme. The suggestions below are just a starting point: rename them, remove what you don't need, or add your own. This is the only time the built-in types can be deleted; later they can only be renamed or deactivated.",
"nameLabel": "Display name",
"namePlaceholder": "e.g. Family Shoot",
"slugLabel": "URL prefix",
"slugPlaceholder": "e.g. family",
"add": "Add event type",
"hint": "The URL prefix appears in gallery links (e.g. family-smith-2025-06-01). Icons, themes and order can be tuned later in Settings → Event Types.",
"atLeastOne": "Keep at least one event type — every gallery needs one.",
"loadFailed": "Could not load the event types — you can adjust them later in Settings → Event Types.",
"saveFailed": "Some event type changes could not be saved — you can finish them in Settings → Event Types."
},
"community": {
"subtitle": "You're all set",
"mission": "PicPeak exists so photographers can own their galleries and client data — on their own server, without monthly SaaS fees. Thanks for giving it a try.",