Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:58:52 +08:00
commit eac17f89fa
40 changed files with 4048 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
# Framework Make Entity
Génère une entité Doctrine avec repository selon principes Elegant Objects.
## Vue d'ensemble
Cette skill crée une entité Doctrine complète respectant les principes Elegant Objects, avec son repository et son interface.
## Caractéristiques
### Entité générée
- Constructeur privé + factory statique `create()`
- Classe `final`
- Propriétés privées avec getters uniquement
- Pas de setters (immutabilité encouragée)
- Implémentation des interfaces de contrats
- Traits Atournayre intégrés
- Attributs Doctrine ORM configurés
- Méthode `toLog()` pour LoggableInterface
### Repository généré
- Extends ServiceEntityRepository
- Classe `final`
- Interface dédiée
- Prêt pour méthodes custom
## Utilisation
```bash
Use skill framework:make:entity
```
Vous serez invité à fournir :
1. Nom de l'entité (PascalCase)
2. Liste des propriétés avec types
## Exemple d'utilisation
```bash
EntityName: Product
Properties:
- name: string
- description: string
- price: float
- stock: int
- isActive: bool
```
Génère :
```php
// src/Entity/Product.php
final class Product implements LoggableInterface, DatabaseEntityInterface, ...
{
use DatabaseTrait;
use NullTrait;
use DependencyInjectionTrait;
private function __construct(
#[ORM\Id]
#[ORM\Column(type: 'uuid')]
private Uuid $id,
#[ORM\Column(type: 'string')]
private string $name,
// ...
) {}
public static function create(Uuid $id, string $name, ...): self
{
return new self(id: $id, name: $name, ...);
}
public function id(): Uuid { return $this->id; }
public function name(): string { return $this->name; }
// ...
}
```
## Structure créée
```
src/
├── Entity/
│ └── {EntityName}.php
└── Repository/
├── {EntityName}Repository.php
└── {EntityName}RepositoryInterface.php
```
## Prérequis
- Contracts doivent exister (appelle automatiquement `framework:make:contracts` si absents)
- Projet Symfony avec Doctrine ORM configuré
- Framework `atournayre/framework` installé
## Types de propriétés supportés
- Scalaires : `string`, `int`, `float`, `bool`
- UUID : `Uuid` (Symfony\Component\Uid\Uuid)
- DateTime : `\DateTimeImmutable`
- Arrays : `array`
- Relations Doctrine (à configurer manuellement après génération)
## Principes Elegant Objects appliqués
- Constructeur privé
- Factory statique pour création
- Classe finale (pas d'héritage)
- Pas de setters publics
- Propriétés privées avec getters
- Interfaces pour tous les contrats
- Immutabilité encouragée

108
skills/make-entity/SKILL.md Normal file
View File

@@ -0,0 +1,108 @@
---
name: framework:make:entity
description: Génère une entité Doctrine avec repository selon principes Elegant Objects
license: MIT
version: 1.0.0
---
# Framework Make Entity Skill
## Description
Génère une entité Doctrine complète avec son repository selon les principes Elegant Objects.
L'entité générée inclut :
- Constructeur privé avec factory statique `create()`
- Traits Elegant Objects (DatabaseTrait, NullTrait, DependencyInjectionTrait)
- Implémentation des interfaces de contrats
- Repository avec interface
## Usage
```
Use skill framework:make:entity
Vous serez invité à fournir :
- Le nom de l'entité (ex: Product, User, Order)
- Les propriétés avec leurs types (ex: name:string, email:string, isActive:bool)
```
## Templates
- `Entity/Utilisateur.php` - Template d'entité
- `Repository/UtilisateurRepository.php` - Template de repository
- `Repository/UtilisateurRepositoryInterface.php` - Template d'interface repository
## 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)
- **{properties}** - Liste des propriétés avec types (array)
## Dépendances
- Requiert que les Contracts soient présents
- Appelle automatiquement `framework:make:contracts` si les interfaces n'existent pas
## Outputs
- `src/Entity/{EntityName}.php`
- `src/Repository/{EntityName}Repository.php`
- `src/Repository/{EntityName}RepositoryInterface.php`
## Workflow
1. Demander le nom de l'entité (EntityName)
2. Demander les propriétés (nom, type, nullable)
3. Vérifier si `src/Contracts/` existe
- Si non : appeler `framework:make:contracts`
4. Générer l'entité depuis le template :
- Remplacer `{EntityName}` par le nom fourni
- Remplacer `{entityName}` par la version camelCase
- Générer les propriétés dans le constructeur
- Générer les méthodes getter pour chaque propriété
5. Générer le repository et son interface
6. Afficher le résumé des fichiers créés
## Patterns appliqués
### Entité
- Classe `final`
- Constructeur privé
- Factory statique `create()` pour instanciation
- Traits : DatabaseTrait, NullTrait, DependencyInjectionTrait
- Attributs Doctrine ORM (#[ORM\Entity], #[ORM\Id], #[ORM\Column])
- Implémentation des interfaces :
- LoggableInterface
- DatabaseEntityInterface
- NullableInterface
- DependencyInjectionAwareInterface
- OutInterface
- HasUrlsInterface
- InvalideInterface
### Repository
- Classe `final`
- Extends ServiceEntityRepository
- Implémente l'interface du repository
- Constructeur avec ManagerRegistry uniquement
## Exemple
```bash
Use skill framework:make:entity
# Saisies utilisateur :
EntityName: Product
Properties:
- id: Uuid
- name: string
- price: float
- isActive: bool
# Résultat :
✓ src/Entity/Product.php
✓ src/Repository/ProductRepository.php
✓ src/Repository/ProductRepositoryInterface.php
```
## Notes
- L'ID de type Uuid est ajouté automatiquement
- Les propriétés sont toujours privées avec getters
- Pas de setters (immutabilité)
- La méthode `toLog()` inclut automatiquement toutes les propriétés

View File

@@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use App\Contracts\HasUrlsInterface;
use App\Contracts\InvalideInterface;
use App\Contracts\OutInterface;
use App\Invalide\UtilisateurInvalide;
use App\MessageHandler\UtilisateurUrlsMessage;
use App\Out\UtilisateurOut;
use App\Repository\UtilisateurRepository;
use App\Urls\UtilisateurUrls;
use Atournayre\Common\Persistance\DatabaseTrait;
use Atournayre\Contracts\DependencyInjection\DependencyInjectionAwareInterface;
use Atournayre\Contracts\Log\LoggableInterface;
use Atournayre\Contracts\Null\NullableInterface;
use Atournayre\Contracts\Persistance\DatabaseEntityInterface;
use Atournayre\Null\NullTrait;
use Atournayre\Traits\DependencyInjectionTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: UtilisateurRepository::class)]
final class Utilisateur implements LoggableInterface, DatabaseEntityInterface, NullableInterface, DependencyInjectionAwareInterface, OutInterface, HasUrlsInterface, InvalideInterface
{
use DatabaseTrait;
use DependencyInjectionTrait;
use NullTrait;
private function __construct(
#[ORM\Id]
#[ORM\Column(type: 'uuid')]
private Uuid $id,
) {
}
public static function create(
Uuid $id,
): self {
return new self(
id: $id,
);
}
public function id(): Uuid
{
return $this->id;
}
/**
* @return array<string, mixed>
*/
public function toLog(): array
{
return [
'id' => $this->id,
];
}
public function invalide(): UtilisateurInvalide
{
return UtilisateurInvalide::new(
utilisateur: $this,
);
}
public function out(): UtilisateurOut
{
return UtilisateurOut::new(
utilisateur: $this,
);
}
public function urls(): UtilisateurUrls
{
/** @var UtilisateurUrls $urls */
$urls = UtilisateurUrlsMessage::new(
id: $this->id->toRfc4122(),
)->query($this->dependencyInjection()->queryBus());
return $urls;
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\Utilisateur;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Utilisateur>
*/
final class UtilisateurRepository extends ServiceEntityRepository implements UtilisateurRepositoryInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Utilisateur::class);
}
}

View File

@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace App\Repository;
interface UtilisateurRepositoryInterface
{
}