agentleFS
muon-m2muon-m2/magento2-tools/skills/data-migration/SKILL.md

data-migration

Skill6 starsChanged 28 days agoMITView on GitHub

Generate data patches, importer services, and transformation scripts. - Idempotent. Re-running setup:upgrade must NOT duplicate data. Check for existing state before inserting. - DataPatchInterface only. No legacy Setup/InstallData.php or UpgradeData.php. - Chunked for bulk. Imports of > 100 rows must process in batches of ≤ 500. - Transactional for transformations. SELECT → INSERT → DELETE wrapped in a single DB transaction (where possible). - Reversible when feasible. Patches that delete data must document the rollback path (or refuse to delete…

We split this skill into the rules it gives an agent

11 rules. 0 are common, 6 are distinctive, and 5 are very specific to this project.

  • 0

    Common

    Most of the 8 edited versions we read keep these.

  • 6

    Distinctive

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    DataPatchInterface only: No legacy Setup/InstallData.php or UpgradeData.php.

    line 20
  2. Distinctive:

    Test-first for the data effect: Write the failing integration test before the patch body (red → green → refactor) and watch it fail for the …

    line 26
  3. Distinctive:

    Ask the user for:

    line 57
  4. Very specific:

    2A — Write the failing test (RED): Before any patch code, add an integration test under Test/Integration/ that asserts the post-migration …

    line 65
  5. Distinctive:

    unit: test of the importer's idempotency guard (lookup-then-insert) instead, and record the integration gap in the Phase 4 report.

    line 72
  6. Distinctive:

    2B — Generate the patch (GREEN): Write the minimal patch needed to turn 2A green:

    line 75
  7. Very specific:

    Run the Phase 2A test with {ctx.runner} vendor/bin/phpunit and confirm it now passes (it failed before 2B).

    line 98
  8. Very specific:

    Apply the shared module-hygiene baseline (required): After generating or modifying PHP files, run …

    line 102
  9. Distinctive:

    Test path + red→green evidence (or the recorded integration gap if a test DB was unavailable)

    line 117
  10. Very specific:

    All generated patches implement DataPatchInterface and getDependencies().

    line 180
  11. Distinctive:

    All patches are idempotent.

    line 181

“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Magento 2 Data Migration

Generate data patches, importer services, and transformation scripts.

Core Rules

  • Idempotent. Re-running setup:upgrade must NOT duplicate data. Check for existing state before inserting.
  • DataPatchInterface only. No legacy Setup/InstallData.php or UpgradeData.php.
  • Chunked for bulk. Imports of > 100 rows must process in batches of ≤ 500.
  • Transactional for transformations. SELECT → INSERT → DELETE wrapped in a single DB transaction (where possible).
  • Reversible when feasible. Patches that delete data must document the rollback path (or refuse to delete without --allow-destructive).
  • Test-first for the data effect. Write the failing integration test before the patch body (red → green → refactor) and watch it fail for the right reason. The test asserts the post-migration state and, critically, idempotency (apply twice → identical state). The patch exists only to turn that test green. See context/references/tdd-discipline.md. A patch is exempt only when it is pure config with no data effect — document why.
  • Coding style. Generated PHP follows PER-CS 3.0 as the baseline, with the Magento 2 coding standard taking precedence on any conflict; --standard=Magento2 PHPCS is the gate. See context/references/php-coding-style.md.
  • Source of truth. Generate from templates → shared references → baked-in Magento 2 knowledge → official Magento/Adobe docs (live-fetched only when uncertain). Do NOT read, grep, or "study" other modules under app/code/vendor/*/Magento core to infer conventions, entity shapes, naming, or wiring. Narrow exceptions: the target module/class of this operation, and the specific contract of a module this code explicitly depends on. Affirm sources in the final report. See context/references/source-of-truth.md.

Workflow

Phase 0 — Context Resolution

Invoke context.

Phase 1 — Plan

Determine migration class:

ClassWhen
Fixed seedSmall, known data (< 100 rows hard-coded in PHP)
Bulk importCSV/JSON, > 100 rows from an external source
TransformationMove/rename existing data inside Magento

Ask the user for:

  • Data source (file path, API endpoint, M1 DB connection details)
  • Target tables / entities
  • Idempotency strategy (hash, unique constraint, lookup-then-insert)
  • Whether rollback is required

Phase 2 — Test First, then Generate

2A — Write the failing test (RED). Before any patch code, add an integration test under Test/Integration/ that asserts the post-migration state and idempotency (run the patch twice → identical rows, no duplicates, no error). Start from test-generate/templates/test-integration-data-patch.php and follow context/references/tdd-discipline.md. Run it and confirm it fails for the right reason (data absent / patch class missing) — not a setup or missing-class error. If no Magento test DB is available, follow the tiered fallback in tdd-discipline.md: write a test-first unit test of the importer's idempotency guard (lookup-then-insert) instead, and record the integration gap in the Phase 4 report.

2B — Generate the patch (GREEN). Write the minimal patch needed to turn 2A green:

Fixed seed

  • Setup/Patch/Data/{Name}.php with the data inline.

Bulk import

  • Setup/Patch/Data/{Name}.php invoking…
  • Service/Importer/{Name}Importer.php — chunked processing, idempotency checks
  • Optional Console/Command/{Name}Command.php — CLI entry point (bin/magento {vendor}:{module}:import [--dry-run])

Transformation

  • Setup/Patch/Data/{Name}.php with SELECT → INSERT → DELETE inside a transaction.
  • Idempotency: check whether destination already has the migrated row before inserting.

2C — Refactor. With the test green, tidy only what you touched; keep it green.

Phase 3 — Verify

  • php -l on each file.
  • Run the Phase 2A test with {ctx.runner} vendor/bin/phpunit and confirm it now passes (it failed before 2B). Run the affected module's suite to confirm nothing else broke.
  • Dry-run: optional --dry-run flag on generated CLI command outputs what would be imported without writing.
  • Apply the shared module-hygiene baseline (required). After generating or modifying PHP files, run ${CLAUDE_PLUGIN_ROOT}/skills/context/scripts/add-license-headers.sh {ctx.magento_root}/app/code/{Vendor}/{Module} {Vendor} to stamp the standard copyright header onto every new .php (idempotent — it skips files that already carry it). When adding a composer.json require entry, resolve a bounded constraint via ${CLAUDE_PLUGIN_ROOT}/skills/context/scripts/resolve-dep-constraint.sh <vendor/package> — never "*". See context/references/module-hygiene.md.

Phase 4 — Report

Save to {output_root}/migrations/{name}-{date}.md:

  • Source described
  • Target tables / entities
  • Idempotency strategy
  • Test path + red→green evidence (or the recorded integration gap if a test DB was unavailable)
  • Re-run safety statement
  • Rollback statement (if feasible)
  • Migration command for the user to run

Docs may now be stale. This change modified module code. Run docs --module={Vendor}_{Module} to refresh the module's README, CHANGELOG, and docs/*.md (technical reference, guides, and API references as applicable).

Inputs

/data-migration --type=seed|import|transform [source flags] [--docs-root=<path>]

--docs-root=<path> — output-root override; see "Output root" below.

Outputs

{ctx.magento_root}/app/code/{Vendor}/{Module}/Setup/Patch/Data/{Name}.php
{ctx.magento_root}/app/code/{Vendor}/{Module}/Service/Importer/{Name}Importer.php        # if import
{ctx.magento_root}/app/code/{Vendor}/{Module}/Console/Command/{Name}Command.php          # if CLI
{ctx.magento_root}/app/code/{Vendor}/{Module}/Test/Integration/Setup/Patch/Data/{Name}Test.php  # test-first (Phase 2A)

{output_root}/migrations/{name}-{date}.md

{output_root} defaults to .docs ({ctx.docs_root}), anchored at the project root, never under {ctx.magento_root}, app/code, or a module dir. See the Artifact location rule in context/SKILL.md.

Output root (--docs-root)

This skill accepts --docs-root=<path> (see context/references/artifact-layout.md). When set, write the run report (and any report artifacts) under <path>/migrations/; otherwise default to {ctx.docs_root}/migrations/. feature passes this so a feature run's reports collect under its folder.

Reference Files

  • references/data-patch-rules.md — DataPatchInterface idempotency rules.
  • references/importer-patterns.md — chunked import patterns.
  • references/m1-to-m2-map.md — common Magento 1 → 2 transformations.
  • references/idempotency-strategies.md — hash-based, unique-constraint, lookup-then-insert.
  • references/rollback-strategies.md — when rollback is feasible; how to implement.
  • context/references/tdd-discipline.md — shared test-first loop; the Phase 2A test reuses test-generate/templates/test-integration-data-patch.php as its skeleton.
  • context/references/source-of-truth.md — source-of-truth hierarchy + the no-unrelated-module-scanning rule (allowed reads, live-doc fetch protocol, report affirmation).

Templates

  • templates/data-patch-fixed-seed.php
  • templates/data-patch-bulk-import.php
  • templates/data-patch-transformation.php
  • templates/importer-service.php
  • templates/import-cli-command.php

Acceptance Criteria

  • All generated patches implement DataPatchInterface and getDependencies().
  • All patches are idempotent.
  • A test asserting idempotency (apply twice → identical state) was written and watched to fail before the patch existed, and passes after (integration when a test DB is available; otherwise a test-first unit test of the idempotency guard, with the integration gap recorded).
  • For bulk imports, processing is chunked (default 500 rows).
  • For transformations, source data is preserved until destination is verified.

Related Skills

PhaseSkill
0context
(after Phase 2)review for the affected module

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.