feat: Gestion des matières scolaires

Les établissements ont besoin de définir leur référentiel de matières
pour pouvoir ensuite les associer aux enseignants et aux classes.
Cette fonctionnalité permet aux administrateurs de créer, modifier et
archiver les matières avec leurs propriétés (nom, code court, couleur).

L'architecture suit le pattern DDD avec des Value Objects utilisant
les property hooks PHP 8.5 pour garantir l'immutabilité et la validation.
L'isolation multi-tenant est assurée par vérification dans les handlers.
This commit is contained in:
2026-02-05 20:42:31 +01:00
parent 8e09e0abf1
commit 0d5a097c4c
50 changed files with 5882 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Migration pour créer la table subjects (matières).
*
* @see Story 2.2 - Création et Gestion des Matières
* @see FR74 - Structurer l'offre pédagogique
*/
final class Version20260205100001 extends AbstractMigration
{
public function getDescription(): string
{
return 'Create subjects table for school subjects management';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
CREATE TABLE subjects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL,
school_id UUID NOT NULL,
name VARCHAR(100) NOT NULL,
code VARCHAR(10) NOT NULL,
color VARCHAR(7),
description TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'active',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ NULL
)
SQL);
// Index pour la recherche par tenant et school
$this->addSql('CREATE INDEX idx_subjects_tenant_id ON subjects(tenant_id)');
$this->addSql('CREATE INDEX idx_subjects_school_id ON subjects(school_id)');
// Index unique partiel pour l'unicité du code par tenant/school (excluant les matières archivées)
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX idx_subjects_unique_code_active
ON subjects (tenant_id, school_id, code)
WHERE deleted_at IS NULL
SQL);
}
public function down(Schema $schema): void
{
$this->addSql('DROP TABLE IF EXISTS subjects');
}
}