Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Renzo717/Aula-Virtual-Universidad-Radiolocucion/llms.txt

Use this file to discover all available pages before exploring further.

The preceptor is an administrative support role that sits between the admin and the teaching staff. Preceptors do not teach subjects and do not attend courses — their work is purely operational. They are responsible for keeping the enrolment register up to date, ensuring that students are correctly assigned to their careers and standalone subjects, adjusting subject metadata such as assigned teachers and timetables, entering official final grades, and generating grade bulletins for reporting purposes. A preceptor account cannot be self-registered; it must be created by an admin via POST /api/users with rol: 'preceptor'.

Role Scope

Can Do

Manage student enrolments, edit subject name and schedule, assign teachers to subjects, enter and update final grades for any subject, download any student’s boletín, search users.

Cannot Do

Create or delete user accounts, create or delete careers, create subjects from scratch, delete subjects, access virtual classrooms, view audit logs or admin dashboard stats.

Enrolment Management

All inscripciones routes require either admin or preceptor role. The router applies requireRole('admin', 'preceptor') as router-level middleware, so all endpoints below share the same access rule:
// apps/api/src/routes/inscripciones.ts
router.use(requireAuth, requireRole('admin', 'preceptor'));

View a student’s enrolments

GET /api/inscripciones/usuario/:userId
Returns all enrolment records for the specified user, joined with career and subject details:
[
  {
    "id": "insc-uuid",
    "user_id": "student-uuid",
    "carrera_id": "carrera-uuid",
    "materia_id": null,
    "estado": "activa",
    "created_at": "2025-03-01T10:00:00Z",
    "carrera": { "nombre": "Locución Integral", "codigo": "LI-2024", "anio": 1 }
  }
]
Results are ordered by created_at descending so the most recent enrolment appears first.

Enrol a student in a career

POST /api/inscripciones
Content-Type: application/json

{
  "user_id":    "student-uuid",
  "carrera_id": "carrera-uuid"
}
The server verifies that the career exists and is activa, and that the student is not already enrolled with estado: 'activa'. A duplicate enrolment attempt returns 400 El alumno ya está inscripto en esta carrera.

Enrol a student in a standalone subject

POST /api/inscripciones
Content-Type: application/json

{
  "user_id":   "student-uuid",
  "materia_id": "materia-uuid"
}
This path enrols the student in a subject that has no carrera_id (a standalone course). The server checks that the subject exists, is active, and has carrera_id: null. The response includes the new enrolment record joined with the subject’s nombre, fecha_inicio, and fecha_fin. The createInscripcionSchema requires that at least one of carrera_id or materia_id is present:
// packages/shared/src/schemas.ts
export const createInscripcionSchema = z
  .object({
    user_id:    z.string().uuid(),
    carrera_id: z.string().uuid().optional(),
    materia_id: z.string().uuid().optional(),
  })
  .refine((data) => data.carrera_id || data.materia_id, {
    message: 'Debe indicar carrera_id o materia_id',
  });
There is currently no DELETE /api/inscripciones endpoint. To revoke access, an admin must set the enrolment estado to 'baja' directly via the database or a future admin-only patch endpoint.

Subject Editing

Preceptors can update the metadata of any existing subject using:
PATCH /api/carreras/materias/:id
Content-Type: application/json
The allowed fields are defined by updateMateriaSchema:
// packages/shared/src/schemas.ts
export const updateMateriaSchema = z.object({
  nombre:     z.string().min(2).optional(),
  promocional: z.boolean().optional(),
  docente_id: z.string().uuid().nullable().optional(),
  horarios:   horariosCursadoSchema.optional(),
  horario:    z.string().regex(/^\d{2}:\d{2} - \d{2}:\d{2}$/).optional().or(z.literal('')),
});
Typical preceptor use cases:
  • Reassign a teacher — set docente_id to the new teacher’s UUID (or null to unassign)
  • Update the timetable — pass a horarios array with day and time slots
  • Rename a subject — update nombre
  • Mark as promocional — set promocional: true when a subject allows direct promotion

Example: reassign teacher and update schedule

PATCH /api/carreras/materias/mat-uuid
Content-Type: application/json

