addSql(<<<'SQL' CREATE TABLE qualimat_carrier ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, siret VARCHAR(20) NOT NULL, name VARCHAR(255) NOT NULL, address VARCHAR(255) DEFAULT NULL, postal_code VARCHAR(10) DEFAULT NULL, city VARCHAR(255) DEFAULT NULL, phone VARCHAR(32) DEFAULT NULL, department VARCHAR(64) DEFAULT NULL, status VARCHAR(32) NOT NULL, validity_date DATE DEFAULT NULL, is_active BOOLEAN DEFAULT TRUE NOT NULL, last_synced_at TIMESTAMP(6) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY (id), CONSTRAINT uq_qualimat_carrier_siret UNIQUE (siret) ) SQL); $this->addSql('CREATE INDEX idx_qualimat_carrier_active ON qualimat_carrier (is_active)'); $this->comment('qualimat_carrier', '_table', "Referentiel des transporteurs agrees QUALIMAT, synchronise quotidiennement depuis l'API qualimat.org (type=operateur_transport)."); $this->comment('qualimat_carrier', 'id', 'Cle technique auto-incrementee.'); $this->comment('qualimat_carrier', 'siret', 'SIRET normalise (chiffres sans espaces). Cle naturelle de synchro (unique). Source parfois incomplete (longueur variable), non contrainte a 14.'); $this->comment('qualimat_carrier', 'name', 'Raison sociale du transporteur (champs Nom = Societe de la source, identiques).'); $this->comment('qualimat_carrier', 'address', 'Adresse postale (voie). Nullable.'); $this->comment('qualimat_carrier', 'postal_code', 'Code postal. Nullable.'); $this->comment('qualimat_carrier', 'city', 'Ville. Nullable.'); $this->comment('qualimat_carrier', 'phone', 'Telephone au format source "indicatif|numero" (ex: +33|0608890316). Nullable.'); $this->comment('qualimat_carrier', 'department', 'Departement au format source "code - libelle" (ex: 65 - Hautes-Pyrenees). Nullable.'); $this->comment('qualimat_carrier', 'status', "Statut d'agrement QUALIMAT (valeurs connues : Audite, Valide, Suspendu). Valeur brute de la source, non contrainte."); $this->comment('qualimat_carrier', 'validity_date', 'Date de fin de validite de la certification (convertie depuis dd/mm/yyyy). Nullable.'); $this->comment('qualimat_carrier', 'is_active', 'Faux = transporteur absent du dernier import (soft-delete). Toute ligne non revue par le dernier run passe a FALSE.'); $this->comment('qualimat_carrier', 'last_synced_at', 'Horodatage du run de synchro ayant vu cette ligne en dernier (soft-delete : last_synced_at < run courant).'); $this->addSql(<<<'SQL' CREATE TABLE qualimat_sync_log ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, fetched_at TIMESTAMP(6) WITHOUT TIME ZONE NOT NULL, rows_total INT NOT NULL, rows_upserted INT NOT NULL, rows_skipped INT NOT NULL, rows_deactivated INT NOT NULL, created_at TIMESTAMP(6) WITHOUT TIME ZONE DEFAULT NOW() NOT NULL, PRIMARY KEY (id) ) SQL); $this->comment('qualimat_sync_log', '_table', 'Journal des synchronisations QUALIMAT (une ligne par run de la commande app:qualimat:sync).'); $this->comment('qualimat_sync_log', 'id', 'Cle technique auto-incrementee.'); $this->comment('qualimat_sync_log', 'fetched_at', "Horodatage de l'appel a l'API source (= run de synchro)."); $this->comment('qualimat_sync_log', 'rows_total', "Nombre d'items renvoyes par l'API."); $this->comment('qualimat_sync_log', 'rows_upserted', 'Nombre de transporteurs inseres ou mis a jour.'); $this->comment('qualimat_sync_log', 'rows_skipped', "Nombre d'items ignores (sans SIRET exploitable)."); $this->comment('qualimat_sync_log', 'rows_deactivated', 'Nombre de transporteurs passes a is_active=false (absents de cet import).'); $this->comment('qualimat_sync_log', 'created_at', 'Horodatage de fin du run (insertion du journal).'); } public function down(Schema $schema): void { $this->addSql('DROP TABLE IF EXISTS qualimat_sync_log'); $this->addSql('DROP TABLE IF EXISTS qualimat_carrier'); } /** * Pose un COMMENT ON TABLE/COLUMN en dollar-quoting Postgres ($_$...$_$) * pour eviter tout echappement d'apostrophes dans les descriptions. */ private function comment(string $table, string $column, string $description): void { $quotedTable = '"'.str_replace('"', '""', $table).'"'; if ('_table' === $column) { $this->addSql(sprintf('COMMENT ON TABLE %s IS $_$%s$_$', $quotedTable, $description)); return; } $this->addSql(sprintf( 'COMMENT ON COLUMN %s.%s IS $_$%s$_$', $quotedTable, '"'.str_replace('"', '""', $column).'"', $description, )); } }