@startuml domain-model
!theme plain
skinparam classAttributeIconSize 0
skinparam classFontStyle bold
skinparam classBackgroundColor #F8F9FA
skinparam classBorderColor #495057

title Sistema de Registro de Estudiantes - Modelo de Dominio

package "Domain" {

    class Student <<Entity>> {
        - id: int
        - name: string
        - email: Email
        - enrollments: List<Enrollment>
        --
        + getTotalCredits(): int
        + canEnrollIn(subject: Subject): bool
        + enroll(subject: Subject): Enrollment
        + unenroll(enrollmentId: int): void
    }

    class Subject <<Entity>> {
        - id: int
        - name: string
        - credits: int {= 3}
        - professorId: int
        --
        + getProfessor(): Professor
    }

    class Professor <<Entity>> {
        - id: int
        - name: string
        - subjects: List<Subject>
        --
        + getSubjects(): List<Subject>
    }

    class Enrollment <<Entity>> {
        - id: int
        - studentId: int
        - subjectId: int
        - enrolledAt: DateTime
        --
        + getStudent(): Student
        + getSubject(): Subject
    }

    class Email <<Value Object>> {
        - value: string
        --
        + {static} create(value: string): Email
        - validate(value: string): void
    }

    class EnrollmentDomainService <<Domain Service>> {
        --
        + validateEnrollment(student: Student, subject: Subject): void
        - checkMaxEnrollments(student: Student): void
        - checkProfessorConstraint(student: Student, subject: Subject): void
    }

    ' Relaciones
    Student "1" *-- "0..3" Enrollment : tiene
    Subject "1" *-- "0..*" Enrollment : inscripciones
    Professor "1" *-- "2" Subject : imparte
    Student *-- Email : email

    EnrollmentDomainService ..> Student : valida
    EnrollmentDomainService ..> Subject : valida
}

note bottom of Student
  <b>Invariantes:</b>
  - Máximo 3 inscripciones
  - Email válido y único
  - No repetir profesor
end note

note bottom of Subject
  <b>Invariantes:</b>
  - Créditos = 3 (fijo)
  - Pertenece a un profesor
end note

note right of Professor
  Cada profesor
  imparte exactamente
  2 materias
end note

@enduml
