kithkin/database/migrations/2025_08_21_000000_user_address_improvements.php

79 lines
3.1 KiB
PHP

<?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
{
/**
* 1) addresses per user (supports billing/shipping/home/work/etc.)
* optional link to `locations` for normalized/geocoded data.
*/
Schema::create('user_addresses', function (Blueprint $table) {
$table->bigIncrements('id');
// your users.id is char(26)
$table->char('user_id', 26);
$table->string('label', 100)->nullable(); // "Home", "Office"
$table->string('kind', 20)->nullable(); // "billing", "shipping", "home", "work"
// raw, user-entered fields
$table->string('line1', 255)->nullable();
$table->string('line2', 255)->nullable();
$table->string('city', 100)->nullable();
$table->string('state', 64)->nullable();
$table->string('postal', 32)->nullable();
$table->string('country', 64)->nullable();
$table->string('phone', 32)->nullable();
// optional normalized location
$table->unsignedBigInteger('location_id')->nullable();
// nullable so unique index allows many NULLs (only 1 with value 1)
$table->boolean('is_primary')->nullable()->default(null);
$table->timestamps();
// helpful indexes
$table->index(['user_id', 'kind']);
$table->index('postal');
$table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
$table->foreign('location_id')->references('id')->on('locations')->nullOnDelete();
// enforce at most one primary per (user,kind)
$table->unique(['user_id', 'kind', 'is_primary'], 'user_kind_primary_unique');
});
/**
* 2) lightweight geocoder bias on users (postal/country + optional centroid).
*/
Schema::table('users', function (Blueprint $table) {
$table->string('postal', 32)->nullable()->after('timezone');
$table->string('country', 64)->nullable()->after('postal');
$table->decimal('lat', 9, 6)->nullable()->after('country');
$table->decimal('lon', 9, 6)->nullable()->after('lat');
$table->index('postal');
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
if (Schema::hasColumn('users', 'postal')) $table->dropIndex(['postal']);
foreach (['postal','country','lat','lon'] as $col) {
if (Schema::hasColumn('users', $col)) $table->dropColumn($col);
}
});
Schema::table('user_addresses', function (Blueprint $table) {
if (Schema::hasColumn('user_addresses', 'user_id')) $table->dropForeign(['user_id']);
if (Schema::hasColumn('user_addresses', 'location_id')) $table->dropForeign(['location_id']);
});
Schema::dropIfExists('user_addresses');
}
};