Backend service and controller for converting piece categories to component categories (and vice-versa). Uses raw SQL in a transaction to preserve IDs and transfer all related data (documents, custom fields, constructeurs). Includes php-cs-fixer formatting pass on existing controllers/entities. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
118 lines
2.8 KiB
PHP
118 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Entity;
|
|
|
|
use App\Repository\AuditLogRepository;
|
|
use DateTimeImmutable;
|
|
use Doctrine\DBAL\Types\Types;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
|
|
#[ORM\Entity(repositoryClass: AuditLogRepository::class)]
|
|
#[ORM\Table(name: 'audit_logs')]
|
|
#[ORM\Index(name: 'idx_audit_entity', columns: ['entityType', 'entityId'])]
|
|
#[ORM\Index(name: 'idx_audit_created_at', columns: ['createdAt'])]
|
|
#[ORM\HasLifecycleCallbacks]
|
|
class AuditLog
|
|
{
|
|
#[ORM\Id]
|
|
#[ORM\Column(type: Types::STRING, length: 36)]
|
|
private ?string $id = null;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 50)]
|
|
private string $entityType;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 36)]
|
|
private string $entityId;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 20)]
|
|
private string $action;
|
|
|
|
#[ORM\Column(type: Types::JSON, nullable: true)]
|
|
private ?array $diff = null;
|
|
|
|
#[ORM\Column(type: Types::JSON, nullable: true)]
|
|
private ?array $snapshot = null;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 36, nullable: true)]
|
|
private ?string $actorProfileId = null;
|
|
|
|
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'createdAt')]
|
|
private DateTimeImmutable $createdAt;
|
|
|
|
public function __construct(
|
|
string $entityType,
|
|
string $entityId,
|
|
string $action,
|
|
?array $diff = null,
|
|
?array $snapshot = null,
|
|
?string $actorProfileId = null,
|
|
) {
|
|
$this->entityType = $entityType;
|
|
$this->entityId = $entityId;
|
|
$this->action = $action;
|
|
$this->diff = $diff;
|
|
$this->snapshot = $snapshot;
|
|
$this->actorProfileId = $actorProfileId;
|
|
}
|
|
|
|
#[ORM\PrePersist]
|
|
public function initializeAuditLog(): void
|
|
{
|
|
if (!isset($this->createdAt)) {
|
|
$this->createdAt = new DateTimeImmutable();
|
|
}
|
|
|
|
if (null === $this->id) {
|
|
$this->id = $this->generateCuid();
|
|
}
|
|
}
|
|
|
|
public function getId(): ?string
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getEntityType(): string
|
|
{
|
|
return $this->entityType;
|
|
}
|
|
|
|
public function getEntityId(): string
|
|
{
|
|
return $this->entityId;
|
|
}
|
|
|
|
public function getAction(): string
|
|
{
|
|
return $this->action;
|
|
}
|
|
|
|
public function getDiff(): ?array
|
|
{
|
|
return $this->diff;
|
|
}
|
|
|
|
public function getSnapshot(): ?array
|
|
{
|
|
return $this->snapshot;
|
|
}
|
|
|
|
public function getActorProfileId(): ?string
|
|
{
|
|
return $this->actorProfileId;
|
|
}
|
|
|
|
public function getCreatedAt(): DateTimeImmutable
|
|
{
|
|
return $this->createdAt;
|
|
}
|
|
|
|
private function generateCuid(): string
|
|
{
|
|
// Keep the same lightweight CUID-like strategy used across the project.
|
|
return 'cl'.substr(strtolower(base_convert(bin2hex(random_bytes(12)), 16, 36)), 0, 24);
|
|
}
|
|
}
|