migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
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('restaurant_delivery_zones', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('restaurant_id')->nullable()->index();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->string('color', 7)->default('#3B82F6');
$table->json('coordinates'); // Polygon coordinates
$table->decimal('min_lat', 10, 7)->nullable();
$table->decimal('max_lat', 10, 7)->nullable();
$table->decimal('min_lng', 10, 7)->nullable();
$table->decimal('max_lng', 10, 7)->nullable();
$table->integer('priority')->default(0);
$table->boolean('is_active')->default(true);
$table->boolean('is_default')->default(false);
$table->decimal('max_delivery_distance', 8, 2)->nullable();
$table->json('operating_hours')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['is_active', 'priority']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_delivery_zones');
}
};

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
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('restaurant_zone_pricing_rules', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('restaurant_id')->nullable()->index();
$table->foreignId('zone_id')->constrained('restaurant_delivery_zones')->cascadeOnDelete();
$table->string('name');
$table->integer('priority')->default(1);
$table->boolean('is_active')->default(true);
// Base pricing
$table->decimal('base_fare', 10, 2)->default(30.00);
$table->decimal('minimum_fare', 10, 2)->default(30.00);
$table->decimal('per_km_charge', 10, 2)->default(8.00);
$table->decimal('free_distance', 8, 2)->default(0);
$table->decimal('max_distance', 8, 2)->nullable();
// Surge pricing
$table->boolean('surge_enabled')->default(false);
$table->decimal('surge_multiplier', 4, 2)->default(1.00);
// Conditions
$table->json('conditions')->nullable();
$table->time('valid_from')->nullable();
$table->time('valid_until')->nullable();
$table->integer('valid_days')->nullable(); // Bitmask for days
$table->timestamps();
$table->softDeletes();
$table->index(['zone_id', 'is_active', 'priority']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_zone_pricing_rules');
}
};

View File

@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
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('restaurant_riders', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('restaurant_id')->nullable()->index();
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
// Personal information
$table->string('first_name');
$table->string('last_name');
$table->string('phone')->unique();
$table->string('email')->nullable();
$table->string('photo')->nullable();
$table->date('date_of_birth')->nullable();
$table->string('national_id')->nullable();
$table->string('emergency_contact')->nullable();
// Rider type and status
$table->enum('type', ['internal', 'freelance', 'third_party'])->default('freelance');
$table->enum('status', ['pending', 'active', 'suspended', 'inactive'])->default('pending');
// Vehicle information
$table->enum('vehicle_type', ['bicycle', 'motorcycle', 'car', 'van'])->default('motorcycle');
$table->string('vehicle_number')->nullable();
$table->string('vehicle_model')->nullable();
$table->string('vehicle_color')->nullable();
$table->string('license_number')->nullable();
$table->date('license_expiry')->nullable();
// Verification
$table->boolean('is_verified')->default(false);
$table->timestamp('verified_at')->nullable();
$table->string('verified_by')->nullable();
$table->json('verification_documents')->nullable();
// Commission settings
$table->enum('commission_type', ['fixed', 'percentage', 'per_km', 'hybrid'])->default('percentage');
$table->decimal('commission_rate', 8, 2)->default(70);
$table->decimal('base_commission', 8, 2)->nullable(); // For hybrid
$table->decimal('per_km_rate', 8, 2)->nullable(); // For hybrid
// Current location
$table->decimal('current_latitude', 10, 7)->nullable();
$table->decimal('current_longitude', 10, 7)->nullable();
$table->timestamp('last_location_update')->nullable();
// Stats
$table->decimal('rating', 3, 2)->default(5.00);
$table->unsignedInteger('rating_count')->default(0);
$table->unsignedInteger('total_deliveries')->default(0);
$table->unsignedInteger('successful_deliveries')->default(0);
$table->unsignedInteger('cancelled_deliveries')->default(0);
$table->unsignedInteger('failed_deliveries')->default(0);
$table->decimal('acceptance_rate', 5, 2)->default(100.00);
$table->decimal('completion_rate', 5, 2)->default(100.00);
// Online status
$table->boolean('is_online')->default(false);
$table->timestamp('last_online_at')->nullable();
$table->timestamp('went_offline_at')->nullable();
// Firebase
$table->string('fcm_token')->nullable();
$table->string('device_id')->nullable();
// Banking/Payment
$table->string('bank_name')->nullable();
$table->string('bank_account_number')->nullable();
$table->string('bank_account_name')->nullable();
$table->string('mobile_wallet_number')->nullable();
$table->string('mobile_wallet_provider')->nullable();
// Zones
$table->json('assigned_zones')->nullable();
// Metadata
$table->json('meta')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['is_online', 'status']);
$table->index(['current_latitude', 'current_longitude']);
$table->index('rating');
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_riders');
}
};

