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.
124 lines
4.6 KiB
PHP
124 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Scolarite\Infrastructure\Api\Resource;
|
|
|
|
use ApiPlatform\Metadata\ApiProperty;
|
|
use ApiPlatform\Metadata\ApiResource;
|
|
use ApiPlatform\Metadata\Delete;
|
|
use ApiPlatform\Metadata\Get;
|
|
use ApiPlatform\Metadata\GetCollection;
|
|
use ApiPlatform\Metadata\Patch;
|
|
use ApiPlatform\Metadata\Post;
|
|
use App\Scolarite\Domain\Model\Evaluation\Evaluation;
|
|
use App\Scolarite\Infrastructure\Api\Processor\CreateEvaluationProcessor;
|
|
use App\Scolarite\Infrastructure\Api\Processor\DeleteEvaluationProcessor;
|
|
use App\Scolarite\Infrastructure\Api\Processor\UpdateEvaluationProcessor;
|
|
use App\Scolarite\Infrastructure\Api\Provider\EvaluationCollectionProvider;
|
|
use App\Scolarite\Infrastructure\Api\Provider\EvaluationItemProvider;
|
|
use DateTimeImmutable;
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
|
|
#[ApiResource(
|
|
shortName: 'Evaluation',
|
|
operations: [
|
|
new GetCollection(
|
|
uriTemplate: '/evaluations',
|
|
provider: EvaluationCollectionProvider::class,
|
|
name: 'get_evaluation_list',
|
|
),
|
|
new Get(
|
|
uriTemplate: '/evaluations/{id}',
|
|
provider: EvaluationItemProvider::class,
|
|
name: 'get_evaluation',
|
|
),
|
|
new Post(
|
|
uriTemplate: '/evaluations',
|
|
processor: CreateEvaluationProcessor::class,
|
|
validationContext: ['groups' => ['Default', 'create']],
|
|
name: 'create_evaluation',
|
|
),
|
|
new Patch(
|
|
uriTemplate: '/evaluations/{id}',
|
|
provider: EvaluationItemProvider::class,
|
|
processor: UpdateEvaluationProcessor::class,
|
|
validationContext: ['groups' => ['Default', 'update']],
|
|
name: 'update_evaluation',
|
|
),
|
|
new Delete(
|
|
uriTemplate: '/evaluations/{id}',
|
|
provider: EvaluationItemProvider::class,
|
|
processor: DeleteEvaluationProcessor::class,
|
|
name: 'delete_evaluation',
|
|
),
|
|
],
|
|
)]
|
|
final class EvaluationResource
|
|
{
|
|
#[ApiProperty(identifier: true)]
|
|
public ?string $id = null;
|
|
|
|
#[Assert\NotBlank(message: 'La classe est requise.', groups: ['create'])]
|
|
#[Assert\Uuid(message: 'L\'identifiant de la classe doit être un UUID valide.', groups: ['create'])]
|
|
public ?string $classId = null;
|
|
|
|
#[Assert\NotBlank(message: 'La matière est requise.', groups: ['create'])]
|
|
#[Assert\Uuid(message: 'L\'identifiant de la matière doit être un UUID valide.', groups: ['create'])]
|
|
public ?string $subjectId = null;
|
|
|
|
public ?string $teacherId = null;
|
|
|
|
#[Assert\NotBlank(message: 'Le titre est requis.', groups: ['create', 'update'])]
|
|
#[Assert\Length(max: 255, maxMessage: 'Le titre ne peut pas dépasser 255 caractères.')]
|
|
public ?string $title = null;
|
|
|
|
public ?string $description = null;
|
|
|
|
#[Assert\NotBlank(message: 'La date d\'évaluation est requise.', groups: ['create', 'update'])]
|
|
public ?string $evaluationDate = null;
|
|
|
|
#[Assert\Range(min: 1, max: 100, notInRangeMessage: 'Le barème doit être compris entre 1 et 100.')]
|
|
public ?int $gradeScale = null;
|
|
|
|
#[Assert\Range(min: 0.1, max: 10, notInRangeMessage: 'Le coefficient doit être compris entre 0.1 et 10.')]
|
|
public ?float $coefficient = null;
|
|
|
|
public ?string $status = null;
|
|
|
|
public ?string $className = null;
|
|
|
|
public ?string $subjectName = null;
|
|
|
|
public ?DateTimeImmutable $createdAt = null;
|
|
|
|
public ?DateTimeImmutable $updatedAt = null;
|
|
|
|
public ?DateTimeImmutable $gradesPublishedAt = null;
|
|
|
|
public static function fromDomain(
|
|
Evaluation $evaluation,
|
|
?string $className = null,
|
|
?string $subjectName = null,
|
|
): self {
|
|
$resource = new self();
|
|
$resource->id = (string) $evaluation->id;
|
|
$resource->classId = (string) $evaluation->classId;
|
|
$resource->subjectId = (string) $evaluation->subjectId;
|
|
$resource->teacherId = (string) $evaluation->teacherId;
|
|
$resource->title = $evaluation->title;
|
|
$resource->description = $evaluation->description;
|
|
$resource->evaluationDate = $evaluation->evaluationDate->format('Y-m-d');
|
|
$resource->gradeScale = $evaluation->gradeScale->maxValue;
|
|
$resource->coefficient = $evaluation->coefficient->value;
|
|
$resource->status = $evaluation->status->value;
|
|
$resource->className = $className;
|
|
$resource->subjectName = $subjectName;
|
|
$resource->createdAt = $evaluation->createdAt;
|
|
$resource->updatedAt = $evaluation->updatedAt;
|
|
$resource->gradesPublishedAt = $evaluation->gradesPublishedAt;
|
|
|
|
return $resource;
|
|
}
|
|
}
|