documentation
Kohinos v3 Doc générée le commit 8d60b1904

Conventions & règles dures

Règles non négociables du projet. Toute PR qui les enfreint est rejetée. Ces conventions sont le reflet direct des priorités : intégrité financière › souveraineté › sobriété › maintenabilité › performance.

Doctrine — attributs PHP 8 uniquement

⛔ Règle absolue

Le projet est en mapping type: attribute. Les docblock annotations ne sont pas lues par Doctrine. Une annotation oubliée en docblock produit une colonne manquante ou un slug NULL en silence.

// ❌ INTERDIT
/** @ORM\Column(type="string") @Gedmo\Slug(fields={"name"}) */
private $slug;

// ✅ OBLIGATOIRE
#[ORM\Column(length: 100)]
#[Gedmo\Slug(fields: ['name'])]
private ?string $slug = null;

Inclut aussi : #[ORM\PostPersist], #[ORM\HasLifecycleCallbacks], #[ORM\MappedSuperclass], #[Assert\NotBlank]…

Cryptographie — libsodium uniquement

⛔ Règle absolue

Toute signature ou vérification cryptographique passe par sodium_* (Ed25519, Curve25519). Aucun appel à openssl_* n'est toléré pour les flux financiers. Cohérent avec la roadmap Reticulum/LoRa (offline).

Atomicité financière

Toute modification de solde doit s'inscrire dans une transaction unique avec lock pessimiste et persistance d'une Operation.

$em->wrapInTransaction(function () use ($accountId, $montant) {
    $account = $em->find(Account::class, $accountId, LockMode::PESSIMISTIC_WRITE);
    $flux    = new Transaction(...);
    $op      = new OperationDebit($account, $flux, $montant);

    $em->persist($flux);
    $em->persist($op);
    $account->applyOperation($op);
});

Double-flush pour références dépendant de l'UUID

Quand une référence métier dépend de l'UUID (UMR SEPA, slug court…), il faut un flush intermédiaire pour que Doctrine génère l'UUID.

$mandate = new SepaMandate();
$em->persist($mandate);
$em->flush(); // UUID disponible
$mandate->setMandateReference($this->generateUmr($mandate));
$em->flush();

Repository pattern

Sonata Admin 4.x — breaking changes

Sonata 4 a supprimé plusieurs raccourcis présents en 3.x. Sans ces ajustements, les Admins cassent silencieusement.

// ❌ INTERDIT (n'existe plus)
$this->trans('label.foo');

// ✅ OBLIGATOIRE
$this->getTranslator()->trans('label.foo', [], $this->getTranslationDomain());

Symfony 7.x — tests fonctionnels

Frontend — règles dures

⛔ Règle absolue
  1. Aucun JS ni CSS inline dans un .html.twig. Créer assets/js|css/ma-feature.{js,css}, déclarer une entry dans webpack.config.js, inclure via {{ encore_entry_script_tags('ma-feature') }}, passer les données par data-*.
  2. Vanilla JS first : à chaque édition d'un fichier JS, migrer vers ES2020+ natif à comportement identique. Exceptions tolérées : peer deps (Select2, CKEditor).
  3. console.log('[Module] …') partout : Terser strip en prod (drop_console: true). console.warn/error aussi : pas pour du debug persistant.

Commandes Symfony — règles métier

Pipeline de validation pre-commit

flowchart LR
  A["git commit"] --> B["GrumPHP"]
  B --> C["PHP-CS-Fixer"]
  B --> D["PHPStan"]
  B --> E["lint:yaml + lint:twig"]
  B --> F["PHPUnit ciblé"]
  C & D & E & F --> G{"OK ?"}
  G -- non --> H["commit refusé"]
  G -- oui --> I["commit accepté"]
    
Pipeline GrumPHP : tout doit passer avant commit.

CHANGELOG — obligatoire avant chaque commit

FichierContenuPublic
CHANGELOG.mdTechnique : classes, migrations, breaking changesDéveloppeur
CHANGELOG_USER.mdFonctionnel : ce que voient utilisateurs/adminsAdhérent, trésorier

Style PHP 8.4 — résumé