本文へ移動
cccskills
無料GitHub で公開

laravel-migration

Use when creating a Laravel migration — table prefixes, column naming, multi-tenant awareness, php artisan make:migration. Other stacks: use stack-native migration tooling.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.4 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

laravel-migration

When to use

Use this skill when the user asks to create a database migration, add a column, create a table, or modify the schema.

Procedure: Create a migration

  1. Read conventions — Check ./agents/ and AGENTS.md for table prefixes, column naming, multi-tenant setup.
  2. Generate migration — php artisan make:migration create_xyz_table (or add_column, etc.).
  3. Write schema — Follow naming conventions, add indexes for WHERE/JOIN columns, use decimal for money.
  4. Verify — Run migration (php artisan migrate), then rollback (php artisan migrate:rollback) to confirm reversibility.

All projects

  • Use decimal for money — never float.
  • Add indexes for columns used in WHERE clauses and JOINs.
  • Match existing column naming patterns in the same table or domain.
  • Declare recovery: a reversible down(), or a roll-forward plan in the file (see § The recovery contract below). Silence is the violation.

Laravel projects

Multi-database architecture

Some projects use multiple database connections. Check config/database.php for connections.

CheckHow
Available connectionsconfig/database.php → 'connections' array
Migration directoriesdatabase/migrations/ (default), check for additional directories
Custom migrate commandsphp artisan list migrate — look for project-specific commands

Always determine which database the table belongs to before creating a migration.

API database migration

php artisan make:migration create_example_table
return new class extends Migration {
    public function up(): void
    {
        Schema::connection('api_database')->create('example_table', function (Blueprint $table): void {
            $table->id();
            $table->unsignedBigInteger('customer_id');
            $table->string('name');
            $table->boolean('is_active')->default(true);
            $table->timestamps();
            $table->softDeletes();

            $table->foreign('customer_id')
                ->references('id')
                ->on('customers')
                // Choose the referential action; never inherit it from a
                // template. See "Referential action is a decision" below.
                ->onDelete('cascade'); // cascade: rows here are expendable
                                       // WITHOUT their customer

            $table->index('is_active');
        });
    }

    public function down(): void
    {
        Schema::connection('api_database')->dropIfExists('example_table');
    }
};

Customer database migration

php artisan make:migration:customer AddWeatherColumn --table=cl_lv_weather

Customer database tables use the cl_ prefix (e.g. cl_user, cl_lv_weather).

Adding a column (with explicit connection)

return new class extends Migration {
    public function up(): void
    {
        Schema::connection('my_connection')->table('example', function (Blueprint $table): void {
            $table->unsignedInteger('new_column')->after('existing_column');
        });
    }

    public function down(): void
    {
        Schema::connection('my_connection')->table('example', function (Blueprint $table): void {
            $table->dropColumn('new_column');
        });
    }
};

Running migrations

# Default connection
php artisan migrate                           # development
php artisan migrate --env=testing             # testing

# Multi-tenant / custom — check AGENTS.md or module docs for project-specific commands
# Example: php artisan migrate:tenants, php artisan migrate --database=tenant

Composer / legacy projects

  • Check where existing migrations live (e.g. core/migrations/).
  • Use the existing migration format and naming conventions in the project.

Column conventions

  • Foreign keys: {entity}_id (e.g. customer_id, user_id)
  • Booleans: is_ prefix (e.g. is_active, is_default)
  • Dates: descriptive suffix (e.g. upload_date, deleted_at)
  • Always use unsignedBigInteger for foreign keys referencing id() columns
  • Use ->after('column') to place new columns logically

Output format

  1. Migration file with up() and down() methods
  2. Model updates if columns or relationships changed

The recovery contract — one obligation, two branches

Every migration declares one of these, and silence is the violation:

  1. a down() that restores the prior state; or
  2. a roll-forward recovery plan, written in the migration file itself, for the cases where restoration is genuinely impossible — a completed destructive backfill, a dropped column whose data is gone.

