Skill: Create a Domain Event

Skill: Create a Domain Event

Steps

1. Create the Event Class

declare(strict_types=1);

namespace App\Module\{Module}\Domain\Event;

use App\Core\Contract\DomainEventInterface;

final readonly class {Entity}{Action} implements DomainEventInterface
{
    public function __construct(
        public string ${entity}Id,
        public string $tenantId,
        // ... relevant payload fields (primitives only)
        public \DateTimeImmutable $occurredAt,
        public int $version = 1,
    ) {}

    public function topic(): string
    {
        return '{module}.{entity}.{action}';
    }
}

2. Rules

  • All properties must be scalar types or DateTimeImmutable (JSON-serializable)
  • Always include $tenantId and $occurredAt
  • Always include $version with default = 1
  • Name as past tense: MemberCreated, GroupMemberJoined
  • Topic format: {module}.{entity}.{action}

3. Record in Aggregate

$this->recordEvent(new {Entity}{Action}(
    {entity}Id: $this->id->value,
    tenantId: $this->tenantId->value,
    // ...
    occurredAt: new \DateTimeImmutable(),
));

4. Update Event Catalog

Add to .ai/context/EVENT_CATALOG.md:

Event: {Entity}{Action}
Topic: {module}.{entity}.{action}
Version: 1
Emitter: {Module}/{Aggregate}
Consumers: []
Payload:
  - {entity}Id: string (UUID)
  - tenantId: string (UUID)
  - occurredAt: datetime