본문으로 건너뛰기
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

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

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-config122026년 10월 20일 업데이트

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-config122026년 10월 20일 업데이트

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-config122026년 10월 20일 업데이트

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-config122026년 10월 20일 업데이트

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-config122026년 10월 20일 업데이트

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-config122026년 10월 20일 업데이트

event4u-app의 스킬 모두 보기

이 스킬의 문제 신고