c777ca057b
PHPUnit suite for the M0 Catalog module covering the 17 business rules of the spec : - CategoryPermissionsTest (RG-1.01) — 4 personas + admin + anonymous on GET / POST / PATCH / DELETE - CategoryValidationTest (RG-1.02 to RG-1.06) — name NotBlank + trim + length + categoryType required / must exist - CategoryUniqueTest (RG-1.07) — 409 case-insensitive, multi-type allowed, recreate after soft delete - CategoryListTest (RG-1.08 to RG-1.10) — soft-delete filter, includeDeleted flag, name ASC sort - CategoryGetTest (RG-1.11) — 404 on soft-deleted, 200 with flag, 404 on not found - CategoryDeleteTest (RG-1.12 / RG-1.13) — soft delete, deletedAt unwriteable via PATCH, 404 on already deleted - CategoryAuditTest — audit_log written on create / update / soft delete with correct performed_by - CategoryTimestampableBlamableTest (RG-1.15 / RG-1.16) — blame admin on POST, null in console context, frozen createdBy on PATCH, updated_* on soft delete - EntitiesAreTimestampableBlamableTest (RG-1.17) — stays green (already shipped in ERP-52) Side fixes uncovered by the suite : - Category.php : add normalizer 'trim' to NotBlank + Length so a whitespace-only name returns 422 (RG-1.02 + RG-1.03 alignment, the Processor trim was running after validation). - makefile : recreate the partial index uq_category_name_type_active in test-db-setup. doctrine:schema:update drops the unexpressable index after migrations, which made RG-1.07 silently pass (duplicate POST -> 201 instead of 409). The DDL is now restored after schema:update via dbal:run-sql. Tests : 311 total (248 + 63 new), 1071 assertions, 0 failure, 0 risky.