Skip to content

feat(archetype): F2.27 — rename soft-deleted name/slug conflicts so creation isn't blocked #579

@jbourdin

Description

@jbourdin

Problem

Archetype has unique constraints on both name (uniq_archetype_name) and slug (uniq_archetype_slug) at the DB level (src/Entity/Archetype.php:28-29). Soft-deleted rows (deletedAt set, src/Entity/Archetype.php:82-83) still occupy those unique keys, so an admin who deletes an archetype and tries to recreate one with the same name/slug hits a constraint violation. The admin list excludes soft-deletes (['deletedAt' => null] in AdminArchetypeController) so the conflict is invisible from the UI.

Scope

On archetype create (and on update if the new name/slug collides with a soft-deleted row), automatically rename the conflicting soft-deleted row by appending a uniqueness suffix to both its name and slug so the new archetype can take the canonical values.

Suffix shape: __deleted_<short-uniq> — e.g. Gardevoir exGardevoir ex__deleted_a1b2c3 and gardevoir-exgardevoir-ex__deleted_a1b2c3. Generate the short id with bin2hex(random_bytes(3)) (6 hex chars, deterministic length) or Symfony\Component\Uid\Ulid truncated — match whatever the codebase already uses.

Recreate-on-create only: don't repurpose this for any other lookup.

Acceptance criteria

  • Creating an archetype whose name matches a soft-deleted archetype succeeds; the soft-deleted row is renamed with the suffix on both name and slug.
  • Same for slug (e.g. two different display names that slugify to the same value).
  • Rename happens in the same transaction as the create — no partial state if the create fails.
  • Admin list still shows only non-deleted rows.
  • Soft-deleted renamed rows remain restorable for audit (the suffix is appended, the original prefix is preserved for inspection).
  • Unit/functional test under tests/ covering: (a) name collision, (b) slug collision via differing names, (c) no collision still works unchanged.
  • docs/features.md gains an F2.27 row under §F2.

Key files

  • src/Entity/Archetype.php — unique constraints, soft-delete column, PrePersist/PreUpdate slug generator.
  • src/Form/ArchetypeFormType.php — current form (no UniqueEntity validator today).
  • src/Controller/AdminArchetypeController.php — create/edit flow.
  • src/Repository/ArchetypeRepository.php — add a findSoftDeletedByNameOrSlug() helper.
  • tests/Entity/ArchetypeTest.php — existing test file to extend.

Notes

  • Don't introduce a UniqueEntity Symfony validator before this fix — it would also fire on the soft-deleted row and re-introduce the block at validation time. The rename must happen before the new row is flushed.
  • Consider a dedicated ArchetypeNameCollisionResolver service for testability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status

    Next

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions