validate([ 'slug' => ['nullable', 'string', 'max:100'], 'name' => ['nullable', 'string', 'max:255'], 'date' => ['nullable', 'date'], 'event_type' => ['nullable', 'string', 'max:100'], 'tasks' => ['nullable', 'array'], 'tasks.*.slug' => ['required_with:tasks', 'string', 'max:120'], 'tasks.*.title' => ['required_with:tasks', 'string', 'max:255'], 'tasks.*.description' => ['nullable', 'string', 'max:1000'], ]); $slug = Str::slug($validated['slug'] ?? 'pwa-demo-event'); [$event, $tokenValue] = DB::transaction(function () use ($validated, $slug, $joinTokens) { $tenant = $this->ensureTenant(); $eventType = $this->ensureEventType($validated['event_type'] ?? 'wedding'); $event = Event::updateOrCreate( ['slug' => $slug], [ 'tenant_id' => $tenant->id, 'event_type_id' => $eventType->id, 'name' => [ 'de' => $validated['name'] ?? 'PWA Demo Event', 'en' => $validated['name'] ?? 'PWA Demo Event', ], 'description' => [ 'de' => 'Automatisches Demo-Event für Playwright.', 'en' => 'Automated demo event for Playwright.', ], 'default_locale' => 'de', 'status' => 'published', 'is_active' => true, 'date' => ($validated['date'] ?? Carbon::now()->addWeeks(2)->toDateString()), 'settings' => [ 'branding' => [ 'primary_color' => '#FF5A5F', 'secondary_color' => '#FFF8F5', 'font_family' => 'Inter, sans-serif', ], ], ] ); $taskIds = $this->ensureTasks($tenant->id, $eventType->id, $validated['tasks'] ?? null); if ($taskIds !== []) { $event->tasks()->syncWithoutDetaching($taskIds); } $token = $event->joinTokens()->latest()->first(); if (! $token || ! $token->isActive()) { $token = $joinTokens->createToken($event, [ 'label' => 'Testing Automation', 'metadata' => ['generator' => 'testing_api'], ]); } return [$event, $token?->token]; }); return response()->json([ 'data' => [ 'event_id' => $event->id, 'slug' => $event->slug, 'name' => $event->name, 'join_token' => $tokenValue, ], ]); } private function ensureTenant(): Tenant { $user = User::firstOrCreate( ['email' => 'guest-suite@example.com'], [ 'name' => 'Guest Suite Admin', 'first_name' => 'Guest', 'last_name' => 'Suite', 'password' => Hash::make('Password123!'), 'role' => 'tenant_admin', ] ); $tenant = Tenant::firstOrCreate( ['slug' => 'guest-suite-tenant'], [ 'user_id' => $user->id, 'name' => 'Guest Suite Tenant', 'email' => $user->email, 'is_active' => true, ] ); if (! $user->tenant_id) { $user->forceFill(['tenant_id' => $tenant->id])->save(); } return $tenant; } private function ensureEventType(string $slug): EventType { $slug = Str::slug($slug) ?: 'wedding'; return EventType::updateOrCreate( ['slug' => $slug], [ 'name' => [ 'de' => Str::title($slug), 'en' => Str::title($slug), ], 'settings' => [], ] ); } /** * @return array */ private function ensureTasks(int $tenantId, int $eventTypeId, ?array $payload): array { $definitions = $payload ?: [ [ 'slug' => 'guest-demo-rings', 'title' => 'Ringe im Fokus', 'description' => 'Halte die Ringe oder eure Hände mit einem kreativen Hintergrund fest.', ], [ 'slug' => 'guest-demo-dancefloor', 'title' => 'Tanzfläche in Bewegung', 'description' => 'Zeigt uns eure besten Moves – gerne mit Motion Blur.', ], [ 'slug' => 'guest-demo-cheers', 'title' => 'Cheers!', 'description' => 'Ein Toast-Moment mit Gläsern oder Konfetti.', ], ]; $ids = []; foreach ($definitions as $index => $definition) { $task = Task::updateOrCreate( ['slug' => $definition['slug']], [ 'tenant_id' => $tenantId, 'event_type_id' => $eventTypeId, 'title' => [ 'de' => $definition['title'], 'en' => $definition['title'], ], 'description' => [ 'de' => $definition['description'] ?? $definition['title'], 'en' => $definition['description'] ?? $definition['title'], ], 'instructions' => [ 'de' => 'Creatives Willkommen', 'en' => 'Get creative', ], 'priority' => $index === 0 ? 'high' : 'medium', ] ); $ids[] = $task->id; } return $ids; } }