environment('production')) { $this->error('Nur fuer local/staging — nicht in Produktion ausfuehren.'); return self::FAILURE; } $portal = (string) $this->option('portal'); if (! in_array($portal, [Portal::Businessportal24->value, Portal::Presseecho->value], true)) { $this->error('Ungueltiges Portal: '.$portal); return self::FAILURE; } $email = (string) $this->option('email'); $legacyId = 999901; // 1. Testkunde: aktiver Legacy-API-User (wie connektar). $user = User::query()->firstOrCreate( ['email' => $email], [ 'name' => 'API Testkunde', 'password' => Hash::make('password'), 'email_verified_at' => now(), ], ); $user->forceFill([ 'is_active' => true, 'portal' => $portal, 'legacy_portal' => $portal, 'legacy_id' => $legacyId, 'registration_type' => RegistrationType::ApiUser, 'agency_name' => 'API Testverteiler', ])->save(); if (! $user->hasRole('customer')) { $user->assignRole('customer'); } // 2. Grandfathering (Bestandsschutz): macht den User API-berechtigt // und laesst das Buchungs-Gate passieren. $paymentOption = PaymentOption::query()->firstOrCreate( ['article_number' => 'ART-API-TEST'], [ 'type' => PaymentOptionType::cases()[0]->value, 'price_cents' => 0, 'currency' => 'EUR', 'interval' => 'monthly', 'is_hidden' => true, ], ); UserPaymentOption::query()->updateOrCreate( ['user_id' => $user->id, 'payment_option_id' => $paymentOption->id], [ 'status' => UserPaymentOptionStatus::Grandfathered->value, 'grandfathered_until' => null, 'current_period_start' => now()->subMonth(), 'current_period_end' => now()->addMonths(11), 'stripe_subscription_id' => null, ], ); // 3. Sofort-Publish-Privileg (Alt-Verhalten von connektar). Die // Permission defensiv anlegen — lokale DBs sind nicht immer auf dem // juengsten Seeder-Stand. Permission::firstOrCreate(['name' => 'api:immediate-publication']); if (! $user->hasPermissionTo('api:immediate-publication')) { $user->givePermissionTo('api:immediate-publication'); } // 4. Firma + Pressekontakt (der API-Flow kann weitere anlegen). $company = Company::withoutGlobalScopes()->firstOrNew( ['name' => 'API Test GmbH', 'portal' => $portal], [ 'type' => CompanyType::Company->value, 'address' => "Teststrasse 1\n33602 Bielefeld", 'country_code' => 'DE', 'email' => 'firma@api-test.example', 'website' => 'https://api-test.example', 'is_active' => true, ], ); if (! $company->slug) { $company->slug = $company->generateUniqueSlug($company->name); } $company->owner_user_id ??= $user->id; $company->save(); if (! $company->users()->whereKey($user->id)->exists()) { $company->users()->attach($user->id, ['role' => 'owner']); } $contact = $company->contacts()->firstOrCreate( ['email' => 'presse@api-test.example'], [ 'portal' => $portal, 'salutation_key' => 'mr', 'first_name' => 'Max', 'last_name' => 'Mustermann', 'responsibility' => 'Pressestelle', ], ); // 5. Legacy-API-Key erneuern (wie legacy:import-api-keys). $apiKey = 'test-'.Str::random(40); $user->tokens()->delete(); $importer->import($portal, [ ['legacy_id' => $legacyId, 'api_key' => $apiKey], ]); $category = Category::withoutGlobalScopes()->where('is_active', true)->first(); $host = rtrim((string) config("domains.domains.{$portal}.url", config('app.url')), '/'); $this->info('API-Testkunde bereit.'); $this->table(['Feld', 'Wert'], [ ['Login (Panel)', $email.' / password'], ['Portal', $portal], ['X-ApiKey', $apiKey], ['Firma', "#{$company->id} {$company->name}"], ['Pressekontakt', "#{$contact->id} {$contact->first_name} {$contact->last_name}"], ['Kategorie (legacy_id)', $category ? "#{$category->legacy_id}" : '— (keine aktive Kategorie!)'], ['Sofort-Publish', 'ja (api:immediate-publication)'], ]); $categoryId = $category?->legacy_id ?? 1; $this->line(<<id}' \\ -d 'press_release[category_id]={$categoryId}' \\ -d 'press_release[language]=de' \\ -d 'press_release[title]=Testmeldung ueber die Legacy-API' \\ -d 'press_release[text]=Dies ist eine Testmeldung aus der Legacy-API-Kompatibilitaetsschicht.' \\ -d 'press_release[contacts_list][]={$contact->id}' # 4. Bild hochladen (PM_ID aus Location-Header von Schritt 3) curl -s -i -X POST '{$host}/service/pressreleases/PM_ID/images' \\ -H 'X-ApiKey: {$apiKey}' \\ -F 'press_release_image[image]=@pressefoto.jpg' \\ -F 'press_release_image[copyright]=API Test GmbH' # 5. Veroeffentlichungs-Kontrolle (404 = noch nicht veroeffentlicht) curl -s '{$host}/service/pressreleases/PM_ID' -H 'X-ApiKey: {$apiKey}' CURL); $this->newLine(); $this->comment('Hinweis: Schalter "KI-Pruefung Legacy-API" auf /admin/press-releases steuert Sofort-Publish vs. KI-Review.'); return self::SUCCESS; } }