feat(versioning) : add entity versioning with numbered versions and restore

Backend:
- Migration: version column on audit_logs and machines
- AuditLog, Machine, Composant, Piece, Product: version + skipAudit properties
- AbstractAuditSubscriber: auto-increment version, skip on restore, fix decimal diff
- Enriched snapshots with slots, custom fields and version number
- AuditLogRepository: findVersionHistory, findByVersion
- EntityVersionService: list, preview, restore with skeleton/integrity checks
- EntityVersionController: REST endpoints for all 4 entity types
- 11 tests covering list, preview, restore, auth

Frontend: update submodule pointer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-26 15:01:56 +01:00
parent 162c6ece71
commit 9299a46c8b
16 changed files with 1425 additions and 35 deletions

View File

@@ -35,6 +35,38 @@ final class AuditLogRepository extends ServiceEntityRepository
;
}
/**
* @return list<AuditLog>
*/
public function findVersionHistory(string $entityType, string $entityId): array
{
return $this->createQueryBuilder('a')
->andWhere('a.entityType = :entityType')
->andWhere('a.entityId = :entityId')
->andWhere('a.version IS NOT NULL')
->setParameter('entityType', $entityType)
->setParameter('entityId', $entityId)
->orderBy('a.version', 'DESC')
->getQuery()
->getResult()
;
}
public function findByVersion(string $entityType, string $entityId, int $version): ?AuditLog
{
return $this->createQueryBuilder('a')
->andWhere('a.entityType = :entityType')
->andWhere('a.entityId = :entityId')
->andWhere('a.version = :version')
->setParameter('entityType', $entityType)
->setParameter('entityId', $entityId)
->setParameter('version', $version)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult()
;
}
/**
* @param array{entityType?: string, action?: string} $filters
*