fix(event-types): harden setup window + catalog validation (codex review)
Three review rounds on PR #801; fixes in response: - isValidEventType: live catalog is authoritative when it has rows — a deleted or deactivated slug no longer validates via the legacy fallback (fallback now only serves an empty-catalog install) - deleteEventType: refuse deleting the last (and last ACTIVE) type; updateEventType: refuse deactivating the last active type (unknown slugs are rejected since the validator change, so an empty active catalog would brick event creation) - setup window fails closed: only an explicit stored `false` opens it (a portable-backup restore can leave the key absent) and a normal admin login durably closes it (abandoned-wizard case) - reserved bootstrap keys (setup_wizard_completed, setup_token) are stripped from ALL generic settings upserts (/general, /security, /analytics, /seo) so the marker is genuinely one-way - wizard step: deletes ordered so the catalog can never end up empty, and a genuinely failed system-type deletion reloads the list and stays on the step instead of advancing past the only window in which it can be retried - CreateEventPage: snap the hardcoded initial 'wedding' selection to the first active type when the catalog no longer contains it - v1 API: new GET /event-types (read scope) so token clients can discover valid slugs; OpenAPI enum replaced with the live-catalog description
This commit is contained in:
@@ -182,6 +182,18 @@ export const CreateEventPage: React.FC = () => {
|
||||
[eventTypes]
|
||||
);
|
||||
|
||||
// The hardcoded initial form value ('wedding') may not exist in the live
|
||||
// catalog — the setup wizard can rename or delete the defaults (#800), and
|
||||
// the backend now rejects unknown slugs. Snap to the first active type; a
|
||||
// user-picked value is always in the list, so this never fights the user.
|
||||
useEffect(() => {
|
||||
if (!availableEventTypes.length) return;
|
||||
if (!availableEventTypes.some(t => t.value === formData.event_type)) {
|
||||
setFormData(prev => ({ ...prev, event_type: availableEventTypes[0].value }));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [availableEventTypes, formData.event_type]);
|
||||
|
||||
// Fetch default settings
|
||||
const { data: settings } = useQuery({
|
||||
queryKey: ['admin-settings'],
|
||||
|
||||
Reference in New Issue
Block a user