Files
gh-atournayre-claude-market…/skills/make-urls/SKILL.md
2025-11-29 17:58:52 +08:00

5.8 KiB

name, description, license, version
name description license version
framework:make:urls Génère classe Urls + Message CQRS + Handler MIT 1.0.0

Framework Make Urls Skill

Description

Génère une classe Urls pour la génération d'URLs d'une entité, avec le pattern CQRS (Message + MessageHandler).

La classe Urls encapsule la logique de génération d'URLs pour une entité, le Message représente la query CQRS, et le Handler orchestre la récupération de l'entité et la création des URLs.

Usage

Use skill framework:make:urls

Vous serez invité à fournir :
- Le nom de l'entité (ex: Product, User, Order)

Templates

  • Urls/UtilisateurUrls.php - Template de classe Urls
  • MessageHandler/UtilisateurUrlsMessage.php - Template de message CQRS
  • MessageHandler/UtilisateurUrlsMessageHandler.php - Template de handler

Variables requises

  • {EntityName} - Nom de l'entité en PascalCase (ex: Utilisateur, Product)
  • {entityName} - Nom de l'entité en camelCase (ex: utilisateur, product)
  • {namespace} - Namespace du projet (défaut: App)

Dépendances

  • Requiert que l'entité existe dans src/Entity/{EntityName}.php
  • Requiert que le repository existe dans src/Repository/{EntityName}Repository.php
  • Requiert que l'interface repository existe dans src/Repository/{EntityName}RepositoryInterface.php

Outputs

  • src/Urls/{EntityName}Urls.php
  • src/MessageHandler/{EntityName}UrlsMessage.php
  • src/MessageHandler/{EntityName}UrlsMessageHandler.php

Workflow

  1. Demander le nom de l'entité (EntityName)
  2. Vérifier que l'entité existe dans src/Entity/{EntityName}.php
    • Si non : arrêter et demander de créer l'entité d'abord
  3. Vérifier que le repository existe
    • Si non : arrêter et demander de créer l'entité avec repository d'abord
  4. Générer les 3 classes depuis les templates :
    • Remplacer {EntityName} par le nom fourni
    • Remplacer {entityName} par la version camelCase
  5. Afficher les fichiers créés

Patterns appliqués

Classe Urls

  • Classe final readonly
  • Constructeur privé
  • Factory statique new()
  • Propriétés : UrlGeneratorInterface + entité
  • Méthodes pour générer URLs spécifiques

Message CQRS

  • Extends AbstractQueryEvent
  • Implements QueryInterface
  • Classe final
  • Constructeur privé avec factory new()
  • Propriété publique id
  • Méthode getter id()

MessageHandler

  • Classe final readonly
  • Attribut #[AsMessageHandler]
  • Constructeur avec repository + UrlGeneratorInterface
  • Méthode __invoke() retournant Urls

Exemple

Use skill framework:make:urls

# Saisies utilisateur :
EntityName: Product

# Résultat :
✓ src/Urls/ProductUrls.php
✓ src/MessageHandler/ProductUrlsMessage.php
✓ src/MessageHandler/ProductUrlsMessageHandler.php

Fichiers générés :

// src/Urls/ProductUrls.php
final readonly class ProductUrls
{
    private function __construct(
        private UrlGeneratorInterface $urlGenerator,
        private Product $product,
    ) {}

    public static function new(
        UrlGeneratorInterface $urlGenerator,
        Product $product,
    ): self {
        return new self(
            urlGenerator: $urlGenerator,
            product: $product,
        );
    }
}

// src/MessageHandler/ProductUrlsMessage.php
final class ProductUrlsMessage extends AbstractQueryEvent implements QueryInterface
{
    private function __construct(
        public string $id,
    ) {}

    public static function new(string $id): self
    {
        return new self(id: $id);
    }

    public function id(): string
    {
        return $this->id;
    }
}

// src/MessageHandler/ProductUrlsMessageHandler.php
#[AsMessageHandler]
final readonly class ProductUrlsMessageHandler
{
    public function __construct(
        private ProductRepositoryInterface $productRepository,
        private UrlGeneratorInterface $urlGenerator,
    ) {}

    public function __invoke(ProductUrlsMessage $message): ProductUrls
    {
        $product = $this->productRepository->find($message->id());
        return ProductUrls::new(
            urlGenerator: $this->urlGenerator,
            product: $product,
        );
    }
}

Usage dans l'entité

L'entité doit implémenter la méthode urls() :

public function urls(): ProductUrls
{
    /** @var ProductUrls $urls */
    $urls = ProductUrlsMessage::new(
        id: $this->id->toRfc4122(),
    )->query($this->dependencyInjection()->queryBus());

    return $urls;
}

Enrichissement avec URLs spécifiques

final readonly class ProductUrls
{
    private function __construct(
        private UrlGeneratorInterface $urlGenerator,
        private Product $product,
    ) {}

    public static function new(
        UrlGeneratorInterface $urlGenerator,
        Product $product,
    ): self {
        return new self(
            urlGenerator: $urlGenerator,
            product: $product,
        );
    }

    public function show(): string
    {
        return $this->urlGenerator->generate(
            'product_show',
            ['id' => $this->product->id()->toRfc4122()],
            UrlGeneratorInterface::ABSOLUTE_URL
        );
    }

    public function edit(): string
    {
        return $this->urlGenerator->generate(
            'product_edit',
            ['id' => $this->product->id()->toRfc4122()],
            UrlGeneratorInterface::ABSOLUTE_URL
        );
    }

    public function delete(): string
    {
        return $this->urlGenerator->generate(
            'product_delete',
            ['id' => $this->product->id()->toRfc4122()],
            UrlGeneratorInterface::ABSOLUTE_URL
        );
    }
}

Notes

  • Pattern CQRS : séparation query (Message) / handler
  • UrlGeneratorInterface injecté pour génération d'URLs
  • Repository utilisé pour récupérer l'entité par ID
  • Classe Urls peut être enrichie avec méthodes spécifiques au besoin
  • Respecte le principe d'immutabilité (readonly)