Files
pta/app/Models/SchemaModel.php
PTA 8d900bede8 Retrait de l'ancienne case « formation déjà prévue dans la répartition annuelle »
La fiche agent portait deux cases à cocher pour la formation depuis l'ajout du
droit à l'enveloppe : celle-ci faisait doublon et disparaît, avec sa colonne
`agent.formation_repartition_annuelle` et tout ce qui la lisait — projection
SQL, création et modification d'agent, formulaires d'administration, JS, et
liste des colonnes obligatoires de SchemaModel.

L'enveloppe de formation ne dépend donc plus que du droit :
AgentModel::trainingEnvelopeMinutes() rend 14 h ou 0.

La colonne est retirée du socle (le CREATE TABLE ne la crée plus sur une base
neuve) et par migration_v7_9c sur les bases existantes. migration_v7_9b perd sa
clause AFTER, qui pointait sur la colonne supprimée et aurait fait échouer
l'installation d'une base neuve ; sa réécriture est sans risque, le script de
migration rejoue un fichier modifié et l'ALTER reste idempotent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 15:40:56 +02:00

121 lines
4.2 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Models;
final class SchemaModel extends BaseModel
{
public function assertCurrent(): void
{
$requiredTables = [
'agent',
'structure',
'agent_structure',
'motif_planning',
'semaine',
'planning',
'creneau_horaire',
'quota_agent_annuel',
'modele_semaine_agent',
'modele_semaine_creneau',
'structure_couverture_horaire',
'periode_vacance',
'poste_agent',
'pta_annuel',
'agent_structure_souhait',
'agent_contrainte',
'equipe_pta',
'equipe_pta_membre',
'structure_creneau_reference',
];
$placeholders = implode(',', array_fill(0, count($requiredTables), '?'));
$stmt = $this->pdo->prepare(
"SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ($placeholders)"
);
$stmt->execute($requiredTables);
$existing = $stmt->fetchAll(\PDO::FETCH_COLUMN);
$missingTables = array_values(array_diff($requiredTables, $existing));
if ($missingTables) {
throw new \RuntimeException(
'Base PTA incomplète : table(s) manquante(s) : '
. implode(', ', $missingTables)
. '. Exécutez database/install_complet.sql ou les migrations nécessaires.'
);
}
$requiredColumns = [
'creneau_horaire' => ['id_motif'],
'planning' => ['date_validation'],
'agent' => ['email', 'telephone', 'adresse', 'est_diplome', 'diplome_libelle', 'id_structure', 'id_poste', 'type_contrat', 'date_debut_contrat', 'date_fin_contrat', 'droit_enveloppe_formation', 'commentaire_pta'],
'structure' => ['type_affectation'],
];
foreach ($requiredColumns as $table => $columns) {
$columnPlaceholders = implode(',', array_fill(0, count($columns), '?'));
$params = array_merge([$table], $columns);
$columnStmt = $this->pdo->prepare(
"SELECT COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = ?
AND COLUMN_NAME IN ($columnPlaceholders)"
);
$columnStmt->execute($params);
$existingColumns = $columnStmt->fetchAll(\PDO::FETCH_COLUMN);
$missingColumns = array_values(array_diff($columns, $existingColumns));
if ($missingColumns) {
throw new \RuntimeException(sprintf(
'Base PTA incomplète : colonne(s) manquante(s) dans %s : %s.',
$table,
implode(', ', $missingColumns)
));
}
}
$this->assertAccessViews();
}
/**
* Les vues d'accès portent l'intégralité des règles de droits. Si elles
* manquent, l'application doit refuser de démarrer plutôt que de tourner
* sans contrôle de périmètre.
*/
private function assertAccessViews(): void
{
$requiredViews = [
'v_acces_role_page',
'v_acces_role_permission',
'v_acces_identite_agent',
'v_acces_identite_structure',
'v_acces_agent_par_structure',
'v_acces_perimetre_creneau',
'v_acces_perimetre_planning',
];
$placeholders = implode(',', array_fill(0, count($requiredViews), '?'));
$stmt = $this->pdo->prepare(
"SELECT TABLE_NAME
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ($placeholders)"
);
$stmt->execute($requiredViews);
$missing = array_values(array_diff($requiredViews, $stmt->fetchAll(\PDO::FETCH_COLUMN)));
if ($missing) {
throw new \RuntimeException(
'Contrôle d’accès indisponible : vue(s) manquante(s) : '
. implode(', ', $missing)
. '. Exécutez database/migration_v7_8_securite_acces.sql.'
);
}
}
}