View File

@@ -0,0 +1,135 @@
<?php
declare(strict_types=1);
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('restaurant_deliveries', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->string('tracking_code', 20)->unique();
$table->foreignId('restaurant_id')->nullable()->index();
$table->foreignId('rider_id')->nullable()->constrained('restaurant_riders')->nullOnDelete();
$table->foreignId('zone_id')->nullable()->constrained('restaurant_delivery_zones')->nullOnDelete();
// Polymorphic relation to order
$table->morphs('orderable');
// Status
$table->string('status')->default('pending');
$table->string('previous_status')->nullable();
$table->timestamp('status_changed_at')->nullable();
// Restaurant/Pickup details
$table->string('restaurant_name')->nullable();
$table->string('pickup_address');
$table->decimal('pickup_latitude', 10, 7);
$table->decimal('pickup_longitude', 10, 7);
$table->string('pickup_contact_name')->nullable();
$table->string('pickup_contact_phone')->nullable();
$table->text('pickup_instructions')->nullable();
// Customer/Drop details
$table->string('customer_name')->nullable();
$table->string('drop_address');
$table->decimal('drop_latitude', 10, 7);
$table->decimal('drop_longitude', 10, 7);
$table->string('drop_contact_name')->nullable();
$table->string('drop_contact_phone')->nullable();
$table->text('drop_instructions')->nullable();
$table->string('drop_floor')->nullable();
$table->string('drop_apartment')->nullable();
// Distance and time
$table->decimal('distance', 8, 2)->nullable();
$table->string('distance_unit', 10)->default('km');
$table->integer('estimated_duration')->nullable(); // in minutes
$table->timestamp('estimated_pickup_time')->nullable();
$table->timestamp('estimated_delivery_time')->nullable();
// Actual timestamps
$table->timestamp('food_ready_at')->nullable();
$table->timestamp('rider_assigned_at')->nullable();
$table->timestamp('rider_accepted_at')->nullable();
$table->timestamp('rider_at_restaurant_at')->nullable();
$table->timestamp('picked_up_at')->nullable();
$table->timestamp('on_the_way_at')->nullable();
$table->timestamp('arrived_at')->nullable();
$table->timestamp('delivered_at')->nullable();
$table->timestamp('cancelled_at')->nullable();
$table->timestamp('failed_at')->nullable();
// Pricing
$table->decimal('base_fare', 10, 2)->default(0);
$table->decimal('distance_charge', 10, 2)->default(0);
$table->decimal('surge_charge', 10, 2)->default(0);
$table->decimal('surge_multiplier', 4, 2)->default(1.00);
$table->decimal('peak_hour_charge', 10, 2)->default(0);
$table->decimal('late_night_charge', 10, 2)->default(0);
$table->decimal('small_order_fee', 10, 2)->default(0);
$table->decimal('total_delivery_charge', 10, 2)->default(0);
$table->json('charge_breakdown')->nullable();
// Tip
$table->decimal('tip_amount', 10, 2)->default(0);
$table->string('tip_type')->nullable(); // pre_delivery, post_delivery
$table->timestamp('tip_paid_at')->nullable();
// Order value (for small order fee calculation)
$table->decimal('order_value', 10, 2)->default(0);
// Cancellation
$table->string('cancellation_reason')->nullable();
$table->string('cancelled_by')->nullable();
$table->text('cancellation_notes')->nullable();
// Failure
$table->string('failure_reason')->nullable();
$table->text('failure_notes')->nullable();
// Route data
$table->text('route_polyline')->nullable();
$table->json('route_data')->nullable();
// Assignment
$table->unsignedTinyInteger('assignment_attempts')->default(0);
$table->unsignedTinyInteger('reassignment_count')->default(0);
$table->json('assignment_history')->nullable();
// Proof of delivery
$table->string('delivery_photo')->nullable();
$table->string('signature')->nullable();
$table->string('recipient_name')->nullable();
// Customer communication
$table->boolean('customer_notified')->default(false);
$table->json('notification_log')->nullable();
// Priority
$table->boolean('is_priority')->default(false);
$table->boolean('is_scheduled')->default(false);
$table->timestamp('scheduled_for')->nullable();
// Metadata
$table->json('meta')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['status', 'created_at']);
$table->index(['rider_id', 'status']);
$table->index(['restaurant_id', 'status']);
$table->index('tracking_code');
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_deliveries');
}
};

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
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('restaurant_delivery_ratings', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('delivery_id')->constrained('restaurant_deliveries')->cascadeOnDelete();
$table->foreignId('rider_id')->constrained('restaurant_riders')->cascadeOnDelete();
$table->foreignId('customer_id')->nullable()->index();
$table->foreignId('restaurant_id')->nullable()->index();
// Overall rating
$table->unsignedTinyInteger('overall_rating'); // 1-5
// Category ratings
$table->unsignedTinyInteger('speed_rating')->nullable();
$table->unsignedTinyInteger('communication_rating')->nullable();
$table->unsignedTinyInteger('food_condition_rating')->nullable();
$table->unsignedTinyInteger('professionalism_rating')->nullable();
// Review
$table->text('review')->nullable();
$table->boolean('is_anonymous')->default(false);
// Tags (quick feedback)
$table->json('tags')->nullable(); // ['friendly', 'fast', 'careful', 'late', 'rude']
// Restaurant can also rate rider
$table->boolean('is_restaurant_rating')->default(false);
// Moderation
$table->boolean('is_approved')->default(true);
$table->boolean('is_featured')->default(false);
$table->string('moderation_status')->default('approved'); // pending, approved, rejected
$table->text('moderation_notes')->nullable();
// Rider response
$table->text('rider_response')->nullable();
$table->timestamp('rider_responded_at')->nullable();
// Helpful votes (if you want community feedback on reviews)
$table->unsignedInteger('helpful_count')->default(0);
$table->unsignedInteger('not_helpful_count')->default(0);
$table->timestamps();
$table->softDeletes();
$table->index(['rider_id', 'created_at']);
$table->index(['overall_rating']);
$table->unique(['delivery_id', 'is_restaurant_rating'], 'deliv_rating_unique');
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_delivery_ratings');
}
};

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
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('restaurant_delivery_tips', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('delivery_id')->constrained('restaurant_deliveries')->cascadeOnDelete();
$table->foreignId('rider_id')->constrained('restaurant_riders')->cascadeOnDelete();
$table->foreignId('customer_id')->nullable()->index();
$table->foreignId('restaurant_id')->nullable()->index();
// Tip details
$table->decimal('amount', 10, 2);
$table->string('currency', 3)->default('BDT');
$table->enum('type', ['pre_delivery', 'post_delivery'])->default('pre_delivery');
$table->enum('calculation_type', ['fixed', 'percentage'])->default('fixed');
$table->decimal('percentage_value', 5, 2)->nullable(); // If percentage-based
$table->decimal('order_value', 10, 2)->nullable(); // Order value for percentage calculation
// Payment
$table->string('payment_status')->default('pending'); // pending, captured, transferred, failed
$table->string('payment_method')->nullable();
$table->string('payment_reference')->nullable();
$table->timestamp('paid_at')->nullable();
// Distribution
$table->decimal('rider_amount', 10, 2); // Amount rider receives
$table->decimal('platform_amount', 10, 2)->default(0); // Platform fee if any
$table->decimal('rider_share_percentage', 5, 2)->default(100);
// Transferred to rider
$table->boolean('is_transferred')->default(false);
$table->timestamp('transferred_at')->nullable();
$table->foreignId('payout_id')->nullable();
// Message
$table->string('message')->nullable(); // Optional message from customer
$table->timestamps();
$table->softDeletes();
$table->index(['rider_id', 'is_transferred']);
$table->index(['payment_status']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_delivery_tips');
}
};

