docs(catalog) : M0 categories specs (back + front) #12
Reference in New Issue
Block a user
Delete Branch "feature/M0-spec-categories"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Contexte
Premier passage du workflow MALIO sur un module concret. Cette MR introduit uniquement la documentation (2 specs Markdown) du Module 0 — Gestion des catégories. Aucun code applicatif n'est touché.
La spec back a été cadrée sur l'archi DDD réelle de Starseed (cf.
.claude/rules/architecture.md+backend.md) après audit du repo (modulesCore,Commercial,Sites). Elle introduit aussi un nouveau moduleCatalog(bounded context "référentiels partagés") — non créé dans cette MR, il viendra avec les tickets de dev.Contenu
docs/specs/M0-categories/spec-back.mddocs/specs/M0-categories/spec-front.mdDécisions d'archi (auto-validation back-only)
Toutes les décisions sont documentées dans
spec-back.md § 2:Catalogcréé séparément deCommercialpour rester réutilisable par les futurs modules Tiers (M-Clients, M-Fournisseurs, M-Prestas)User,Role, etc.)deleted_at TIMESTAMP(0) WITHOUT TIME ZONE NULL— pattern introduit par ce module (aucune autre entité Starseed ne le portait)(LOWER(name), category_type_id) WHERE deleted_at IS NULL→ unicité case-insensitive parmi non soft-deleted, recréation possible après suppression logiqueview+manage(aligné surcore.users.view+core.users.manage)CategoryType= entité séparée, table vide à la livraison, valeurs seedées plus tard (HP-1)Règles métier (RG-1.01 → RG-1.13)
Chaque RG est numérotée, stable, testable, et constituera un critère d'acceptation côté ticket Lesstime (cf.
spec-back.md § 7).Couverture par catégorie :
name: RG-1.02 (obligatoire), RG-1.03 (trim), RG-1.04 (longueur 2-120)categoryType: RG-1.05 (obligatoire), RG-1.06 (référence valide)?includeDeleted=true), RG-1.10 (triname ASC)deletedAtnon modifiable via PATCH)Découpe en tickets Lesstime
TaskGroup
#22 — M0 — Gestion des catégoriescréé sur le projet STARSEED. 9 tickets en backlog :#43Migrer les tables Category et CategoryType#44Créer les entités Category et CategoryType#45Implémenter Provider et Processor Category#46Exposer le référentiel CategoryType en lecture seule#47Déclarer le module Catalog et synchroniser RBAC#48Écrire les tests PHPUnit RG-1.01 à RG-1.13#49Créer la page Gestion des catégories (datatable + drawer)#50Implémenter les composables useCategoriesAdmin et useCategoryForm#51Écrire les tests Vitest des composables CatalogTotal estimé : ~15-25h (9 mini-MR de 1-4h).
Hors-périmètre (HP)
Pas codés / pas inclus dans cette spec (cf.
spec-back.md § 9) :CategoryType(spec dédiée à venir)category_idsur Clients/Fournisseurs/Prestas viendront avec leurs modules)nameChecklist review
Pas de code → review légère, lecture des 2
.mdsuffit.spec-back.md § 2)Stratégie de merge
Squash merge vers
develop(1 PR = 1 commit propre dans l'historique).Lien Lesstime
#22 — M0 — Gestion des catégories(projet ERP / Starseed)#43→#51@@ -0,0 +91,4 @@CoreModule::class,CommercialModule::class,SitesModule::class,CatalogModule::class, // ← AJOUTÉA voir. Comment on fait si le module est désactivé sachant que pour créer un client il est requis de sélectionner une catégorie.
@@ -0,0 +547,4 @@**Aucun code custom à écrire côté M0.** Il suffit que `Category` porte `#[Auditable]`. Le soft delete (UPDATE `deleted_at`) est tracé comme un UPDATE normal.### 6.2 Pas de colonnes `created_by` / `updated_by` / `created_at` / `updated_at` sur `category`Si il faut au moins les colonnes created_at et updated_at
Bonne question. Réponse v1.2 :
CatalogModule::REQUIRED = true.Comme la FK
category_idsera NOT NULL côté Client (et Fournisseur, Prestataire — confirmé via la maquette de création client), désactiver Catalog ferait casser tout le métier au boot Doctrine. Donc on aligne sur le pattern deCoreModule: module obligatoire, impossible de le commenter dansconfig/modules.phpsans casser l'app.→ Commit
e4b8df1:REQUIRED = true+ commentaire dans le code qui cite explicitement cette question.Bonus pour la cohérence :
Categoryest exposée aux autres modules viaShared/Domain/Contract/CategoryInterface.php(pattern Sites existant, résolution Doctrine viaresolve_target_entities). Aucun import direct cross-module, on respecte la règle ABSOLUE n°1.Cf. spec-back.md § 2.1 (module + REQUIRED) et § 2.3 (FK des Tiers).
Tu as raison. Spec v1.2 ajoute non pas 2 mais les 4 colonnes automatisées par un pattern Shared (pour ne pas avoir à le redécider à chaque entité).
Ce qui change :
src/Shared/(Trait + Interfaces + Subscriber DoctrineprePersist/preUpdate) qui remplitcreated_at,updated_at,created_by,updated_byautomatiquement pour toute entité métier quiuse TimestampableBlamableTrait;+implements TimestampableInterface, BlamableInterface.created_at/updated_at: NOT NULL, remplis systématiquement par le Subscriber.created_by/updated_by: FK nullable versuser(ON DELETE SET NULL) — permet créations CLI/cron sans user en session, affiché « Système » côté front si null.use Trait, 2implements), pas de redéclaration manuelle des props.Garde-fou pour pas oublier sur les futures entités : test PHPUnit d'architecture (
tests/Architecture/EntitiesAreTimestampableBlamableTest) qui scannesrc/Module/*/Domain/Entity/et fait échouer la CI si une entité métier n'implémente pas les 2 interfaces. Whitelist explicite (EXCLUDED) pour les référentiels statiques typeCategoryTypequi n'ont pas besoin de traçabilité.→ Commit
723a220: pattern complet + 3 RG ajoutées (RG-1.15, RG-1.16, RG-1.17).Lecture : spec-back.md § 2.5 (vue d'ensemble audit + dates), § 2.8 (pattern Shared), § 2.8.bis (garde-fous architecture), § 6 (réécrite), RG-1.15 / 1.16 / 1.17 dans § 7.
Ticket Lesstime dédié au pattern Shared : #52 (0.0) — prérequis du M0 et de tous les futurs modules métier.