@startuml sequence-enrollment !theme plain skinparam sequenceMessageAlign center skinparam responseMessageBelowArrow true skinparam sequenceParticipantBackgroundColor #F8F9FA skinparam sequenceParticipantBorderColor #495057 title Secuencia: Inscripción de Estudiante en Materia actor "Estudiante" as user participant "Frontend\n(Angular)" as frontend participant "API GraphQL\n(HotChocolate)" as api participant "EnrollStudentHandler" as handler participant "EnrollmentDomainService" as domainService participant "StudentRepository" as studentRepo participant "SubjectRepository" as subjectRepo participant "EnrollmentRepository" as enrollRepo database "SQL Server" as db == Solicitud de Inscripción == user -> frontend : Selecciona materia\ny hace clic en "Inscribir" activate frontend frontend -> api : mutation enrollStudent(\n studentId, subjectId) activate api api -> handler : Handle(EnrollStudentCommand) activate handler == Obtención de Datos == handler -> studentRepo : GetByIdWithEnrollmentsAsync(studentId) activate studentRepo studentRepo -> db : SELECT Student + Enrollments db --> studentRepo : Student data studentRepo --> handler : Student deactivate studentRepo handler -> subjectRepo : GetByIdAsync(subjectId) activate subjectRepo subjectRepo -> db : SELECT Subject db --> subjectRepo : Subject data subjectRepo --> handler : Subject deactivate subjectRepo == Validación de Reglas de Negocio == handler -> domainService : ValidateEnrollment(student, subject) activate domainService domainService -> domainService : CheckMaxEnrollments()\n[máx 3 materias] alt Estudiante tiene 3 materias domainService --> handler : throw MaxEnrollmentsExceededException handler --> api : Error: "Límite de materias alcanzado" api --> frontend : { errors: [...] } frontend --> user : Muestra mensaje de error end domainService -> domainService : CheckProfessorConstraint()\n[no repetir profesor] alt Ya tiene materia con el profesor domainService --> handler : throw SameProfessorConstraintException handler --> api : Error: "Ya tienes materia con este profesor" api --> frontend : { errors: [...] } frontend --> user : Muestra mensaje de error end domainService --> handler : Validación OK deactivate domainService == Persistencia == handler -> enrollRepo : AddAsync(enrollment) activate enrollRepo enrollRepo -> db : INSERT Enrollment db --> enrollRepo : OK enrollRepo --> handler : Enrollment deactivate enrollRepo handler --> api : EnrollmentPayload deactivate handler api --> frontend : { enrollment: {...} } deactivate api frontend --> user : Muestra confirmación:\n"Inscrito en [materia]" deactivate frontend @enduml