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
- Distinctive: line 15
Add a product, customer, customer-address, or category attribute via an idempotent data patch with correct backend / source / frontend …
- Very specific: line 28
No legacy
Setup/InstallData.php: Use Setup/Patch/Data/ only. - Distinctive: line 32
Test-first for the attribute effect: Write the failing integration test before the patch (red → green → refactor) and watch it fail for the …
- Distinctive: line 56
Ask for any missing values:
- Very specific: line 95
3A — Write the failing test (RED): Before any patch code, add an integration test under Test/Integration/ that loads the attribute (via the …
- Distinctive: line 105
3B — Generate the patch (GREEN): Write the minimal patch to turn 3A green, using the entity-specific template:
- Very specific: line 122
Run the Phase 3A test with {ctx.runner} vendor/bin/phpunit and confirm it now passes (it failed before 3B).
- Very specific: line 125
Verify dependencies in getDependencies() reference existing classes.
- Very specific: line 126
Apply the shared module-hygiene baseline (required): After generating or modifying PHP files, run …
- Distinctive: line 140
Test path + red→green evidence (or the recorded integration gap if no test DB was available)
- Very specific: line 204
All templates follow the placeholder registry in context/references/placeholder-schema.md.
≈ “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.
Files
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.phpadds exactly one attribute. Bundling multiple attributes per patch makes failures harder to recover from. - Idempotent. Re-running
setup:upgrademust not duplicate the attribute. UseEavSetup::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. UseSetup/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'stoOptionArray()). Seecontext/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=Magento2PHPCS is the gate. Seecontext/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. Seecontext/references/source-of-truth.md.
Workflow
Phase 0 — Context Resolution
Invoke context.
Phase 1 — Resolve Inputs
Ask for any missing values:
| Input | Default | Notes |
| 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 type | text | text, textarea, select, multiselect, date, boolean, price, image, media_image |
| Scope | store | global, website, store |
| Required | false | true/false |
| Source model | none | Required if select/multiselect |
| Backend model | none | Required for multiselect, image, date, price |
| Frontend model | none | Optional |
| Used in product listing | false | Triggers flat-table inclusion |
| Used for sorting | false | Triggers flat-table inclusion |
| Filterable in catalog search | false | Layered nav |
| Searchable | false | Catalog search index |
| Visible on storefront | true | Triggers system attribute group assignment |
| Apply to product types | all | Restrict to simple, configurable, etc. |
| Form / grid visibility (customer) | varies | is_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.phptemplates/eav-add-customer-attribute-patch.phptemplates/eav-add-customer-address-attribute-patch.phptemplates/eav-add-category-attribute-patch.php
Plus companion templates as needed:
templates/source-model.phptemplates/backend-model.phptemplates/frontend-model.php
Phase 4 — Verify
php -lon every generated file.- Run the Phase 3A test with
{ctx.runner} vendor/bin/phpunitand confirm it now passes (it failed before 3B); run the affected module's suite to confirm nothing else broke. composer validateif 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 acomposer.jsonrequireentry, resolve a bounded constraint via${CLAUDE_PLUGIN_ROOT}/skills/context/scripts/resolve-dep-constraint.sh <vendor/package>— never"*". Seecontext/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, anddocs/*.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.phptemplates/eav-add-customer-attribute-patch.phptemplates/eav-add-customer-address-attribute-patch.phptemplates/eav-add-category-attribute-patch.phptemplates/source-model.phptemplates/backend-model.phptemplates/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
DataPatchInterfaceand uses the correct*SetupFactoryfor the entity type. - Source/backend/frontend model is generated only when actually required.
- Generated patch passes
reviewwith zero Critical/High findings.
Common Pitfalls Handled
| Pitfall | How the skill avoids it |
Forgetting getDependencies() returns | Always emitted, even when empty |
addAttribute without apply_to for product type | Asked in Phase 1 |
is_global set wrong | Asked in Phase 1; default store |
| Missing DI for source model | Generated when source model used |
Missing is_used_in_grid / is_visible_in_grid | Asked in Phase 1 |
Legacy Setup/InstallData.php | Skill refuses; uses Setup/Patch/Data/ only |
Related Skills
| Phase | Skill |
| 0 | context |
| (caller) | feature Phase 5 — when blueprint declares EAV attributes |
In this repository35 other files it gives its agents.
- a11y-auditSkill
- admin-formSkill
- admin-listingSkill
- auditSkill
- breeze-adaptSkill
- breeze-compatSkill
- breeze-themeSkill
- cli-commandSkill
- contextSkill
- data-migrationSkill
- debugSkill
- deploySkill
- docsSkill
- extension-pointSkill
- featureSkill
- fixSkill
- frontendSkill
- graphqlSkill
- i18nSkill
- indexerSkill
- lintSkill
- marketplaceSkill
- message-queueSkill
- module-createSkill
- perf-auditSkill
- releaseSkill
- remediateSkill
- reviewSkill
- securitySkill
- system-configSkill
- test-generateSkill
- triageSkill
- upgradeSkill
- webapiSkill
- widgetSkill
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.

