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 Final Grade Book (Finales) is where teachers, preceptors, and admins record end-of-year academic results for each enrolled student. It tracks the final exam score, an optional recuperatory score, and two status flags — libre and regular — all scoped to a specific academic year derived from the career configuration.

Grade Record Structure

Each record in the notas_finales table represents a single student’s outcome for one subject in one academic year:
interface NotaFinal {
  id: string;
  estudiante_id: string;
  materia_id: string;
  anio_academico: number;      // derived from the career's `anio` field
  nota: number | null;         // final exam score 1–10
  nota_recuperatorio: number | null; // recuperatory score 1–10
  libre: boolean;
  regular: boolean;
  cargada_por: string | null;  // user ID of who saved the record
  updated_at: string;
}
nota
number | null
Final exam score. Must be between 1 and 10 inclusive, or null if not yet recorded.
nota_recuperatorio
number | null
Recuperatory (make-up) exam score. Same range: 1–10 or null. When present, the boletin PDF uses this value as the effective grade.
libre
boolean
default:"false"
Mark the student as libre (did not meet attendance or coursework requirements). Cannot be true at the same time as regular.
regular
boolean
default:"false"
Mark the student as regular (met coursework requirements and may sit the final exam). Cannot be true at the same time as libre.
The API enforces a hard constraint: libre and regular cannot both be true for the same student in the same subject. Submitting both as true returns a 400 validation error: “Libre y Regular no pueden estar marcados a la vez”.

Academic Year (anio_academico)

The anio_academico value is never entered manually. The API derives it automatically from the anio field on the associated career (carreras.anio) when reading or writing grade records.
// lib/finales.ts — getAnioAcademicoMateria
async function getAnioAcademicoMateria(materiaId: string): Promise<number | null> {
  // Looks up materias → carreras(anio)
  // Returns the career's anio integer, e.g. 1, 2, or 3
}
This means that all subjects belonging to a career automatically share the same anio_academico, keeping grade records consistent without any manual configuration.

Reading the Grade Book

GET /api/finales/materia/:materiaId
Returns the current academic year and an array of students sorted alphabetically by last name, each with their current grades:
interface FinalesMateriaResponse {
  anio_academico: number;
  alumnos: AlumnoNotaFinal[];
}

interface AlumnoNotaFinal {
  estudiante_id: string;
  nombre: string;
  apellido: string;
  email: string;
  dni: string | null;
  nota: number | null;
  nota_recuperatorio: number | null;
  libre: boolean;
  regular: boolean;
}
Students with no existing notas_finales record are still included — they appear with nota: null, nota_recuperatorio: null, libre: false, regular: false.

Bulk Upsert: Saving Grades

Teachers and preceptors save the entire grade book in a single request. The endpoint uses an upsert strategy keyed on (estudiante_id, materia_id, anio_academico), so re-saving a student’s record safely overwrites the previous values.
PUT /api/finales/materia/:materiaId
{
  "notas": [
    {
      "estudiante_id": "uuid-student-1",
      "nota": 7,
      "nota_recuperatorio": null,
      "libre": false,
      "regular": true
    },
    {
      "estudiante_id": "uuid-student-2",
      "nota": 4,
      "nota_recuperatorio": 6,
      "libre": false,
      "regular": false
    },
    {
      "estudiante_id": "uuid-student-3",
      "nota": null,
      "libre": true,
      "regular": false
    }
  ]
}
Only students who are enrolled in the subject’s career cohort may have grades submitted. The API validates each estudiante_id against the enrolled list and returns 400 Alumno no inscripto en la comisión de esta materia for any unrecognised ID.

Permissions

1

Docente

Can read and write grades only for subjects where they are the assigned docente_id. The assertDocenteMateria helper enforces this by checking materias.docente_id === user.id.
2

Preceptor

Can read and write grades for any subject that belongs to a career (carrera_id IS NOT NULL). Standalone courses (materias without a career) are excluded.
3

Admin

Full access to read and write grades for any subject.
4

Estudiante

No access to the /api/finales endpoints. Students view their own grades exclusively through the Boletín PDF.

FinalesPanel: Teacher UI

In the classroom interface the FinalesPanel component renders an inline editable table. Each row represents one enrolled student; teachers type grades directly into the input cells and tick the Libre / Regular checkboxes, then click Guardar notas to fire the bulk PUT.
ColumnDescription
AlumnoApellido, Nombre — sorted alphabetically
LibreCheckbox — toggling it to true automatically unchecks Regular
RegularCheckbox — toggling it to true automatically unchecks Libre
FinalNumeric input, step 0.1, range 1–10
Recup.Numeric input for recuperatory score, step 0.1, range 1–10
The panel’s header shows the anio_academico (e.g. “1º año académico”) so teachers always know which cohort year they are editing.
Preceptors navigate directly to the Finales tab when opening a classroom. The rest of the tabs (Planificación, Actividades, Foro, Recursos) are hidden from their view.

How Grades Appear in the Boletín

When generating a grade bulletin PDF, the system reads notas_finales for a student across all subjects in their career. For each subject row, it uses nota_recuperatorio as the effective final grade when present — falling back to nota otherwise. The libre and regular flags are rendered as checkmarks in dedicated columns of the PDF table.

Build docs developers (and LLMs) love