# DI-004: Esquema GraphQL **Proyecto:** Sistema de Registro de Estudiantes **Fecha:** 2026-01-07 --- ## 1. Schema Completo ```graphql # ═══════════════════════════════════════════════════════════════ # TYPES # ═══════════════════════════════════════════════════════════════ type Student { id: Int! name: String! email: String! totalCredits: Int! enrollments: [Enrollment!]! } type Subject { id: Int! name: String! credits: Int! professor: Professor! enrolledStudents: [Student!]! } type Professor { id: Int! name: String! subjects: [Subject!]! } type Enrollment { id: Int! student: Student! subject: Subject! enrolledAt: DateTime! } type AvailableSubject { subject: Subject! isAvailable: Boolean! unavailableReason: String } type Classmate { subjectName: String! students: [String!]! } # ═══════════════════════════════════════════════════════════════ # QUERIES # ═══════════════════════════════════════════════════════════════ type Query { # Estudiantes students: [Student!]! student(id: Int!): Student # Materias subjects: [Subject!]! subject(id: Int!): Subject availableSubjects(studentId: Int!): [AvailableSubject!]! # Profesores professors: [Professor!]! professor(id: Int!): Professor # Compañeros de clase classmates(studentId: Int!): [Classmate!]! } # ═══════════════════════════════════════════════════════════════ # MUTATIONS # ═══════════════════════════════════════════════════════════════ type Mutation { # Estudiantes createStudent(input: CreateStudentInput!): StudentPayload! updateStudent(id: Int!, input: UpdateStudentInput!): StudentPayload! deleteStudent(id: Int!): DeletePayload! # Inscripciones enrollStudent(input: EnrollInput!): EnrollmentPayload! unenrollStudent(enrollmentId: Int!): DeletePayload! } # ═══════════════════════════════════════════════════════════════ # INPUTS # ═══════════════════════════════════════════════════════════════ input CreateStudentInput { name: String! email: String! } input UpdateStudentInput { name: String email: String } input EnrollInput { studentId: Int! subjectId: Int! } # ═══════════════════════════════════════════════════════════════ # PAYLOADS (Union para errores) # ═══════════════════════════════════════════════════════════════ type StudentPayload { student: Student errors: [String!] } type EnrollmentPayload { enrollment: Enrollment errors: [String!] } type DeletePayload { success: Boolean! errors: [String!] } # ═══════════════════════════════════════════════════════════════ # SCALARS # ═══════════════════════════════════════════════════════════════ scalar DateTime ``` --- ## 2. Ejemplos de Queries ### Listar estudiantes con inscripciones ```graphql query GetStudents { students { id name email totalCredits enrollments { subject { name professor { name } } } } } ``` ### Materias disponibles para inscripción ```graphql query GetAvailableSubjects($studentId: Int!) { availableSubjects(studentId: $studentId) { subject { id name credits professor { name } } isAvailable unavailableReason } } ``` ### Compañeros de clase ```graphql query GetClassmates($studentId: Int!) { classmates(studentId: $studentId) { subjectName students } } ``` --- ## 3. Ejemplos de Mutations ### Crear estudiante ```graphql mutation CreateStudent { createStudent(input: { name: "Juan Pérez", email: "juan@email.com" }) { student { id name email } errors } } ``` ### Inscribir en materia ```graphql mutation Enroll { enrollStudent(input: { studentId: 1, subjectId: 3 }) { enrollment { id subject { name } enrolledAt } errors } } ``` --- ## 4. DataLoaders (Evitar N+1) | DataLoader | Carga Batch | |------------|-------------| | `StudentByIdDataLoader` | Estudiantes por IDs | | `SubjectByIdDataLoader` | Materias por IDs | | `ProfessorByIdDataLoader` | Profesores por IDs | | `EnrollmentsByStudentDataLoader` | Inscripciones por estudiante | | `SubjectsByProfessorDataLoader` | Materias por profesor | --- ## 5. Errores de Negocio | Código | Mensaje | Contexto | |--------|---------|----------| | `MAX_ENROLLMENTS` | "Máximo 3 materias permitidas" | enrollStudent | | `SAME_PROFESSOR` | "Ya tienes materia con este profesor" | enrollStudent | | `DUPLICATE_EMAIL` | "Email ya registrado" | createStudent | | `NOT_FOUND` | "Estudiante no encontrado" | updateStudent |