addSql(<<<'SQL' CREATE TABLE uploaded_document ( id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, original_filename VARCHAR(255) NOT NULL, stored_path VARCHAR(512) NOT NULL, mime_type VARCHAR(100) NOT NULL, size_bytes INT NOT NULL, checksum VARCHAR(64) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, created_by INT DEFAULT NULL, PRIMARY KEY (id), CONSTRAINT fk_uploaded_document_created_by FOREIGN KEY (created_by) REFERENCES "user" (id) ON DELETE SET NULL ) SQL); // Postgres n'indexe pas automatiquement les colonnes de FK. $this->addSql('CREATE INDEX idx_uploaded_document_created_by ON uploaded_document (created_by)'); // Recherche d'integrite / future deduplication par empreinte sha256. $this->addSql('CREATE INDEX idx_uploaded_document_checksum ON uploaded_document (checksum)'); $this->addSql('COMMENT ON TABLE uploaded_document IS $_$Fichiers televerses (infra generique Shared, ERP-154) — documents immuables (PDF / images), 1er consommateur la Decharge M4.$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.id IS $_$Identifiant interne auto-incremente.$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.original_filename IS $_$Nom de fichier d origine fourni par le client (≤ 255) — metadonnee d affichage uniquement, jamais utilise pour le stockage disque.$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.stored_path IS $_$Chemin relatif du fichier sous var/uploads (ex: 2026/06/.pdf) — nom genere aleatoirement, jamais le nom client.$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.mime_type IS $_$Type MIME detecte SERVER-SIDE via getMimeType (jamais getClientMimeType, spoofable) — borne a la whitelist FileUploader (PDF + images).$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.size_bytes IS $_$Taille du fichier en octets — bornee par FileUploader::MAX_SIZE_BYTES.$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.checksum IS $_$Empreinte SHA-256 du contenu (64 caracteres hex) — controle d integrite + deduplication eventuelle (hors scope).$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.created_at IS $_$Horodatage UTC du televersement — rempli par FileUploader via l horloge injectee (pas via TimestampableBlamableSubscriber).$_$'); $this->addSql('COMMENT ON COLUMN uploaded_document.created_by IS $_$ID de l utilisateur ayant televerse le fichier — null hors HTTP (CLI, fixture). FK -> "user".id, ON DELETE SET NULL.$_$'); } public function down(Schema $schema): void { $this->addSql('DROP TABLE IF EXISTS uploaded_document'); } }