422. * - Get (/uploaded_documents/{id}) : necessaire pour qu'API Platform genere * l'IRI renvoyee par le Post. Protege par IS_AUTHENTICATED_FULLY uniquement * (pas de RBAC ni de cloisonnement tenant ici) : cette ressource est une * infra GENERIQUE qui ne porte aucune notion de proprietaire metier. Le * cloisonnement d'acces (qui peut voir quel document) est volontairement * delegue au module CONSOMMATEUR (ex: la Decharge M4), qui exposera le * document via sa propre ressource cloisonnee plutot que via cet endpoint * technique. Ne renvoie que des metadonnees (jamais le binaire). * * Pas de GetCollection exposee (non requise) — la regle de pagination ne * s'applique donc pas ici. */ #[ORM\Entity] #[ORM\Table(name: 'uploaded_document')] #[ApiResource( operations: [ new Get( security: "is_granted('IS_AUTHENTICATED_FULLY')", ), new Post( // Entree multipart : le binaire arrive en multipart/form-data sous // le champ « file ». Sans cet inputFormats, API Platform rejette la // requete en 415. inputFormats: ['multipart' => ['multipart/form-data']], // Le fichier n'est pas deserialisable dans l'entite : le processor // lit le binaire de la requete. La validation est portee par le // FileUploader (MIME server-side, taille), pas par les contraintes. deserialize: false, validate: false, security: "is_granted('IS_AUTHENTICATED_FULLY')", processor: UploadedDocumentProcessor::class, ), ], normalizationContext: ['groups' => ['uploaded_document:read']], )] class UploadedDocument { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] #[Groups(['uploaded_document:read'])] private ?int $id = null; #[ORM\Column(name: 'original_filename', length: 255)] #[Groups(['uploaded_document:read'])] private string $originalFilename; #[ORM\Column(name: 'stored_path', length: 512)] #[Groups(['uploaded_document:read'])] private string $storedPath; #[ORM\Column(name: 'mime_type', length: 100)] #[Groups(['uploaded_document:read'])] private string $mimeType; #[ORM\Column(name: 'size_bytes', type: 'integer')] #[Groups(['uploaded_document:read'])] private int $sizeBytes; #[ORM\Column(name: 'checksum', length: 64)] #[Groups(['uploaded_document:read'])] private string $checksum; #[ORM\Column(name: 'created_at', type: 'datetime_immutable')] #[Groups(['uploaded_document:read'])] private DateTimeImmutable $createdAt; #[ORM\ManyToOne(targetEntity: UserInterface::class)] #[ORM\JoinColumn(name: 'created_by', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')] private ?UserInterface $createdBy = null; public function __construct( string $originalFilename, string $storedPath, string $mimeType, int $sizeBytes, string $checksum, DateTimeImmutable $createdAt, ) { $this->originalFilename = $originalFilename; $this->storedPath = $storedPath; $this->mimeType = $mimeType; $this->sizeBytes = $sizeBytes; $this->checksum = $checksum; $this->createdAt = $createdAt; } public function getId(): ?int { return $this->id; } public function getOriginalFilename(): string { return $this->originalFilename; } public function getStoredPath(): string { return $this->storedPath; } public function getMimeType(): string { return $this->mimeType; } public function getSizeBytes(): int { return $this->sizeBytes; } public function getChecksum(): string { return $this->checksum; } public function getCreatedAt(): DateTimeImmutable { return $this->createdAt; } public function getCreatedBy(): ?UserInterface { return $this->createdBy; } public function setCreatedBy(?UserInterface $user): void { $this->createdBy = $user; } }