213 lines
8 KiB
PHP
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;
|
|
}
|
|
}
|