feat(fournisseurs) : categories (M2M) + telephones (1-N) + import customer.json
All checks were successful
Auto Tag Develop / tag (push) Successful in 9s
All checks were successful
Auto Tag Develop / tag (push) Successful in 9s
- Nouvelles entites ConstructeurCategorie (referentiel M2M) et ConstructeurTelephone (1-N) - Constructeur : retrait colonne phone, ajout collections telephones/categories, groupes de serialisation constructeur:read/write - Migration : cree les 3 tables, migre la colonne phone existante vers constructeur_telephone, drop phone - Commande app:import-fournisseurs (dry-run par defaut, --force) : non destructive, find-or-create par nom, ne touche jamais un ID existant, ajout-seulement pour telephones/categories - MAJ MCP tools / MachineStructureController / audit subscriber / tests - Frontend : page constructeurs avec telephones multiples + categories (tableau, filtre, formulaire), composable useConstructeurCategories, composant ConstructeurCategorieSelect Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20260512150000_AddConstructeurCategoriesAndPhones extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add constructeur_categorie + constructeur_categories (M2M) + constructeur_telephone (1-N); migrate constructeurs.phone into constructeur_telephone then drop the phone column';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// 1. Référentiel de catégories de fournisseurs.
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS constructeur_categorie (
|
||||
id VARCHAR(36) NOT NULL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||
updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL
|
||||
)
|
||||
SQL);
|
||||
|
||||
// 2. Table de jointure many-to-many fournisseur <-> catégorie.
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS constructeur_categories (
|
||||
constructeur_id VARCHAR(36) NOT NULL REFERENCES constructeurs(id) ON DELETE CASCADE,
|
||||
categorie_id VARCHAR(36) NOT NULL REFERENCES constructeur_categorie(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY(constructeur_id, categorie_id)
|
||||
)
|
||||
SQL);
|
||||
$this->addSql('CREATE INDEX IF NOT EXISTS idx_constructeur_categories_categorie ON constructeur_categories (categorie_id)');
|
||||
|
||||
// 3. Téléphones (un fournisseur peut en avoir plusieurs).
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS constructeur_telephone (
|
||||
id VARCHAR(36) NOT NULL PRIMARY KEY,
|
||||
constructeurid VARCHAR(36) NOT NULL REFERENCES constructeurs(id) ON DELETE CASCADE,
|
||||
numero VARCHAR(50) NOT NULL,
|
||||
label VARCHAR(100) DEFAULT NULL,
|
||||
createdat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
|
||||
updatedat TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL
|
||||
)
|
||||
SQL);
|
||||
$this->addSql('CREATE INDEX IF NOT EXISTS idx_constructeur_telephone_constructeur ON constructeur_telephone (constructeurid)');
|
||||
|
||||
// 4. Migration des téléphones existants (colonne unique) vers la nouvelle table.
|
||||
$this->addSql(<<<'SQL'
|
||||
INSERT INTO constructeur_telephone (id, constructeurid, numero, label, createdat, updatedat)
|
||||
SELECT
|
||||
'cl' || substring(md5(random()::text || clock_timestamp()::text || c.id), 1, 24),
|
||||
c.id,
|
||||
trim(c.phone),
|
||||
NULL,
|
||||
NOW(),
|
||||
NOW()
|
||||
FROM constructeurs c
|
||||
WHERE c.phone IS NOT NULL AND trim(c.phone) <> ''
|
||||
SQL);
|
||||
|
||||
// 5. La colonne unique n'est plus la source de vérité.
|
||||
$this->addSql('ALTER TABLE constructeurs DROP COLUMN IF EXISTS phone');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE constructeurs ADD COLUMN IF NOT EXISTS phone VARCHAR(255) DEFAULT NULL');
|
||||
|
||||
// Restaure un téléphone par fournisseur (le plus récemment créé), best-effort.
|
||||
$this->addSql(<<<'SQL'
|
||||
UPDATE constructeurs c
|
||||
SET phone = t.numero
|
||||
FROM (
|
||||
SELECT DISTINCT ON (constructeurid) constructeurid, numero
|
||||
FROM constructeur_telephone
|
||||
ORDER BY constructeurid, createdat DESC
|
||||
) t
|
||||
WHERE t.constructeurid = c.id
|
||||
SQL);
|
||||
|
||||
$this->addSql('DROP TABLE IF EXISTS constructeur_telephone');
|
||||
$this->addSql('DROP TABLE IF EXISTS constructeur_categories');
|
||||
$this->addSql('DROP TABLE IF EXISTS constructeur_categorie');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user