The second branch is not a lighter obligation. A migration taking it records, in its own file comments, all three of:

  1. why restoration is impossible, with the evidence — the data was checked and is unrecoverable, not assumed to be;
  2. the ordered recovery procedure — the steps, the inputs each needs, and the criteria that say recovery succeeded;
  3. the responsible recovery owner.

Vague intent or missing detail is the violation. The plan lives in the migration file and lands in the same diff, because a plan documented "later" somewhere else is a plan nobody can review at the moment it matters.

Referential action is a decision

The template above labels its onDelete('cascade') as one branch, not a default. Copying it unchanged is how a delete of one customer silently removes records that had independent value.

The child row, without its parent, isActionWhat happens
expendable — it only means something as part of the parentcascadedeleted with the parent
self-valued — it is a record in its own right (an invoice, an audit row, a payment)restrict (or no action)the parent delete FAILS until the child is dealt with
survivable — it outlives the parent with the link removedset nullthe column is nulled; requires a nullable column

Two consequences worth stating because they are the ones missed:

  • restrict is the safe default for anything a finance, audit, or legal reader would expect to still exist. A failed delete is a conversation; a cascaded delete is a recovery.
  • set null needs the foreign-key column to be nullable, and it needs the application to handle the orphan state. Choosing it without both is choosing a constraint error later.

Soft deletes do not interact with this: onDelete fires on a real DELETE, so a soft-deleting parent never triggers it. If the model soft-deletes, the referential action describes what happens on a force-delete or a purge, and that is the case to decide against.

Gotcha

  • Always check if the table/column already exists before creating the migration — the model doesn't always check.
  • Multi-tenant migrations need special handling — customer tables use different prefixes.
  • Don't modify existing migrations that have been deployed — create a new migration instead.
  • The model forgets ->after('column') for column ordering — MariaDB respects it, and it matters for readability.

Do NOT

  • Do NOT create migrations without specifying the correct connection when multiple databases exist.
  • Do NOT create tables without checking the project's naming conventions (prefixes, casing).
  • Do NOT use raw SQL in migrations when Schema builder works.
  • Do NOT leave recovery undeclared — ship a down() that restores the prior state, or the three-part roll-forward plan in the migration file. Neither is optional; choosing between them is.
  • Do NOT use float for money — use decimal.
  • Do NOT forget indexes on foreign keys and frequently filtered columns.

Adversarial review

Before finalizing a migration, run the adversarial-review skill. Focus on the "Database migrations" attack questions: Can this destroy data? Is rollback possible?

Auto-trigger keywords

  • database migration
  • create migration
  • table prefix
  • column naming
  • add column
  • create table

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.

日本語の概要は準備中です。原文の説明を表示しています。

event4u-app/agent-config112026年10月13日 更新

Use when defining or auditing the activation event — aha-moment selection, retention correlation, falsifiable definition. Triggers on 'what is our aha moment', 'redefine activation'.

日本語の概要は準備中です。原文の説明を表示しています。

event4u-app/agent-config112026年10月13日 更新

Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'.

日本語の概要は準備中です。原文の説明を表示しています。

event4u-app/agent-config112026年10月13日 更新

Adversarial critique — devil's advocate, stress-test, honest teardown ('poke holes', 'be brutal', 'was hältst du davon'); explicit request only. Routine code or design review → code-review.

日本語の概要は準備中です。原文の説明を表示しています。

event4u-app/agent-config112026年10月13日 更新

Use when reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md. Understands the full .augment/, agents/, and copilot-instructions structure.

日本語の概要は準備中です。原文の説明を表示しています。

event4u-app/agent-config112026年10月13日 更新

Use for an adversarial red-team / blue-team / auditor review of an AI agent's CONFIG + behaviour (rules, skills, MCP, hooks, permissions) — attack-chain → defensive-gap list, not a code audit.

日本語の概要は準備中です。原文の説明を表示しています。

event4u-app/agent-config112026年10月13日 更新

event4u-app のスキルをすべて見る

このスキルの問題を報告する