View File

@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
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('restaurant_rider_earnings', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('rider_id')->constrained('restaurant_riders')->cascadeOnDelete();
$table->foreignId('delivery_id')->nullable()->constrained('restaurant_deliveries')->nullOnDelete();
$table->foreignId('restaurant_id')->nullable()->index();
// Earning type
$table->enum('type', [
'delivery', // Regular delivery earning
'tip', // Tip from customer
'bonus', // Any bonus
'penalty', // Penalty/deduction
'adjustment', // Manual adjustment
'incentive', // Special incentive
])->default('delivery');
// Sub-type for bonuses/penalties
$table->string('sub_type')->nullable(); // peak_hour, rain, consecutive, rating, cancellation, late
// Amount details
$table->decimal('gross_amount', 10, 2);
$table->decimal('platform_fee', 10, 2)->default(0);
$table->decimal('tax', 10, 2)->default(0);
$table->decimal('deductions', 10, 2)->default(0);
$table->decimal('net_amount', 10, 2);
$table->string('currency', 3)->default('BDT');
// Calculation details
$table->json('calculation_breakdown')->nullable();
// Description
$table->string('description')->nullable();
// Status
$table->string('status')->default('pending'); // pending, confirmed, paid, cancelled
$table->timestamp('confirmed_at')->nullable();
// Payout
$table->foreignId('payout_id')->nullable();
$table->boolean('is_paid')->default(false);
$table->timestamp('paid_at')->nullable();
// For weekly/daily reporting
$table->date('earning_date');
$table->unsignedTinyInteger('earning_week')->nullable();
$table->unsignedTinyInteger('earning_month')->nullable();
$table->unsignedSmallInteger('earning_year')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['rider_id', 'status', 'earning_date']);
$table->index(['rider_id', 'type']);
$table->index(['is_paid', 'status']);
$table->index(['earning_date']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_rider_earnings');
}
};

