agentleFS
muon-m2muon-m2/magento2-tools/skills/eav-attribute/SKILL.md

eav-attribute

Skill6 starsChanged 28 days agoMITView on GitHub

Add a product, customer, customer-address, or category attribute via an idempotent data patch with correct backend / source / frontend models, scope, store-view handling, and indexer integration. - One attribute per patch. Each Add{Code}Attribute.php adds exactly one attribute. Bundling multiple attributes per patch makes failures harder to recover from. - Idempotent. Re-running setup:upgrade must not duplicate the attribute. Use EavSetup::getAttribute() check before adding. - getDependencies() always present. Even when empty, the method must be implemented. - Use the matching Setup…

We split this skill into the rules it gives an agent

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

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Add a product, customer, customer-address, or category attribute via an idempotent data patch with correct backend / source / frontend …

    line 15
  2. Very specific:

    No legacy Setup/InstallData.php: Use Setup/Patch/Data/ only.

    line 28
  3. Distinctive:

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

    line 32
  4. Distinctive:

    Ask for any missing values:

    line 56
  5. Very specific:

    3A — Write the failing test (RED): Before any patch code, add an integration test under Test/Integration/ that loads the attribute (via the …

    line 95
  6. Distinctive:

    3B — Generate the patch (GREEN): Write the minimal patch to turn 3A green, using the entity-specific template:

    line 105
  7. Very specific:

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

    line 122
  8. Very specific:

    Verify dependencies in getDependencies() reference existing classes.

    line 125
  9. Very specific:

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

    line 126
  10. Distinctive:

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

    line 140
  11. Very specific:

    All templates follow the placeholder registry in context/references/placeholder-schema.md.

    line 204

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “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 EAV Attribute

Add a product, customer, customer-address, or category attribute via an idempotent data patch with correct backend / source / frontend models, scope, store-view handling, and indexer integration.

Core Rules

  • One attribute per patch. Each Add{Code}Attribute.php adds exactly one attribute. Bundling multiple attributes per patch makes failures harder to recover from.
  • Idempotent. Re-running setup:upgrade must not duplicate the attribute. Use EavSetup::getAttribute() check before adding.
  • getDependencies() always present. Even when empty, the method must be implemented.
  • Use the matching Setup factory. Product → EavSetupFactory; Customer → CustomerSetupFactory; etc. Mixing factories breaks the patch.
  • No legacy Setup/InstallData.php. Use Setup/Patch/Data/ only.
  • Generate companions only when needed. Source model only for select/multiselect; backend model only for date/image/price/multiselect/non-trivial; frontend model only when explicitly requested.
  • Test-first for the attribute effect. Write the failing integration test before the patch (red → green → refactor) and watch it fail for the right reason. It asserts the attribute exists after the patch runs with the declared scope (is_global), frontend_input, and any backend/source model wiring — plus idempotency (patch runs twice → no duplicate, no error). Behaviour-bearing source/backend models get a test-first unit test (e.g. the source model's toOptionArray()). See context/references/tdd-discipline.md.
  • 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 — Resolve Inputs

Ask for any missing values:

InputDefaultNotes
Entity type(ask)product, customer, customer_address, category
Module to host the patch(ask)Existing {Vendor}_{Module} or new
Attribute code(ask)snake_case, ≤ 30 chars
Attribute label(ask)Human-readable
Input typetexttext, textarea, select, multiselect, date, boolean, price, image, media_image
Scopestoreglobal, website, store
Requiredfalsetrue/false
Source modelnoneRequired if select/multiselect
Backend modelnoneRequired for multiselect, image, date, price
Frontend modelnoneOptional
Used in product listingfalseTriggers flat-table inclusion
Used for sortingfalseTriggers flat-table inclusion
Filterable in catalog searchfalseLayered nav
SearchablefalseCatalog search index
Visible on storefronttrueTriggers system attribute group assignment
Apply to product typesallRestrict to simple, configurable, etc.
Form / grid visibility (customer)variesis_used_in_grid, is_visible_in_grid etc.

See references/entity-types.md, references/input-types.md, references/scope-rules.md.

Phase 2 — Plan

Present the file plan:

  • Setup/Patch/Data/Add{AttributeCode}Attribute.php
  • Optionally: source model Model/Source/{AttributeCode}.php
  • Optionally: backend model Model/Attribute/Backend/{AttributeCode}.php
  • Optionally: frontend model Model/Attribute/Frontend/{AttributeCode}.php
  • Optionally: indexer/system attribute registration in etc/indexer.xml
  • Optionally: DI binding for source model in etc/di.xml

Wait for "proceed."

Phase 3 — Test First, then Generate

3A — Write the failing test (RED). Before any patch code, add an integration test under Test/Integration/ that loads the attribute (via the entity's attribute repository / EAV config) and asserts it exists with the declared scope, input type, and backend/source wiring, plus idempotency (running the patch twice does not duplicate or error). Follow context/references/tdd-discipline.md and the integration patterns in test-generate/references/integration-patterns.md. Run it and confirm it fails for the right reason (attribute absent), not a setup error. If no Magento test DB is available, follow the tiered fallback: for an attribute with a behavioural source/backend model, write a test-first unit test of that model; record the integration gap in the Phase 5 report.

3B — Generate the patch (GREEN). Write the minimal patch to turn 3A green, using the entity-specific template:

  • templates/eav-add-product-attribute-patch.php
  • templates/eav-add-customer-attribute-patch.php
  • templates/eav-add-customer-address-attribute-patch.php
  • templates/eav-add-category-attribute-patch.php

Plus companion templates as needed:

  • templates/source-model.php
  • templates/backend-model.php
  • templates/frontend-model.php

Phase 4 — Verify

  • php -l on every generated file.
  • Run the Phase 3A test with {ctx.runner} vendor/bin/phpunit and confirm it now passes (it failed before 3B); run the affected module's suite to confirm nothing else broke.
  • composer validate if composer.json was modified.
  • Verify dependencies in getDependencies() reference existing classes.
  • 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 5 — Report

Brief Markdown saved to {output_root}/eav-attributes/{Vendor}_{Module}-{code}-{date}.md:

  • Files generated
  • Test path + red→green evidence (or the recorded integration gap if no test DB was available)
  • Migration command: bin/magento setup:upgrade
  • Reindex hint if attribute is searchable / filterable
  • Cache flush hint

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

/eav-attribute --entity=product --code=acme_color --label="Acme Color" --type=select --module=Acme_Catalog [--docs-root=<path>]

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

Outputs

{ctx.magento_root}/app/code/{Vendor}/{Module}/Setup/Patch/Data/Add{Code}Attribute.php
{ctx.magento_root}/app/code/{Vendor}/{Module}/Model/Source/{Code}.php          # if applicable
{ctx.magento_root}/app/code/{Vendor}/{Module}/Model/Attribute/Backend/{Code}.php # if applicable
{ctx.magento_root}/app/code/{Vendor}/{Module}/Test/Integration/.../Add{Code}AttributeTest.php  # test-first (Phase 3A)

{output_root}/eav-attributes/{Vendor}_{Module}-{code}-{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>/eav-attributes/; otherwise default to {ctx.docs_root}/eav-attributes/. feature passes this so a feature run's reports collect under its folder.

Reference Files

  • references/entity-types.md — per-entity-type input map.
  • references/input-types.md — each input type's required backend/source model.
  • references/scope-rules.md — global vs website vs store semantics.
  • references/source-model-patterns.md — standard source model implementations.
  • references/backend-model-patterns.md — standard backend model implementations.
  • references/frontend-impact.md — listing, sorting, search, layered nav.
  • context/references/tdd-discipline.md — shared test-first loop applied in Phase 3A (integration patterns: test-generate/references/integration-patterns.md).
  • 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/eav-add-product-attribute-patch.php
  • templates/eav-add-customer-attribute-patch.php
  • templates/eav-add-customer-address-attribute-patch.php
  • templates/eav-add-category-attribute-patch.php
  • templates/source-model.php
  • templates/backend-model.php
  • templates/frontend-model.php

All templates follow the placeholder registry in context/references/placeholder-schema.md. This skill's templates use the {Vendor} / {Module} / {Entity} convention (both that and the module-create {ModuleName} / {EntityName} convention are registered and accepted). Every token used must be in the Registry there — tests/test-placeholder-tokens.sh enforces it.

(Near-identical EAV patch templates also exist in module-create/templates/ (eav-add-*-attribute-patch.php). They are not identical: this skill's copies are the canonical ones for EAV work because they add the getAttribute() idempotency short-circuit and the try/finally around startSetup()/endSetup(). Prefer this skill's templates; the module-create copies are the simpler scaffolding variant. Single-sourcing the two sets is tracked as a follow-up.)

Acceptance Criteria

  • Generated patch is idempotent.
  • An integration test asserting the attribute's scope/input-type/wiring and idempotency was written and watched to fail before the patch existed, and passes after (or, when no test DB is available, a test-first unit test covers a behavioural source/backend model and the integration gap is recorded).
  • Patch implements DataPatchInterface and uses the correct *SetupFactory for the entity type.
  • Source/backend/frontend model is generated only when actually required.
  • Generated patch passes review with zero Critical/High findings.

Common Pitfalls Handled

PitfallHow the skill avoids it
Forgetting getDependencies() returnsAlways emitted, even when empty
addAttribute without apply_to for product typeAsked in Phase 1
is_global set wrongAsked in Phase 1; default store
Missing DI for source modelGenerated when source model used
Missing is_used_in_grid / is_visible_in_gridAsked in Phase 1
Legacy Setup/InstallData.phpSkill refuses; uses Setup/Patch/Data/ only

Related Skills

PhaseSkill
0context
(caller)feature Phase 5 — when blueprint declares EAV attributes

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.