feat(addons): finalize event addon catalog and ai styling upgrade flow
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('package_addons')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = Carbon::now();
|
||||
$existing = DB::table('package_addons')
|
||||
->where('key', 'ai_styling_unlock')
|
||||
->first();
|
||||
|
||||
$metadata = $this->mergeMetadata($existing?->metadata ?? null);
|
||||
|
||||
if (! $existing) {
|
||||
DB::table('package_addons')->insert([
|
||||
'key' => 'ai_styling_unlock',
|
||||
'label' => 'AI Styling Add-on',
|
||||
'variant_id' => null,
|
||||
'extra_photos' => 0,
|
||||
'extra_guests' => 0,
|
||||
'extra_gallery_days' => 0,
|
||||
'active' => true,
|
||||
'sort' => 42,
|
||||
'metadata' => json_encode($metadata, JSON_UNESCAPED_UNICODE),
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('package_addons')
|
||||
->where('id', $existing->id)
|
||||
->update([
|
||||
'label' => $existing->label ?: 'AI Styling Add-on',
|
||||
'sort' => $existing->sort ?: 42,
|
||||
'metadata' => json_encode($metadata, JSON_UNESCAPED_UNICODE),
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function mergeMetadata(mixed $metadata): array
|
||||
{
|
||||
if (is_string($metadata)) {
|
||||
$decoded = json_decode($metadata, true);
|
||||
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
$metadata = $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
$metadata = is_array($metadata) ? $metadata : [];
|
||||
$entitlements = Arr::get($metadata, 'entitlements');
|
||||
$entitlements = is_array($entitlements) ? $entitlements : [];
|
||||
$features = Arr::get($entitlements, 'features', []);
|
||||
$features = is_array($features) ? $features : [];
|
||||
$features[] = 'ai_styling';
|
||||
|
||||
$entitlements['features'] = array_values(array_unique(array_filter(array_map(
|
||||
static fn (mixed $feature): string => trim((string) $feature),
|
||||
$features,
|
||||
))));
|
||||
|
||||
if (! is_numeric(Arr::get($metadata, 'price_eur'))) {
|
||||
$metadata['price_eur'] = 9;
|
||||
}
|
||||
|
||||
if (! is_string(Arr::get($metadata, 'scope')) || trim((string) Arr::get($metadata, 'scope')) === '') {
|
||||
$metadata['scope'] = 'feature';
|
||||
}
|
||||
|
||||
$metadata['entitlements'] = $entitlements;
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
};
|
||||
@@ -142,6 +142,7 @@ class PackageAddonSeeder extends Seeder
|
||||
'sort' => 42,
|
||||
'metadata' => [
|
||||
'price_eur' => 9,
|
||||
'scope' => 'feature',
|
||||
'entitlements' => [
|
||||
'features' => ['ai_styling'],
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user