{
  "docente_id": "new-docente-uuid",
  "horarios": [
    { "dia": "martes",  "inicio": "17:00", "fin": "19:00" },
    { "dia": "jueves",  "inicio": "17:00", "fin": "19:00" }
  ]
}
When horarios is provided the API automatically generates a formatted horario display string via formatHorarios for use in the UI.
Preceptors cannot create or delete subjects. POST /api/carreras/materias and DELETE /api/carreras/materias/:id are restricted to the admin role. If a subject needs to be created or deactivated, an admin must perform that action.

Listing Subjects by Teacher

Preceptors can look up all active subjects assigned to a specific docente, which is useful when reassigning workloads or auditing timetable conflicts:
GET /api/carreras/docentes/:docenteId/materias
Returns an array of Materia objects joined with the parent career’s nombre and anio:
[
  {
    "id": "mat-uuid",
    "nombre": "Fonética y Dicción",
    "carrera_id": "car-uuid",
    "docente_id": "docente-uuid",
    "horarios": [{ "dia": "lunes", "inicio": "18:00", "fin": "20:00" }],
    "activa": true,
    "carrera": { "nombre": "Locución Integral", "anio": 1 }
  }
]
Preceptors share the user search endpoint with admins. This allows them to find a student’s UUID before creating an enrolment, without having access to the full user management panel:
GET /api/users/search?q=perez
Returns up to 30 profiles matching the query across nombre, apellido, and dni. The response only includes id, nombre, apellido, email, dni, rol, and avatar_url — not sensitive fields like status or last_login.

Final Grades

Preceptors can enter and update official final marks for any subject — they are not limited to subjects assigned to a particular teacher. This is intentional: preceptors often need to correct or complete grade records when a teacher is unavailable.
GET /api/finales/materia/:materiaId
Returns the enrolled students list with their current final marks for the academic year derived from the subject’s fecha_inicio.
PUT /api/finales/materia/:materiaId
Content-Type: application/json

{
  "notas": [
    {
      "estudiante_id": "student-uuid-1",
      "nota": 8,
      "nota_recuperatorio": null,
      "libre": false,
      "regular": true
    },
    {
      "estudiante_id": "student-uuid-2",
      "nota": null,
      "nota_recuperatorio": null,
      "libre": true,
      "regular": false
    }
  ]
}
The bulk upsert uses (estudiante_id, materia_id, anio_academico) as the conflict key, so it is safe to call repeatedly. Only enrolled students are accepted — submitting a grade for a student not enrolled in the subject returns 400 Alumno no inscripto en la comisión de esta materia. Each UpsertNotaFinalInput accepts:
FieldTypeNotes
estudiante_idstring (UUID)Required
notanumber | nullFinal exam mark, 1–10
nota_recuperatorionumber | nullResit mark, 1–10 (optional)
librebooleanStudent sat as libre (free candidate)
regularbooleanStudent is regular; mutually exclusive with libre

Grade Bulletins

Preceptors can download the grade bulletin for any student:
GET /api/boletin/:estudianteId
The bulletin (BoletinAlumnoResumen + BoletinMateriaFila[]) is typically used for formal reporting to the university registrar. Each row shows the subject name, whether it is promocional, the student’s libre/regular status, the nota, and the nota_recuperatorio.
When preparing batch reports for the academic committee, preceptors can loop over a list of student IDs retrieved from /api/users/search or /api/inscripciones/usuario/:userId to generate individual bulletins programmatically.

Endpoint Reference

MethodEndpointDescription
GET/api/users/search?q=Search users by name or DNI (max 30 results)
GET/api/inscripciones/usuario/:userIdList all enrolments for a student
POST/api/inscripcionesEnrol a student in a career or standalone subject
PATCH/api/carreras/materias/:idEdit subject name, teacher, or schedule
GET/api/carreras/docentes/:docenteId/materiasList active subjects by teacher
GET/api/finales/materia/:materiaIdView final grade roster for a subject
PUT/api/finales/materia/:materiaIdSave / update final grades (bulk upsert)
GET/api/boletin/:estudianteIdDownload a student’s grade bulletin

Build docs developers (and LLMs) love