Initial Ladill Queue release — enterprise QMS standalone app.
Deploy Ladill Queue / deploy (push) Successful in 56s
Deploy Ladill Queue / deploy (push) Successful in 56s
Phases 1–6: tickets, counters, displays, appointments, workflows, rules, analytics, reports, feedback, admin, device API, and Gitea deploy workflow for queue.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
*.sqlite*
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Local mirror of the platform identity, keyed by public_id (OIDC sub).
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('public_id')->unique();
|
||||
$table->string('name')->nullable();
|
||||
$table->string('email')->unique();
|
||||
$table->string('avatar_url')->nullable();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password')->nullable();
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
Schema::dropIfExists('sessions');
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('cache', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->mediumText('value');
|
||||
$table->integer('expiration')->index();
|
||||
});
|
||||
|
||||
Schema::create('cache_locks', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->string('owner');
|
||||
$table->integer('expiration')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('cache');
|
||||
Schema::dropIfExists('cache_locks');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
|
||||
Schema::create('job_batches', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('name');
|
||||
$table->integer('total_jobs');
|
||||
$table->integer('pending_jobs');
|
||||
$table->integer('failed_jobs');
|
||||
$table->longText('failed_job_ids');
|
||||
$table->mediumText('options')->nullable();
|
||||
$table->integer('cancelled_at')->nullable();
|
||||
$table->integer('created_at');
|
||||
$table->integer('finished_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
Schema::dropIfExists('job_batches');
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Ladill Queue core schema — multi-branch queue management.
|
||||
*
|
||||
* Hierarchy: owner_ref → Organization → Branch → Department
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('queue_organizations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->string('name');
|
||||
$table->string('slug')->index();
|
||||
$table->string('logo_path')->nullable();
|
||||
$table->string('timezone')->default('UTC');
|
||||
$table->json('settings')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->unique(['owner_ref', 'slug']);
|
||||
});
|
||||
|
||||
Schema::create('queue_branches', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('code')->nullable();
|
||||
$table->string('address')->nullable();
|
||||
$table->string('phone')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('queue_departments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('type')->default('general');
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('queue_members', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->string('user_ref')->index();
|
||||
$table->string('role');
|
||||
$table->foreignId('branch_id')->nullable()->constrained('queue_branches')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
$table->unique(['organization_id', 'user_ref']);
|
||||
});
|
||||
|
||||
Schema::create('queue_audit_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->nullable()->constrained('queue_organizations')->nullOnDelete();
|
||||
$table->string('actor_ref')->nullable();
|
||||
$table->string('action');
|
||||
$table->string('subject_type')->nullable();
|
||||
$table->unsignedBigInteger('subject_id')->nullable();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->string('ip_address')->nullable();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
$table->index(['owner_ref', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('queue_audit_logs');
|
||||
Schema::dropIfExists('queue_members');
|
||||
Schema::dropIfExists('queue_departments');
|
||||
Schema::dropIfExists('queue_branches');
|
||||
Schema::dropIfExists('queue_organizations');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Ladill Queue domain schema — queues, tickets, counters, displays, workflows.
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('queue_service_queues', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->foreignId('department_id')->nullable()->constrained('queue_departments')->nullOnDelete();
|
||||
$table->string('name');
|
||||
$table->text('description')->nullable();
|
||||
$table->string('color', 20)->default('#4f46e5');
|
||||
$table->string('prefix', 10)->default('A');
|
||||
$table->string('strategy')->default('fifo'); // fifo, priority, appointment, vip, emergency, skill, dynamic, overflow
|
||||
$table->unsignedInteger('max_capacity')->nullable();
|
||||
$table->unsignedInteger('avg_service_seconds')->default(300);
|
||||
$table->json('operating_hours')->nullable();
|
||||
$table->json('priority_rules')->nullable();
|
||||
$table->json('settings')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->boolean('is_paused')->default(false);
|
||||
$table->unsignedBigInteger('ticket_sequence')->default(0);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->index(['owner_ref', 'branch_id', 'is_active']);
|
||||
});
|
||||
|
||||
Schema::create('queue_counters', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->foreignId('department_id')->nullable()->constrained('queue_departments')->nullOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('code')->nullable();
|
||||
$table->string('status')->default('offline'); // available, busy, offline, paused
|
||||
$table->json('settings')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('queue_counter_service_queue', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('counter_id')->constrained('queue_counters')->cascadeOnDelete();
|
||||
$table->foreignId('service_queue_id')->constrained('queue_service_queues')->cascadeOnDelete();
|
||||
$table->unsignedSmallInteger('priority')->default(0);
|
||||
$table->unique(['counter_id', 'service_queue_id']);
|
||||
});
|
||||
|
||||
Schema::create('queue_counter_assignments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('counter_id')->constrained('queue_counters')->cascadeOnDelete();
|
||||
$table->string('staff_ref')->index();
|
||||
$table->timestamp('assigned_at')->useCurrent();
|
||||
$table->timestamp('released_at')->nullable();
|
||||
$table->timestamps();
|
||||
$table->index(['counter_id', 'released_at']);
|
||||
});
|
||||
|
||||
Schema::create('queue_staff_sessions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->foreignId('counter_id')->nullable()->constrained('queue_counters')->nullOnDelete();
|
||||
$table->string('staff_ref')->index();
|
||||
$table->timestamp('started_at');
|
||||
$table->timestamp('ended_at')->nullable();
|
||||
$table->json('stats')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('queue_tickets', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->foreignId('service_queue_id')->constrained('queue_service_queues')->cascadeOnDelete();
|
||||
$table->foreignId('counter_id')->nullable()->constrained('queue_counters')->nullOnDelete();
|
||||
$table->string('ticket_number')->index();
|
||||
$table->string('status')->default('waiting'); // waiting, called, serving, on_hold, completed, no_show, cancelled, transferred
|
||||
$table->string('priority')->default('walk_in'); // emergency, vip, elderly, disabled, appointment, walk_in
|
||||
$table->unsignedSmallInteger('position')->nullable();
|
||||
$table->string('customer_name')->nullable();
|
||||
$table->string('customer_phone')->nullable();
|
||||
$table->string('customer_email')->nullable();
|
||||
$table->string('source')->default('kiosk'); // kiosk, reception, mobile, web, api, appointment
|
||||
$table->string('qr_token')->nullable()->unique();
|
||||
$table->string('barcode')->nullable();
|
||||
$table->unsignedInteger('estimated_wait_seconds')->nullable();
|
||||
$table->timestamp('issued_at');
|
||||
$table->timestamp('called_at')->nullable();
|
||||
$table->timestamp('serving_started_at')->nullable();
|
||||
$table->timestamp('completed_at')->nullable();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->index(['owner_ref', 'service_queue_id', 'status']);
|
||||
$table->index(['owner_ref', 'branch_id', 'status', 'issued_at']);
|
||||
});
|
||||
|
||||
Schema::create('queue_ticket_events', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('ticket_id')->constrained('queue_tickets')->cascadeOnDelete();
|
||||
$table->string('event'); // issued, called, recalled, skipped, transferred, held, completed, no_show, cancelled
|
||||
$table->string('actor_ref')->nullable();
|
||||
$table->foreignId('counter_id')->nullable()->constrained('queue_counters')->nullOnDelete();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
$table->index(['ticket_id', 'created_at']);
|
||||
});
|
||||
|
||||
Schema::create('queue_ticket_transfers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('ticket_id')->constrained('queue_tickets')->cascadeOnDelete();
|
||||
$table->foreignId('from_service_queue_id')->constrained('queue_service_queues');
|
||||
$table->foreignId('to_service_queue_id')->constrained('queue_service_queues');
|
||||
$table->foreignId('from_counter_id')->nullable()->constrained('queue_counters')->nullOnDelete();
|
||||
$table->string('reason')->nullable();
|
||||
$table->string('transferred_by')->nullable();
|
||||
$table->timestamp('transferred_at')->useCurrent();
|
||||
});
|
||||
|
||||
Schema::create('queue_queue_rules', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('service_queue_id')->constrained('queue_service_queues')->cascadeOnDelete();
|
||||
$table->string('rule_type'); // overflow, routing, priority_boost, capacity
|
||||
$table->json('conditions')->nullable();
|
||||
$table->json('actions')->nullable();
|
||||
$table->unsignedSmallInteger('sort_order')->default(0);
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('queue_workflows', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->nullable()->constrained('queue_branches')->nullOnDelete();
|
||||
$table->string('name');
|
||||
$table->text('description')->nullable();
|
||||
$table->string('industry_template')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->json('settings')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('queue_workflow_steps', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('workflow_id')->constrained('queue_workflows')->cascadeOnDelete();
|
||||
$table->foreignId('service_queue_id')->nullable()->constrained('queue_service_queues')->nullOnDelete();
|
||||
$table->string('name');
|
||||
$table->unsignedSmallInteger('sort_order')->default(0);
|
||||
$table->json('settings')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('queue_appointments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->foreignId('service_queue_id')->nullable()->constrained('queue_service_queues')->nullOnDelete();
|
||||
$table->foreignId('ticket_id')->nullable()->constrained('queue_tickets')->nullOnDelete();
|
||||
$table->string('customer_name');
|
||||
$table->string('customer_phone')->nullable();
|
||||
$table->string('customer_email')->nullable();
|
||||
$table->string('status')->default('scheduled'); // scheduled, checked_in, completed, cancelled, no_show
|
||||
$table->string('mode')->default('hybrid'); // appointment_only, walk_in_only, hybrid
|
||||
$table->timestamp('scheduled_at');
|
||||
$table->timestamp('checked_in_at')->nullable();
|
||||
$table->string('reference')->nullable();
|
||||
$table->json('metadata')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->index(['owner_ref', 'branch_id', 'scheduled_at']);
|
||||
});
|
||||
|
||||
Schema::create('queue_service_sessions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('ticket_id')->constrained('queue_tickets')->cascadeOnDelete();
|
||||
$table->foreignId('counter_id')->constrained('queue_counters')->cascadeOnDelete();
|
||||
$table->string('staff_ref')->nullable();
|
||||
$table->timestamp('started_at');
|
||||
$table->timestamp('ended_at')->nullable();
|
||||
$table->unsignedInteger('duration_seconds')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('queue_display_screens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->constrained('queue_branches')->cascadeOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('layout')->default('standard'); // standard, compact, split, media
|
||||
$table->string('access_token')->unique();
|
||||
$table->json('service_queue_ids')->nullable();
|
||||
$table->json('settings')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
$table->timestamp('last_seen_at')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('queue_devices', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->nullable()->constrained('queue_branches')->nullOnDelete();
|
||||
$table->string('name');
|
||||
$table->string('type'); // kiosk, tablet, printer, scanner, display, feedback_tablet
|
||||
$table->string('status')->default('offline');
|
||||
$table->string('device_token')->nullable()->unique();
|
||||
$table->json('config')->nullable();
|
||||
$table->timestamp('last_online_at')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
|
||||
Schema::create('queue_voice_announcements', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('branch_id')->nullable()->constrained('queue_branches')->nullOnDelete();
|
||||
$table->foreignId('ticket_id')->nullable()->constrained('queue_tickets')->nullOnDelete();
|
||||
$table->string('locale', 10)->default('en');
|
||||
$table->text('message');
|
||||
$table->string('voice')->nullable();
|
||||
$table->unsignedTinyInteger('volume')->default(80);
|
||||
$table->unsignedTinyInteger('repeat_count')->default(1);
|
||||
$table->string('status')->default('pending'); // pending, played, failed
|
||||
$table->timestamp('played_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('queue_customer_feedback', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->uuid('uuid')->unique();
|
||||
$table->string('owner_ref')->index();
|
||||
$table->foreignId('organization_id')->constrained('queue_organizations')->cascadeOnDelete();
|
||||
$table->foreignId('ticket_id')->constrained('queue_tickets')->cascadeOnDelete();
|
||||
$table->foreignId('counter_id')->nullable()->constrained('queue_counters')->nullOnDelete();
|
||||
$table->unsignedTinyInteger('rating')->nullable();
|
||||
$table->unsignedTinyInteger('service_quality')->nullable();
|
||||
$table->unsignedTinyInteger('wait_experience')->nullable();
|
||||
$table->unsignedTinyInteger('staff_professionalism')->nullable();
|
||||
$table->text('comments')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('queue_customer_feedback');
|
||||
Schema::dropIfExists('queue_voice_announcements');
|
||||
Schema::dropIfExists('queue_devices');
|
||||
Schema::dropIfExists('queue_display_screens');
|
||||
Schema::dropIfExists('queue_service_sessions');
|
||||
Schema::dropIfExists('queue_appointments');
|
||||
Schema::dropIfExists('queue_workflow_steps');
|
||||
Schema::dropIfExists('queue_workflows');
|
||||
Schema::dropIfExists('queue_queue_rules');
|
||||
Schema::dropIfExists('queue_ticket_transfers');
|
||||
Schema::dropIfExists('queue_ticket_events');
|
||||
Schema::dropIfExists('queue_tickets');
|
||||
Schema::dropIfExists('queue_staff_sessions');
|
||||
Schema::dropIfExists('queue_counter_assignments');
|
||||
Schema::dropIfExists('queue_counter_service_queue');
|
||||
Schema::dropIfExists('queue_counters');
|
||||
Schema::dropIfExists('queue_service_queues');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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('notifications', function (Blueprint $table) {
|
||||
$table->uuid('id')->primary();
|
||||
$table->string('type');
|
||||
$table->morphs('notifiable');
|
||||
$table->text('data');
|
||||
$table->timestamp('read_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('notifications');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user