@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
