Files
Classeo/backend/migrations/Version20260327211549.php
Mathias STRASSER b70d5ec2ad
Some checks failed
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Naming Conventions (push) Has been cancelled
CI / Build Check (push) Has been cancelled
feat: Permettre à l'enseignant de saisir les notes dans une grille inline
L'enseignant avait besoin d'un moyen rapide de saisir les notes après
une évaluation. La grille inline permet de compléter 30 élèves en moins
de 3 minutes grâce à la navigation clavier (Tab/Enter/Shift+Tab),
la validation temps réel, l'auto-save debounced (500ms) et les
raccourcis /abs et /disp pour marquer absents/dispensés.

Les notes restent en brouillon jusqu'à publication explicite (avec
confirmation modale). Une fois publiées, les élèves les voient
immédiatement ; les parents après un délai de 24h (VisibiliteNotesPolicy).
Le mode offline stocke les notes en IndexedDB et synchronise
automatiquement au retour de la connexion.

Chaque modification est auditée dans grade_events via un event
subscriber qui écoute NoteSaisie/NoteModifiee sur le bus d'événements.
2026-03-29 10:02:03 +02:00

71 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20260327211549 extends AbstractMigration
{
public function getDescription(): string
{
return 'Création des tables grades et grade_events pour la saisie de notes et l\'audit';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
CREATE TABLE grades (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL,
evaluation_id UUID NOT NULL REFERENCES evaluations(id),
student_id UUID NOT NULL REFERENCES users(id),
value DECIMAL(5,2),
status VARCHAR(20) NOT NULL DEFAULT 'graded',
created_by UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (evaluation_id, student_id)
)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX idx_grades_tenant ON grades(tenant_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX idx_grades_evaluation ON grades(evaluation_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX idx_grades_student ON grades(student_id)
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE grade_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
grade_id UUID NOT NULL REFERENCES grades(id),
event_type VARCHAR(50) NOT NULL,
old_value DECIMAL(5,2),
new_value DECIMAL(5,2),
old_status VARCHAR(20),
new_status VARCHAR(20),
created_by UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX idx_grade_events_grade ON grade_events(grade_id)
SQL);
}
public function down(Schema $schema): void
{
$this->addSql('DROP TABLE IF EXISTS grade_events');
$this->addSql('DROP TABLE IF EXISTS grades');
}
}