112 lines
3.1 KiB
Plaintext
112 lines
3.1 KiB
Plaintext
@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 (con JWT)
|
|
|
|
actor "Estudiante" as user
|
|
participant "Frontend\n(Angular)" as frontend
|
|
participant "API GraphQL\n(HotChocolate)" as api
|
|
participant "JWT Middleware" as jwt
|
|
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
|
|
|
|
== Autenticación (previo) ==
|
|
|
|
note over user, frontend
|
|
El estudiante ya inició sesión
|
|
y tiene un JWT válido almacenado
|
|
end note
|
|
|
|
== Solicitud de Inscripción ==
|
|
|
|
user -> frontend : Selecciona materia\ny hace clic en "Inscribir"
|
|
activate frontend
|
|
|
|
frontend -> api : mutation enrollStudent(\n studentId, subjectId)\n[Authorization: Bearer <JWT>]
|
|
activate api
|
|
|
|
api -> jwt : Validate JWT
|
|
activate jwt
|
|
jwt -> jwt : Verify signature\n& expiration
|
|
jwt --> api : ClaimsPrincipal
|
|
deactivate jwt
|
|
|
|
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
|
|
|
|
alt Cuenta no activada
|
|
handler --> api : Error: "Cuenta no activada"
|
|
api --> frontend : { errors: [...] }
|
|
frontend --> user : Muestra mensaje:\n"Activa tu cuenta primero"
|
|
end
|
|
|
|
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
|