View File

@@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
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('restaurant_rider_payouts', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->string('payout_number')->unique();
$table->foreignId('rider_id')->constrained('restaurant_riders')->cascadeOnDelete();
$table->foreignId('restaurant_id')->nullable()->index();
// Period
$table->date('period_start');
$table->date('period_end');
$table->string('period_type')->default('weekly'); // daily, weekly, monthly
// Amount breakdown
$table->decimal('total_deliveries_amount', 12, 2)->default(0);
$table->decimal('total_tips_amount', 12, 2)->default(0);
$table->decimal('total_bonuses_amount', 12, 2)->default(0);
$table->decimal('total_penalties_amount', 12, 2)->default(0);
$table->decimal('total_adjustments_amount', 12, 2)->default(0);
$table->decimal('gross_amount', 12, 2);
$table->decimal('platform_fees', 12, 2)->default(0);
$table->decimal('tax_deductions', 12, 2)->default(0);
$table->decimal('other_deductions', 12, 2)->default(0);
$table->decimal('net_amount', 12, 2);
$table->string('currency', 3)->default('BDT');
// Stats
$table->unsignedInteger('total_deliveries')->default(0);
$table->unsignedInteger('total_tips_count')->default(0);
$table->unsignedInteger('total_bonuses_count')->default(0);
$table->unsignedInteger('total_penalties_count')->default(0);
// Status
$table->string('status')->default('pending'); // pending, processing, completed, failed, cancelled
// Payment details
$table->string('payment_method')->nullable(); // bank_transfer, bkash, nagad, rocket, cash
$table->string('payment_reference')->nullable();
$table->json('payment_details')->nullable();
/*
Example:
{
"bank_name": "Brac Bank",
"account_number": "****1234",
"transaction_id": "TXN123456"
}
*/
// Timestamps
$table->timestamp('processed_at')->nullable();
$table->timestamp('paid_at')->nullable();
$table->timestamp('failed_at')->nullable();
// Failure handling
$table->string('failure_reason')->nullable();
$table->unsignedTinyInteger('retry_count')->default(0);
// Approval
$table->foreignId('approved_by')->nullable();
$table->timestamp('approved_at')->nullable();
$table->foreignId('processed_by')->nullable();
// Notes
$table->text('notes')->nullable();
$table->json('meta')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['rider_id', 'status']);
$table->index(['status', 'created_at']);
$table->index(['period_start', 'period_end']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_rider_payouts');
}
};

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
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('restaurant_rider_bonuses', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('restaurant_id')->nullable()->index();
// Bonus details
$table->string('name');
$table->string('code')->unique();
$table->text('description')->nullable();
$table->enum('type', [
'peak_hour',
'rain',
'consecutive',
'rating',
'weekly_target',
'monthly_target',
'referral',
'special',
'first_delivery',
'new_area',
]);
// Amount
$table->enum('calculation_type', ['fixed', 'percentage', 'per_delivery', 'per_km'])->default('fixed');
$table->decimal('amount', 10, 2);
// Conditions
$table->json('conditions')->nullable();
/*
Example conditions:
{
"min_deliveries": 5,
"min_rating": 4.8,
"time_window": {"start": "12:00", "end": "14:00"},
"weather_condition": "rain",
"consecutive_count": 5,
"target_deliveries": 50
}
*/
// Validity
$table->boolean('is_active')->default(true);
$table->date('valid_from')->nullable();
$table->date('valid_until')->nullable();
$table->json('valid_days')->nullable(); // Specific days of week
// Limits
$table->unsignedInteger('max_uses_total')->nullable();
$table->unsignedInteger('max_uses_per_rider')->nullable();
$table->unsignedInteger('max_uses_per_day')->nullable();
$table->unsignedInteger('current_uses')->default(0);
// Targeting
$table->json('applicable_zones')->nullable();
$table->json('applicable_rider_types')->nullable();
$table->decimal('min_rider_rating', 3, 2)->nullable();
// Stacking
$table->boolean('is_stackable')->default(false);
$table->json('excluded_bonuses')->nullable();
$table->timestamps();
$table->softDeletes();
$table->index(['type', 'is_active']);
$table->index(['valid_from', 'valid_until']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_rider_bonuses');
}
};

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
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('restaurant_delivery_assignments', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->foreignId('delivery_id')->constrained('restaurant_deliveries')->cascadeOnDelete();
$table->foreignId('rider_id')->constrained('restaurant_riders')->cascadeOnDelete();
$table->foreignId('restaurant_id')->nullable()->index();
// Assignment details
$table->string('status')->default('pending'); // pending, accepted, rejected, expired, cancelled
$table->unsignedTinyInteger('attempt_number')->default(1);
// Assignment method
$table->enum('assignment_type', ['auto', 'manual', 'broadcast'])->default('auto');
$table->foreignId('assigned_by')->nullable(); // User who assigned (for manual)
// Scoring (for auto-assignment)
$table->decimal('score', 8, 2)->nullable();
$table->json('score_breakdown')->nullable();
/*
Example:
{
"distance_score": 35,
"rating_score": 23,
"acceptance_rate_score": 14,
"current_orders_score": 8,
"experience_score": 9,
"total": 89
}
*/
// Distance at time of assignment
$table->decimal('distance_to_restaurant', 8, 2)->nullable();
$table->integer('estimated_arrival_time')->nullable(); // minutes
// Response
$table->timestamp('notified_at')->nullable();
$table->timestamp('responded_at')->nullable();
$table->timestamp('expires_at')->nullable();
$table->string('rejection_reason')->nullable();
$table->text('rejection_notes')->nullable();
// Location at assignment
$table->decimal('rider_latitude', 10, 7)->nullable();
$table->decimal('rider_longitude', 10, 7)->nullable();
$table->timestamps();
$table->index(['delivery_id', 'status']);
$table->index(['rider_id', 'status']);
$table->index(['status', 'expires_at']);
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_delivery_assignments');
}
};

