presseportale/app/Console/Commands/SeedLegacyApiTestdata.php
Kevin Adametz 783b9da9b6 docs: verschobene Doku-Pfade in Code-Kommentaren nachgezogen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 07:53:08 +00:00

213 lines
8 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Enums\CompanyType;
use App\Enums\PaymentOptionType;
use App\Enums\Portal;
use App\Enums\RegistrationType;
use App\Enums\UserPaymentOptionStatus;
use App\Models\Category;
use App\Models\Company;
use App\Models\PaymentOption;
use App\Models\User;
use App\Models\UserPaymentOption;
use App\Services\Api\LegacyApiKeyImporter;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Spatie\Permission\Models\Permission;
/**
* Legt einen API-Testkunden nach connektar-Muster an (S4 der Paritäts-Doku
* dev/betrieb/api-legacy-paritaet.md): aktiver Bestandskunde mit Grandfathering,
* importiertem Legacy-Key, Sofort-Publish-Recht, Firma + Pressekontakt — und
* gibt Key + fertige curl-Sammlung für den /service-Flow aus.
*
* Idempotent: wiederholte Läufe erneuern nur den API-Key. Nur local/staging.
*/
class SeedLegacyApiTestdata extends Command
{
protected $signature = 'legacy:seed-api-testdata
{--portal=businessportal24 : Portal des Testkunden (businessportal24|presseecho)}
{--email=api-test@pressekonto.test : E-Mail des Testkunden}';
protected $description = 'API-Testdaten nach connektar-Muster anlegen (Legacy-Key, Firma, Kontakt) + curl-Sammlung ausgeben.';
public function handle(LegacyApiKeyImporter $importer): int
{
if (app()->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(<<<CURL
# --- connektar-Flow (Alt-Vertrag, dev/betrieb/api-legacy-paritaet.md §1) ---
# 1. Firma anlegen
curl -s -i -X POST '{$host}/service/users/me/companies' \\
-H 'X-ApiKey: {$apiKey}' \\
-d 'company[name]=Neue Testfirma GmbH' \\
-d 'company[address]=Musterweg 2, 33602 Bielefeld' \\
-d 'company[country_id]=177' \\
-d 'company[email]=info@neue-testfirma.example'
# 2. Pressekontakt anlegen (COMPANY_ID aus Location-Header von Schritt 1)
curl -s -i -X POST '{$host}/service/users/me/companies/COMPANY_ID/contacts' \\
-H 'X-ApiKey: {$apiKey}' \\
-d 'contact[salutation_id]=1' \\
-d 'contact[first_name]=Erika' \\
-d 'contact[last_name]=Beispiel' \\
-d 'contact[email]=presse@neue-testfirma.example'
# 3. PM anlegen (= einreichen; mit Sofort-Publish geht sie direkt live)
curl -s -i -X POST '{$host}/service/pressreleases' \\
-H 'X-ApiKey: {$apiKey}' \\
-d 'press_release[company_id]={$company->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;
}
}