agentsclimarketplace

Create cqrs commands

Skill jeffsenso/prestashop-skills/skills/prestashop-module-development/ps9-core-ai/Component/CQRS/skills/create-cqrs-commands

Prestashop Developer Skills

Install
npx -y skills add jeffsenso/prestashop-skills --skill create-cqrs-commands

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Set up the full domain layer for a CQRS entity: identity value object, additional value objects, exception hierarchy, commands (Add, Edit, Delete, Toggle, sub-resource, or any custom domain action), and handler interfaces. Covers everything in src/Core/Domain/{Domain}/. Trigger: "create CQRS commands for {Domain}", "set up domain layer for {Domain}".

SKILL.md

5.6 KB, as published. Nobody here has run it

create-cqrs-commands

This skill creates the entire domain layer for an entity. It covers the Core side only (interfaces and data objects) — handler implementations live in implement-cqrs-handlers.

Read CQRS/CONTEXT.md for conventions (scalar inputs/VO getters, exception hierarchy, handler rules).

1. Identity Value Object

Create src/Core/Domain/{Domain}/ValueObject/{Domain}Id.php:

  • Constructor takes int $value, validates $value > 0, throws {Domain}Exception if not
  • Single getter: getValue(): int
  • No Symfony/Doctrine dependencies — pure PHP

Reference: src/Core/Domain/Tax/ValueObject/TaxId.php (simple), src/Core/Domain/Carrier/ValueObject/CarrierId.php (complex domain)

2. Additional Value Objects (if needed)

For fields with non-trivial validation or domain meaning (not just string/int):

  • Enum-like fields: class with constants + fromInt()/fromString() factory
  • URL fields: validate format in constructor
  • Constrained numbers: range checks in constructor

Not every field needs a VO — only those with invariants beyond primitive type checking.

For has-many relations, create typed collections implementing \Countable and \IteratorAggregate.

3. Exception Hierarchy

Create in src/Core/Domain/{Domain}/Exception/ following the hierarchy documented in CQRS/CONTEXT.md: base, not-found, per-action, and constraint classes.

Reference: src/Core/Domain/Tax/Exception/ (simple), src/Core/Domain/Carrier/Exception/ (many constraint codes)

4. Commands

All commands live in src/Core/Domain/{Domain}/Command/.

4.1 Add command

Add{Domain}Command.php:

  • Constructor takes all required fields as scalar typed parameters
  • Optional fields use nullable types with defaults
  • Multilingual fields: array $localizedValues keyed by language ID
  • Validate primitives in constructor (non-empty strings, positive ints)
  • Getters can return VOs built from the scalar inputs
  • Sub-resource fields are NOT included — they get their own command (see 4.5)

Reference: src/Core/Domain/Tax/Command/AddTaxCommand.php (simple), src/Core/Domain/Carrier/Command/AddCarrierCommand.php (many fields)

4.2 Edit command (partial-update pattern)

Edit{Domain}Command.php — follows the partial-update pattern from CQRS/CONTEXT.md:

  • Constructor takes only the entity ID (as int)
  • Every editable field: private ?Type $field = null
  • Fluent setter: public function setName(string $name): self { $this->name = $name; return $this; }
  • Nullable getter: public function getName(): ?string { return $this->name; }
  • Do NOT include fields that are immutable after creation

Reference: src/Core/Domain/Tax/Command/EditTaxCommand.php (simple), src/Core/Domain/Manufacturer/Command/EditManufacturerCommand.php (with image)

4.3 Delete command

Delete{Domain}Command.php:

  • Single constructor parameter: int $id (scalar)
  • Getter returns VO: getId(): {Domain}Id
  • No other properties — existence/constraint checks happen in the handler

4.4 Toggle status command

Toggle{Domain}StatusCommand.php (if entity has an active/enabled boolean):

  • Constructor takes int $id and optionally bool $expectedStatus
  • Handler reads current status and flips it, or sets to $expectedStatus if provided
  • Used by the grid toggle switch (AJAX)

4.5 Sub-resource commands (if entity has has-many relations)

Set{Domain}{SubResource}sCommand.php — one command per sub-resource type:

  • Constructor takes the entity int $id and the full replacement collection (as array of scalars)
  • Getters return VOs as appropriate
  • One command per sub-resource type

Reference: src/Core/Domain/Carrier/Command/SetCarrierRangesCommand.php

4.6 Custom domain actions

Any domain action that doesn't fit CRUD follows the same pattern: a command class with scalar constructor parameters and getters. The naming convention is {Verb}{Domain}Command.php.

5. Handler Interfaces

Create in src/Core/Domain/{Domain}/CommandHandler/:

  • One interface per command: Add{Domain}HandlerInterface, Edit{Domain}HandlerInterface, etc.
  • Single method: public function handle({Action}{Domain}Command $command): void
  • Exception: Add{Domain}HandlerInterface::handle() returns {Domain}Id (the new entity's ID)
  • All other handlers return void

The concrete implementations live in src/Adapter/{Domain}/CommandHandler/ (see implement-cqrs-handlers skill).

6. Domain Interfaces (if needed)

For abstractions that cross the Core/Adapter boundary beyond the repository:

  • File uploader: {Domain}LogoFileUploaderInterface in Core, implemented in Adapter
  • Use only Core domain types in signatures — no Doctrine/ObjectModel types

Rules

All conventions (scalar inputs/VO getters, exception hierarchy, handler rules) are in CQRS/CONTEXT.md. Skill-specific reminders:

  • All validation failures throw domain exceptions from the constructor
  • One handler interface per command — never combine multiple commands

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.