View File

@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
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('restaurant_rider_location_logs', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->nullable()->index();
$table->foreignId('rider_id')->constrained('restaurant_riders')->cascadeOnDelete();
$table->foreignId('delivery_id')->nullable()->constrained('restaurant_deliveries')->nullOnDelete();
// Location
$table->decimal('latitude', 10, 7);
$table->decimal('longitude', 10, 7);
$table->float('speed')->nullable(); // km/h
$table->float('bearing')->nullable(); // degrees
$table->float('accuracy')->nullable(); // meters
$table->float('altitude')->nullable(); // meters
// Battery and device info
$table->unsignedTinyInteger('battery_level')->nullable();
$table->boolean('is_charging')->nullable();
$table->string('network_type')->nullable(); // wifi, 4g, 3g
// Source
$table->string('source')->default('app'); // app, manual, api
$table->timestamp('recorded_at');
$table->timestamps();
// Indexes for efficient querying
$table->index(['rider_id', 'recorded_at']);
$table->index(['delivery_id', 'recorded_at']);
$table->index('recorded_at');
// Partitioning hint - location logs can grow very large
// Consider partitioning by date in production
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_rider_location_logs');
}
};

View File

@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
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('restaurant_delivery_status_history', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->nullable()->index();
$table->foreignId('delivery_id')->constrained('restaurant_deliveries')->cascadeOnDelete();
$table->foreignId('rider_id')->nullable()->constrained('restaurant_riders')->nullOnDelete();
// Status change
$table->string('from_status')->nullable();
$table->string('to_status');
// Who made the change
$table->string('changed_by_type')->nullable(); // rider, customer, restaurant, system, admin
$table->unsignedBigInteger('changed_by_id')->nullable();
// Location at status change
$table->decimal('latitude', 10, 7)->nullable();
$table->decimal('longitude', 10, 7)->nullable();
// Additional data
$table->text('notes')->nullable();
$table->json('meta')->nullable();
// Timing
$table->integer('duration_from_previous')->nullable(); // seconds from previous status
$table->integer('duration_from_start')->nullable(); // seconds from delivery creation
$table->timestamp('changed_at');
$table->timestamps();
$table->index(['delivery_id', 'changed_at']);
$table->index('to_status');
});
}
public function down(): void
{
Schema::dropIfExists('restaurant_delivery_status_history');
}
};