Package system sms
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('packages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('type'); // sms, email, archive, segment
|
||||
$table->string('status')->default('draft'); // draft, queued, running, completed, failed, canceled
|
||||
$table->string('name')->nullable();
|
||||
$table->text('description')->nullable();
|
||||
$table->json('meta')->nullable();
|
||||
$table->unsignedInteger('total_items')->default(0);
|
||||
$table->unsignedInteger('processing_count')->default(0);
|
||||
$table->unsignedInteger('sent_count')->default(0);
|
||||
$table->unsignedInteger('failed_count')->default(0);
|
||||
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
|
||||
$table->timestamp('finished_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['type', 'status']);
|
||||
$table->index(['created_by']);
|
||||
$table->index(['finished_at']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('packages');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('package_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('package_id')->constrained('packages')->cascadeOnDelete();
|
||||
$table->string('status')->default('queued'); // queued, processing, sent, failed, canceled, skipped
|
||||
$table->json('target_json'); // e.g., {"phone_id": 1, "number": "+386..."}
|
||||
$table->json('payload_json')->nullable(); // per-item overrides and variables
|
||||
$table->unsignedTinyInteger('attempts')->default(0);
|
||||
$table->text('last_error')->nullable();
|
||||
$table->json('result_json')->nullable();
|
||||
$table->string('provider_message_id')->nullable();
|
||||
$table->decimal('cost', 10, 4)->nullable();
|
||||
$table->string('currency', 10)->nullable();
|
||||
$table->string('idempotency_key')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['package_id', 'status']);
|
||||
$table->unique(['idempotency_key']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('package_items');
|
||||
}
|
||||
};
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$driver = DB::getDriverName();
|
||||
if ($driver === 'pgsql') {
|
||||
// Create PostgreSQL enum type for phone_type if not exists
|
||||
DB::statement(<<<'SQL'
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'phone_type_enum') THEN
|
||||
CREATE TYPE phone_type_enum AS ENUM ('mobile', 'landline', 'voip');
|
||||
END IF;
|
||||
END$$;
|
||||
SQL);
|
||||
}
|
||||
|
||||
Schema::table('person_phones', function (Blueprint $table): void {
|
||||
// validated flag (default false)
|
||||
if (! Schema::hasColumn('person_phones', 'validated')) {
|
||||
$table->boolean('validated')->default(false)->after('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Add phone_type column depending on driver
|
||||
$hasPhoneType = $driver === 'pgsql'
|
||||
? (bool) DB::selectOne("SELECT 1 as exists FROM information_schema.columns WHERE table_name = 'person_phones' AND column_name = 'phone_type'")
|
||||
: Schema::hasColumn('person_phones', 'phone_type');
|
||||
if (! $hasPhoneType) {
|
||||
if ($driver === 'pgsql') {
|
||||
// enum-typed column for Postgres
|
||||
DB::statement('ALTER TABLE person_phones ADD COLUMN phone_type phone_type_enum NULL');
|
||||
} else {
|
||||
// Fallback for sqlite/mysql in tests/dev: simple string column
|
||||
Schema::table('person_phones', function (Blueprint $table): void {
|
||||
$table->string('phone_type', 20)->nullable()->after('validated');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$driver = DB::getDriverName();
|
||||
// Drop column phone_type if exists
|
||||
$hasPhoneType = $driver === 'pgsql'
|
||||
? (bool) DB::selectOne("SELECT 1 as exists FROM information_schema.columns WHERE table_name = 'person_phones' AND column_name = 'phone_type'")
|
||||
: Schema::hasColumn('person_phones', 'phone_type');
|
||||
if ($hasPhoneType) {
|
||||
if ($driver === 'pgsql') {
|
||||
DB::statement('ALTER TABLE person_phones DROP COLUMN phone_type');
|
||||
} else {
|
||||
Schema::table('person_phones', function (Blueprint $table): void {
|
||||
$table->dropColumn('phone_type');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Schema::table('person_phones', function (Blueprint $table): void {
|
||||
if (Schema::hasColumn('person_phones', 'validated')) {
|
||||
$table->dropColumn('validated');
|
||||
}
|
||||
});
|
||||
|
||||
if ($driver === 'pgsql') {
|
||||
// Drop type if no longer used (best-effort)
|
||||
DB::statement(<<<'SQL'
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'phone_type_enum') THEN
|
||||
-- ensure no remaining dependencies
|
||||
EXECUTE 'DROP TYPE phone_type_enum';
|
||||
END IF;
|
||||
END$$;
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user