mcpField
L
laravel-migrations

laravel-migrations

github.com/fusengineData & databases3462 installsUpdated 1d ago
Repository

About laravel-migrations

A reference skill for Laravel 13 database migrations, for developers managing schema changes and data setup. It covers Schema Builder operations, constraints, Artisan commands, seeders, migration testing, and production rollout, including pgvector extension setup.

Key features

  1. 01Schema Builder table and column changes
  2. 02Indexes and foreign key constraints
  3. 03Artisan migration commands
  4. 04Seeders and migration testing
  5. 05Production rollout and troubleshooting
  6. 06pgvector extension setup

Use cases

  1. 01Creating or changing database tables
  2. 02Adding indexes and cascading foreign keys
  3. 03Seeding data and testing rollbacks
  4. 04Enabling pgvector in migrations

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/fusengine/claude-plugins --skill laravel-migrations

After installing, type/laravel-migrationsin Claude Code to confirm it loaded.

Details

From the project README
Covers Laravel 13 database migrations: the Schema Builder API for creating/modifying/dropping tables, the 50+ column types and modifiers, index types (primary, unique, fulltext, spatial), foreign key constraints with cascade options, Artisan migration commands, seeders, testing migrations, safe production rollout, troubleshooting, and enabling pgvector via Schema::ensureVectorExtensionExists() for vector columns (see laravel-vector-search for querying them).

Laravel Migrations

Agent Workflow (MANDATORY)

Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:

  1. fuse-ai-pilot:explore-codebase - Check existing migrations
  2. fuse-ai-pilot:research-expert - Verify Laravel 13 patterns via Context7
  3. mcp__context7__query-docs - Check specific Schema Builder features

After implementation, run fuse-ai-pilot:sniper for validation.


Overview

FeatureDescription
Schema BuilderCreate, modify, drop tables
Columns50+ column types with modifiers
IndexesPrimary, unique, fulltext, spatial
Foreign KeysConstraints with cascade options
SeedersPopulate tables with data

Critical Rules

  1. Always define down() - Reversible migrations
  2. Use foreignId()->constrained() - Not raw unsignedBigInteger
  3. Add indexes on foreign keys - Performance critical
  4. Test rollback before deploy - Validate down() works
  5. Never modify deployed migrations - Create new ones

Decision Guide

Migration Type
Need schema change?
├── New table → make:migration create_X_table
├── Add column → make:migration add_X_to_Y_table
├── Modify column → make:migration modify_X_in_Y_table
├── Add index → make:migration add_index_to_Y_table
└── Seed data → make:seeder XSeeder
Column Type Selection
Use CaseTypeExample
Primary Keyid()Auto-increment BIGINT
Foreign KeyforeignId()->constrained()References parent
UUID Primaryuuid()->primary()UUIDs
Booleanboolean()is_active
Enumenum('status', [...])order_status
JSONjson()preferences
Moneydecimal('price', 10, 2)99999999.99
Timestampstimestamps()created_at, updated_at
Soft DeletesoftDeletes()deleted_at
Foreign Key Cascade
ScenarioonDeleteUse Case
Strict integrityrestrictOnDelete()Financial records
Auto-cleanupcascadeOnDelete()Post → Comments
Preserve with nullnullOnDelete()Optional relations
No actionnoActionOnDelete()Audit logs

Reference Guide

Core Concepts
TopicReferenceWhen to Consult
Schemaschema.mdTable operations
Columnscolumns.mdColumn types
Indexesindexes.mdPerformance indexes
Foreign Keysforeign-keys.mdConstraints
Commandscommands.mdArtisan commands
Seedingseeding.mdPopulate data
Advanced Topics
TopicReferenceWhen to Consult
Testingtesting.mdTest migrations
Productionproduction.mdDeploy safely
Troubleshootingtroubleshooting.mdFix errors
Templates
TemplateWhen to Use
CreateTableMigration.php.mdNew table
ModifyTableMigration.php.mdAlter table
PivotTableMigration.php.mdMany-to-many
Seeder.php.mdSeed patterns
MigrationTest.php.mdTest migrations

Quick Reference

Create Table
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->string('title');
    $table->text('content');
    $table->enum('status', ['draft', 'published'])->default('draft');
    $table->timestamps();
    $table->softDeletes();

    $table->index(['user_id', 'status']);
});
Modify Table
Schema::table('posts', function (Blueprint $table) {
    $table->string('slug')->after('title')->unique();
    $table->boolean('featured')->default(false);
});
Commands
php artisan make:migration create_posts_table
php artisan migrate
php artisan migrate:rollback --step=1
php artisan migrate:fresh --seed

Best Practices

DO
  • Use foreignId()->constrained() for foreign keys
  • Add composite indexes for common queries
  • Test down() method before deploying
  • Use --pretend to preview SQL
DON'T
  • Modify already-deployed migrations
  • Forget down() method
  • Use raw SQL without Schema Builder
  • Skip indexes on foreign keys

Laravel 13 Notes

Schema::ensureVectorExtensionExists() (pgvector)

Laravel 13 exposes a helper to enable the pgvector extension on PostgreSQL from a migration. Useful for embeddings and semantic search.

use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    public function up(): void
    {
        Schema::ensureVectorExtensionExists();

        Schema::create('documents', function (Blueprint $table) {
            $table->id();
            $table->text('content');
            $table->vector('embedding', dimensions: 1536)->index(); // OpenAI text-embedding-3-small; HNSW cosine vector index
            $table->timestamps();
            // equivalent: $table->vectorIndex('embedding'); — removal: dropVectorIndex() (13.30+)
        });
    }
};

vector columns/indexes also work on MariaDB 11.7+ (no extension needed). See [[laravel-vector-search]] for whereVectorSimilarTo() queries.

What's new in Schema Builder 13.x
  • $table->foreignUuidFor(User::class) (13.9+) and foreignUlidFor() (13.25+)
  • Lock-free indexes: $table->string('email')->unique()->online(); (PostgreSQL / SQL Server)
  • ->inplace() (13.33+, MySQL) on an index or foreign key for the INPLACE DDL algorithm

Comments

Markdown supported