DOCUMENTACIÓN TÉCNICA

EduShield
Cumplimiento MEP
Costa Rica

Módulo de cumplimiento del Reglamento de Evaluación de los Aprendizajes y de la Conducta

Implementaciónlib/compliance/packs/mep_cr
Versión2.0 — Phase 3 completo
Última actualización11 de mayo de 2026
ReglamentoDecreto Ejecutivo 45509-MEP
PublicaciónLa Gaceta 40 · 27 de febrero de 2026
VigenciaCurso lectivo 2026

1. Resumen ejecutivo

El módulo mep_cr de EduShield implementa el cumplimiento del Reglamento de Evaluación de los Aprendizajes y de la Conducta del Ministerio de Educación Pública de Costa Rica para centros educativos privados acreditados. El módulo permite a un centro:

  • Configurar sus datos institucionales oficiales (código MEP, dirección regional, circuito escolar, director).
  • Operar bajo los pesos legalmente fijos por componente de calificación según (nivel educativo, tipo de centro, asignatura).
  • Generar los tres reportes oficiales que el MEP requiere: boleta cumulativa por estudiante, reporte de matrícula y reporte anual de asistencia.
  • Registrar y calificar conducta según el REA 2026, con workflow de remediación socioeducativa.
  • Emitir Informes Descriptivos de Logro en preescolar (Art. 27°) en lugar de boleta numérica.
  • Cerrar el año con el Acta de Promoción, evaluando académica + conducta simultáneamente.
  • Llevar un calendario regulatorio del curso lectivo con eventos críticos del MEP.
  • Aplicar un workflow de aprobación con audit trail inmutable antes de entregar reportes al ministerio.

El módulo está diseñado como un compliance pack pluggable. La arquitectura permite agregar packs para otros países (México, Colombia, Panamá) sin tocar el código actual ni la base de datos existente, registrando un nuevo pack en el registro central.

1.1 Alcance de aplicación al curso

La activación del pack mep_cr en una sombrilla no convierte automáticamente los cursos existentes a REA 2026. La regla operativa es:

  • Cursos nuevos creados bajo una sombrilla MEP-CR: el formulario de creación ofrece un selector de nivel educativo + asignatura. Si el docente (o el staff que crea el curso base) lo activa, el curso nace gobernado por REA 2026 desde el primer día — los pesos por componente se resuelven automáticamente y son inmodificables.
  • Cursos existentes vacíos (sin assignments, quizzes, foros calificados ni notas registradas): pueden activarse a REA en cualquier momento desde su panel de configuración. Una vez con datos, esta acción se vuelve no reversible.
  • Cursos existentes con datos previos: permanecen indefinidamente en su esquema de evaluación original (categorías custom definidas por el docente). El sistemano fuerza la migración y no emite boletas oficiales contra ellos hasta que se cree un curso paralelo bajo REA. Esto evita pérdidas de información ya registrada y conflictos entre el cálculo legacy y el oficial.

Esta política reemplaza al flujo previo de "migración de cursos al modelo REA" que existía en versiones anteriores. La aplicación se decide al momento de crear el curso o cuando aún no tiene actividad, no como una conversión retroactiva de cursos en operación.

2. Contexto regulatorio

2.1 El reglamento vigente

El curso lectivo 2026 en Costa Rica se rige por el Decreto Ejecutivo 45509-MEP, que deroga el Decreto 40862-MEP de 2018. Los cambios estructurales más relevantes para el software:

  • Curso lectivo dividido en dos periodos, no tres trimestres (Art. 3°).
  • Componentes de la calificación pasaron de 6 a 8 (Art. 28°). Se incorporan: Portafolio de evidencias, Demostración de lo aprendido, e Instrumento de evaluación sumativa.
  • Pesos por componente legalmente fijos por matriz (nivel × tipo de centro × asignatura) (Arts. 40°-46°). No son configurables por el centro educativo ni por el docente.
  • Eliminación del arrastre de materias: un estudiante que reprueba una asignatura repite el año completo.
  • Mínimos de aprobación: 65 para I, II y III Ciclo de la EGB regular; 70 para III Ciclo en colegios bilingües y Diversificada (Art. 47°).

2.2 Por qué un gradebook genérico no alcanza

Bajo el REA 2026, permitir al docente o al admin definir pesos arbitrarios (tareas X%, exámenes Y%) no es legal para colegios privados acreditados que reportan al MEP. Si se configura "Tareas 30%" en una asignatura donde el reglamento dice "Tareas 10%", la boleta resultante es un documento ilegal.

EduShield separa dos planos:

  • Gradebook interno del docente (evaluationCategoryWeights, DEPRECATED): herramienta de gestión personal, sigue funcionando para sombrillas sin el pack activo.
  • Boleta oficial MEP (boletaEstudiante.ts): ignora los pesos del docente y aplica los del reglamento resueltos por resolverPesos(nivel, tipoCentro, asignatura).

2.3 Discrepancias documentadas en el reglamento

  • Art. 41.n (Colegios Académicos con Orientación Ambientalista, Inglés conversacional): pesos literales suman 105% (TC 45% + Pruebas 45% + Tareas 10% + Asistencia 5%). El módulo aplica interpretación correctiva (TC 40%) consistente con artículos análogos 41.l, 41.m y 41.o.
  • Art. 46.b (CONED virtual): el texto lista las mismas asignaturas que 46.a pero con pesos distintos. El módulo interpreta que 46.b se refiere a Educación Cívica, siguiendo el patrón del Art. 45.b.

Ambas discrepancias están documentadas en el campo _discrepanciaReglamento del archivorea-2026.json; la UI muestra warning específico cuando se cae en esos casos. La recomendación operativa es solicitar aclaración formal al MEP antes de uso productivo intensivo.

3. Decisiones arquitectónicas

3.1 Compliance packs pluggables

El módulo está construido como un sistema de packs. Core genérico:

lib/compliance/core/
├── types.ts        # CompliancePack, ReportDefinition, Role, ReportStatus
├── registry.ts     # registerPack, isPackActive, getActivePacks
├── permissions.ts  # requireAdminWithUmbrella, requireStaffWithUmbrella
└── bootstrap.ts    # registra packs al arrancar

Cada país-pack vive en su carpeta:

lib/compliance/packs/mep_cr/
├── index.ts                # declara el pack y re-exporta
├── weights/                # matriz REA 2026, resolver, catálogo, heurística
├── grading.ts              # pure functions de cálculo
├── validateBoletaREA.ts    # 3 capas de validación
├── autoSlots.ts            # placeholders por reglamento
├── validators/             # preconditions, calendario, escala, identificación
├── reports/                # generadores PDF/XLSX
├── conduct/                # Phase 2.5: compute + sync + applySuspension
├── actaPromocion/          # Phase 3: compute + generate
├── calendar/               # fechas verificadas + seedYear
├── storage.ts              # R2 con versionado y sha256
├── audit.ts                # logging a ActivityLog
├── mail.ts                 # templates de notificación
└── __tests__/              # 175 unit + 19 integration

La activación es por sombrilla, no global. UmbrellaSettings.compliancePackses String[] con los IDs activos. La UI nunca chequea country === "CR"; siempre consulta isPackActive(umbrellaAdminId, 'mep_cr').

3.2 La fuente de verdad es un JSON, no la base de datos

Los pesos del REA 2026 viven en weights/rea-2026.json, no en una tabla. Razones: son ley (no debe ser modificable por UI ni SQL); versionar por año lectivo es trivial con archivos (rea-2026.json, rea-2027.json); queda bajo git con review obligatorio; auditoría externa lo lee directo.

3.3 Pure functions para todo el cálculo

grading.ts, validateBoletaREA.ts, computeAsistenciaArt37,conduct/compute.ts, actaPromocion/compute.ts son funciones puras sin dependencia de DB. Testing trivial; reusabilidad para preview UI / generación de PDF / validación; auditabilidad (determinista y reproducible).

3.4 Inmutabilidad del audit trail

Cada acción crítica escribe row en ActivityLog con prefijo mep.:

  • mep.report.generated
  • mep.report.submitted_for_approval
  • mep.report.approved
  • mep.report.rejected
  • mep.report.marked_submitted
  • mep.settings.updated
  • mep.calendar.event.*

Logs inmutables y best-effort (si write falla, flow continúa).

4. Modelo de datos

4.1 Enums Prisma

enum MepNivelEducativo {
  PREESCOLAR
  I_CICLO  II_CICLO  III_CICLO
  DIVERSIFICADA
  EPJA_I_NIVEL  EPJA_II_NIVEL  EPJA_III_NIVEL
  VOCACIONAL
  CONED_DISTANCIA  CONED_VIRTUAL
}

enum MepComponenteOficial {
  TC // Trabajo cotidiano
  PE // Portafolio de evidencias
  TA // Tareas
  PR // Pruebas
  PY // Proyecto
  DA // Demostración de lo aprendido
  IS // Instrumento de evaluación sumativa
  AS // Asistencia
}

enum MepApoyoCurricular {
  NINGUNO  ACCESO  NO_SIGNIFICATIVO  SIGNIFICATIVO
}

// Phase 2.5
enum ConductFaltaTipo  { MUY_LEVE  LEVE  GRAVE  MUY_GRAVE  GRAVISIMA }
enum ConductStatus     { EN_CURSO  APROBADO  APLAZADO_EN_CONDUCTA  REPROBADO_EN_CONDUCTA }
enum ConductRemediationStatus { ASIGNADO  EN_PROCESO  APROBADA  REPROBADA }
enum IdlNivelLogro     { INICIANDO  DESARROLLANDO  CONSOLIDADO }
enum IdlArea           { MOTOR_GRUESO  MOTOR_FINO  COMUNICACION  COGNITIVO  SOCIOEMOCIONAL }

// Phase 3
enum ActaPromocionStatus {
  PROMOVIDO  APLAZADO_ACADEMICO  REPROBADO_ACADEMICO
  REPROBADO_EN_CONDUCTA  PROMOVIDO_CONDICIONADO
}

Nota legal sobre apoyo curricular: el Art. 28° párrafo final establece que el cálculo de la nota de un estudiante con apoyo curricular significativo usa los pesos del nivel donde está matriculado. Los pesos NO se ajustan por apoyo curricular. Lo que cambia es la Programación Educativa Individual y los instrumentos. El módulo guarda User.apoyoCurricularpara etiquetar la boleta pero no modifica los pesos.

4.2 Tablas regulatorias

  • ComplianceMepSettings (1:1 con sombrilla): datos institucionales, código MEP, dirección regional, director, imagen de firma escaneada, nota mínima de aprobación, toggle retiroAnticipadoComoAusencia.
  • ComplianceReportGeneration: 1 row por cada generación de reporte. Inmutable salvo por transiciones de estado. Unique constraint (umbrella, reportType, periodId, version).
  • ComplianceCalendarEvent: eventos del calendario regulatorio del año. Status pending/done/late.
  • ComplianceReportTemplate: plantillas custom subibles. Solo una activa por (umbrella, pack, reportType).
  • Phase 2.5: ConductRecord (per student × period), ConductRemediation, IdlReport + IdlAreaEvaluacion.
  • Phase 3: ActaPromocion (per student × year) cacheando resultado anual + breakdown JSON.

4.3 Campos agregados a tablas existentes

TablaCampoDescripción
CoursenivelEducativoEnum. Conduce el resolverPesos.
CourseasignaturaCodigoClave snake_case del catálogo.
CourseumbrellaAdminIdAnchor para queries por sombrilla.
CourseweightsPendingMigrationBool. Mientras true, no se emite boleta.
Assignment / QuizcomponenteOficialEnum MepComponenteOficial.
AssignmentfechaProgramadaFecha planeada (pruebas, proyectos).
AssignmentautoCreatedTrue para slots auto-generados.
SubmissioneximidoArt. 49°: autocalifica 100.
SubmissionreposicionPendienteArt. 36°: marca boleta como provisional.
SubmissionfechaReposicionFecha programada de reposición.
UserapoyoCurricularEnum MepApoyoCurricular. Default NINGUNO.
UsersignatureUrlImagen de firma para Reporte de Aula e IDL.
ConductReportmepSeverity, periodId, triggersSuspension, suspensionStart/EndDateCampos MEP opcionales aditivos.
AttendanceRecordjustified, justificationReason, justificationDocumentUrl, justificationSubmittedAt, lateMinutes, earlyDepartureMinutes, migrationNoteSchema compuesto para Art. 37°.

4.4 AttendanceRecord: schema compuesto

El enum legacy (PRESENT | ABSENT | LATE | EXCUSED) no distinguía justified vs unjustified ni duración de tardía, lo cual impide cálculo correcto del Art. 37°. Se migró a esquema compuesto:

model AttendanceRecord {
  status                  AttendanceStatus  // PRESENT | ABSENT | LATE | EARLY_DEPARTURE | SUSPENDED
  justified               Boolean           // aplica a ABSENT, LATE, EARLY_DEPARTURE
  justificationReason     String?
  justificationDocumentUrl String?
  justificationSubmittedAt DateTime?        // plazo 3 días hábiles (Art. 36°)
  lateMinutes             Int?              // cuando status === LATE
  earlyDepartureMinutes   Int?              // cuando status === EARLY_DEPARTURE
  migrationNote           String?           // marca de migración desde enum legacy
}

Path legacy status='EXCUSED' se interpreta como justified=true en el adapter de countAusenciasInjustificadas para no romper datos viejos. SUSPENDED es nuevo de Phase 2.5 — se auto-crea al registrar incidentes de conducta con suspensión.

5. Pesos oficiales: la fuente de verdad

5.1 Estructura del JSON

{
  "academicas_principales": {
    "tc": 0.45,
    "ta": 0.10,
    "pr": 0.40,
    "as": 0.05,
    "minPruebas": 2,
    "asignaturas": ["matematica", "espanol", "estudios_sociales", "ciencias", "lengua_extranjera"],
    "modalidadCentro": "regular_academico_o_tecnico_diurno_nocturno",
    "articulo": "41.a"
  }
}
  • tc/pe/ta/pr/py/da/is/as: pesos por componente (suman 1.0)
  • minPruebas: mínimo de items por componente (Arts. 32° y 41°)
  • asignaturas: claves del catálogo a las que aplica
  • modalidadCentro: restringe a tipos de centro
  • articulo: para trazabilidad legal en la boleta
  • tipo: 'diagnostico_y_formativo': caso especial sin nota numérica

5.2 Cobertura

El JSON cubre los Arts. 40°-46° en 77 variantes oficiales, todas con trazabilidad al artículo de origen. Las secciones cubren: I-II Ciclo EGB (8), III Ciclo EGB (17), Diversificada (23), EPJA (9), Vocacional (8), CONED Distancia (6), CONED Virtual (6).

5.3 El resolver

function resolverPesos(
  nivel: MepNivelEducativo,
  tipoCentro: TipoCentro,
  asignatura: string
): ResolverResult | ResolverError

Algoritmo: determina sección base según nivel → itera entries → verifica asignatura+modalidadCentro → retorna primer match. Falla cerrado: sin match, no se emite boleta. Previene que una telesecundaria intente emitir boleta de Literatura en Lengua Inglesa (solo aplica a bilingües).

5.4 Auxiliares

  • TIPOS_CENTRO: array literal de los 23 tipos válidos
  • TIPO_CENTRO_TO_MODALIDADES: mapping a cadenas del JSON
  • minimoAprobacion(nivel, opts): 65 default; 70 en III Ciclo bilingüe, Diversificada, EPJA III
  • decretoMetadata(): footer con referencia legal
  • weights/heuristicComponente.ts: sugiere componente desde título de Assignment/Quiz por keywords. Requiere confirmación humana.
  • weights/catalog.ts: lista asignaturas autorizadas por (nivel, tipoCentro) — el dropdown UI filtra para no mostrar opciones inválidas.

6. Cálculo de calificaciones

6.1 Estructura por capas

computeBoletaPromedio                 ← orquestador
  ├─ computeComponentFromItems(items) ← intra-componente
  └─ computeAsistenciaArt37(input)    ← caso especial
                  ↑
  resolverPesos(nivel, tipoCentro, asignatura)

6.2 Intra-componente

El reglamento solo regula pesos entre componentes. Los pesos dentro quedan a discreción del docente (evaluationWeight, default 1). Reglas:

  • Eximidos (Art. 49°): cuentan como 100 con su weight.
  • Reposición pendiente (Art. 36°): excluidos del cálculo. Marca la boleta como Provisional.
  • Sin grade sin marca: excluidos (pendientes de calificar).
  • weight = 0: válido (item diagnóstico que no aporta).

6.3 Combinación inter-componente

nota_final = Σ (pesoOficial[c] × promedio_componente[c])

Decisión arquitectónica clave: NO renormalización. Si el reglamento dice "Pruebas 40%" y no hay pruebas, el sistema NO redistribuye ese 40% entre los otros componentes. En cambio, el validador bloquea la generación de la boleta hasta que el componente esté completo.

6.4 Casos especiales

  • Eximir (Art. 49°): ≥90 en P1 + ≥90 en cada componente de P2 → autocalifica 100 en última prueba.
  • Reposición pendiente (Art. 36°): ausencia justificada con derecho a reposición → item excluido, boleta con marca PROVISIONAL.
  • Adecuación curricular significativa: usa pesos del nivel donde matriculado (Art. 28° párrafo final).
  • Estatus por periodo: solo Aprobado / Reprobado. "Aplazado" NO es banda de notas — es estatus de fin de año del Acta de Promoción.

7. Asistencia: el caso especial del Art. 37°

7.1 Tabla escalonada

% ausencias injustificadasValor componente AS
0% a < 10%5
10% a < 20%4
20% a < 30%3
30% a < 40%2
40% a < 50%1
50% o más0

Tardías: ≤10 min injustificada = 0.5 ausencia; >10 min = 1 ausencia. Caso preescolar: 4 tardías >10 min = 1 ausencia (Art. 37° párr. 5°).

7.2 Política institucional: retiroAnticipadoComoAusencia

El reglamento no es explícito sobre el retiro anticipado. El módulo lo trata como configurable por institución, con default false (interpretación pro-estudiante). El wizard inicial pregunta al admin; la decisión queda en ComplianceMepSettings.retiroAnticipadoComoAusenciay se documenta en audit log.

8. Validación pre-generación: tres capas

Todo el código de validación es puro; recibe datos cargados del loader y decide ok/blockers.

8.1 Capa 1 — validateBoletaCurso

Para un curso × estudiante × periodo. Chequea 10 cosas y retorna { ok, blockers[], warnings[], noMatriculado }. Blockers posibles:

  • NO_MATRICULADO_EN_PERIODO (N/A, no bloquea)
  • PERIODO_CERRADO
  • WEIGHTS_PENDING_MIGRATION
  • NIVEL_NO_CONFIGURADO
  • ASIGNATURA_NO_CONFIGURADA
  • RESOLVER_NO_MATCH
  • ASIGNATURA_DIAGNOSTICO_FORMATIVO
  • ASSIGNMENT_SIN_COMPONENTE
  • COMPONENTE_INCOMPLETO
  • ITEM_SIN_GRADE_SIN_MARCA

8.2 Capa 2 — validateBoletaEstudiante

Agrega todos los cursos del estudiante en el periodo. Strict mode: si cualquier curso tiene blockers, la boleta cumulativa NO se genera. Cursos con noMatriculado: true cuentan como "no aplica".

8.3 Capa 3 — validateBoletaGrupo

Para el coordinador que genera boletas de un grupo entero. Hace drill-down por docente para chasear al responsable específico en lugar de re-correr la generación a ciegas.

8.4 Pre-conditions de sesión

validators/preconditions.ts#validateCanGenerate corre antes de las capas:

  • Pack mep_cr activo en la sombrilla
  • ComplianceMepSettings completo (código MEP, dirección regional, director, etc.)
  • Periodo dentro de la ventana febrero-diciembre
  • Periodo no cerrado
  • Identificaciones válidas (cédula CR, DIMEX o pasaporte)

9. Generación de reportes

9.1 Tres reportes oficiales

ReporteFormatoInputsGeneradorAprobación
Boleta de calificacionesPDFCurso + periodoadmin/coordRequerida
Reporte de matrículaXLSXSombrilla completaadmin/coordRequerida
Reporte anual de asistenciaXLSX o PDFAño lectivoadmin/coordRequerida

9.2 boletaEstudiante.ts — boleta MEP oficial

Por estudiante, no por curso. Una página por estudiante con tabla de todas las asignaturas del periodo. Pesos resueltos por resolverPesos. Footer con referencias granulares por artículo. Marca PROVISIONAL si hay reposición pendiente. Estatus por asignatura: Aprobado / Reprobado contra mínimo del Art. 47°. Estudiante no matriculado en alguna asignatura → fila con — y no contribuye al promedio. Watermark legal del decreto. Hash sha256 del PDF.

Comportamiento defensivo: si el curso es preescolar, bifurca al generador IDL. Si hay blockers, lanza BoletaBlockersError con drill-down.

9.3 reporteAula.ts — reporte interno del docente

NO es la boleta MEP oficial. Per-curso, watermark diagonal "REPORTE INTERNO · NO ES BOLETA MEP OFICIAL", header "Reporte de Aula", footer rojo con disclaimer legal. Usa cálculo viejo por evaluationWeight individual, NO los pesos REA. No persiste enComplianceReportGeneration ni sube a R2. Incluye firma del docente cargada en su perfil si existe.

9.4 matricula.ts

XLSX con dos hojas: Estudiantes (deduplicado de toda la sombrilla con identificación, fecha nacimiento, provincia/cantón/distrito, contacto, encargado legal, cursos) y Centro (metadatos institucionales).

9.5 asistenciaAnual.ts

XLSX (hoja por curso + resumen) o PDF tabular. Reusa lib/studentAttendanceAggregation.js#tallyCourseAttendance — el mismo agregador del dashboard del estudiante. Recorta a [year-01-01, year-12-31]; todayKey = min(today, dec-31).

10. Workflow de aprobación y auditoría

10.1 Estados y transiciones

[generate]  → DRAFT
            ↓ (autor: submit-for-approval)
PENDING_APPROVAL
            ↓ (admin: approve)
APPROVED
            ↓ (cualquier staff: mark-submitted)
SUBMITTED

PENDING_APPROVAL
            ↓ (admin: reject con razón)
REJECTED
            (autor regenera → nuevo row con version+1)

10.2 Endpoints del workflow

  • POST /api/coordinator/compliance/mep/reports/generate/[type] → DRAFT + audit mep.report.generated
  • POST /api/coordinator/compliance/mep/reports/[id]/submit-for-approval → PENDING + email al admin + audit
  • POST /api/admin/compliance/mep/approvals/[id]/approve → APPROVED + email al autor + audit
  • POST /api/admin/compliance/mep/approvals/[id]/reject → REJECTED con razón + email + audit
  • POST /api/coordinator/compliance/mep/reports/[id]/mark-submitted → SUBMITTED + cierra ComplianceCalendarEvent + audit

10.3 Notificaciones

Email vía mail.ts + Notification interna vía sistema general del proyecto. Email falla silencioso si SMTP no está configurado.

11. Permisos y multi-tenancy

11.1 Matriz de permisos

Permisoadmincoorddocenteestudiante
canConfigureRegion / EditMepSettings / ApproveReport / RejectReport / ManageCalendar
canViewMepDashboard / GenerateOfficialReport / MarkSubmitted / ViewReportHistory
canExportTeacherBoleta (reporte de aula)✓ (titular)
Registrar incidente conducta MEP✓ (curso)
Llenar IDL preescolar✓ (titular)
Asignar / avanzar remediación
Emitir Acta de Promoción
Ver propia nota de conducta + propia boleta

11.2 Resolución de sombrilla

Cada endpoint resuelve el primaryAdminId de la sombrilla del usuario y filtra todas las queries por ese ID. Helpers: requireAdminWithUmbrella, requireStaffWithUmbrella, requireRoleWithUmbrella(roles). Coord y docente caen bajo el admin titular vía lib/supportUmbrella.js#getSupportAdminId.

11.3 Testing de seguridad

__tests__/security/cross-umbrella-leak.integration.test.ts verifica explícitamente que un docente/coord de Sombrilla A no puede leer recursos de Sombrilla B vía API directa con su JWT. Cubre 5 endpoints leak-prone con tests reales contra DB y autenticación HTTP.

12. Almacenamiento, integridad y versionado

12.1 Estructura de claves en R2

compliance/{umbrellaAdminId}/mep_cr/{reportType}/{periodId|none}/v{version}-{timestamp}.{ext}

Ejemplo: compliance/admin_abc123/mep_cr/boleta/period_2026_I/v3-1715450000.pdf

12.2 Versionado

storage.ts#nextReportVersion hace MAX(version) + 1 por (umbrella, reportType, periodId). Unique constraint en DB previene race conditions.

12.3 Integridad

Cada archivo se hashea con SHA-256 y se guarda en ComplianceReportGeneration.fileHash. El objeto en R2 lleva metadata {umbrella, pack, report, period, version, hash} para verificación post-hoc.

12.4 Acceso

fileUrl apunta a /api/files/view?key=..., un proxy autenticado que valida sesión y firma URL pre-signed de R2 al vuelo. Los reportes oficiales nunca son accesibles directamente desde R2.

13. Calendario regulatorio

13.1 Defaults verificados 2026

EventoFechasStatus
Capacitación docente9-20 febreropending → done
Inicio del curso lectivo23 febreropending → done
Entrega notas I periodo3 juliopending → done/late
Vacaciones medio periodo6-17 julioinformativo
Entrega notas II periodo9 diciembrepending → done/late
Cierre del curso lectivo9 diciembreinformativo
Graduaciones10-11 diciembreinformativo

El curso lectivo está dividido en 2 periodos (Art. 3°), no 3 trimestres como en el reglamento anterior.

13.2 Seed idempotente

calendar/seedYear.ts siembra eventos por eventName; ediciones del admin se preservan. Años no incluidos en KNOWN_GOOD_YEARS se extrapolan con prefijo "EXTRAPOLADO — REVISAR".

13.3 Estado derivado

Cron /api/cron/compliance/mep/mark-late (Bearer CRON_SECRET, fail-closed) corre nightly. Lazy update también en lectura del dashboard, así el admin ve el estado correcto aunque el cron no corra.

14. Migración de cursos legacy y auto-slots

14.1 Pantalla asistida

/admin/compliance/mep/migrate-courses lista cursos con weightsPendingMigration: true. Detail view permite asignar nivel + asignatura + clasificar Assignments/Quizzes con sugerencia heurística pre-cargada.

14.2 Auto-slots

Una vez configurado el curso, autoSlots.ts crea placeholders alineados al reglamento. TC (1 slot), PR (N = minPruebas), PY (1 si peso>0), PE (solo CTP dual), IS (solo CONED virtual). TA, DA, AS no se auto-crean. Idempotencia: matching por (componenteOficial, title, autoCreated).

15. Phase 2.5 — Conducta MEP

El REA 2026 regula la calificación de conducta como dimensión separada de las asignaturas, pero igual de importante para la promoción anual. Phase 2.5 implementa el ciclo completo.

15.1 Modelo de datos

Reusa ConductReport existente (con incidentType/severity libre + firma del estudiante + evidence + logs) y le agrega 5 columnas opcionales:

  • mepSeverity ConductFaltaTipo? — MUY_LEVE / LEVE / GRAVE / MUY_GRAVE / GRAVISIMA
  • periodId String? — periodo lectivo al que cuenta
  • triggersSuspension Boolean — gatilla suspensión 30 días
  • suspensionStartDate / suspensionEndDate DateTime?

Más dos modelos nuevos:

  • ConductRecord (per student × period): cacheando notaFinal, totalRebajado, counts por severidad, status, FK opcional a remediation. Unique (studentId, periodId).
  • ConductRemediation: track socioeducativo con workflow ASIGNADO → EN_PROCESO → APROBADA / REPROBADA.

15.2 Rebajos por severidad (fijos por reglamento)

SeveridadRebajoDescripción
MUY_LEVE−5Conductas menores que no afectan el clima de aula
LEVE−10Conductas inadecuadas reiteradas o disruptivas leves
GRAVE−20Daño material, ofensas, irrespeto significativo
MUY_GRAVE−30Agresión, plagio mayor, acoso
GRAVISIMA−50Faltas que pueden gatillar suspensión 30 días

El cálculo arranca en 100 y resta. Piso 0 (no negativo). Mínimo de aprobación: 65 (EGB) / 70 (Diversificada).

15.3 Cálculo (función pura)

recomputeConductRecord({
  incidents,           // Array de incidents del periodo con mepSeverity
  notaMinima,          // 65 o 70 según nivel
  periodIsClosed,      // bool
  remediationStatus,   // opcional
}) → { notaFinal, totalRebajado, counts, status }

Determinación del status:

  • EN_CURSO mientras el periodo está abierto.
  • APROBADO si periodo cerrado y nota ≥ mínimo, o si remediation APROBADA.
  • APLAZADO_EN_CONDUCTA si periodo cerrado y nota < mínimo, sin remediation resuelta.
  • REPROBADO_EN_CONDUCTA si remediation REPROBADA. Implica repetir año por reglamento, aunque la académica esté aprobada.

15.4 Suspensión 30 días y propagación a asistencia

Cuando se crea un incident con triggersSuspension=true y un rango, el sistema llamaapplySuspensionToAttendance:

  • Para cada AttendanceSession del estudiante en el rango, crea o actualiza el AttendanceRecord con status='SUSPENDED' + justified=true.
  • SUSPENDED se trata como ausencia justificada en el cómputo del Art. 37° — no penaliza la nota de AS — pero queda auditable en el registro.
  • Si el docente ya marcó manualmente la sesión con otro status explícito (ABSENT, LATE, EXCUSED, EARLY_DEPARTURE), el sistema respeta esa marca y no sobrescribe.

15.5 Workflow de remediación

Cuando el estudiante queda APLAZADO_EN_CONDUCTA, la coord puede asignar un track socioeducativo desde /coordinator/compliance/mep/conduct:

  1. POST con descripción del trabajo + vencimiento opcional → ConductRemediation status=ASIGNADO.
  2. PATCH status=EN_PROCESO mientras el estudiante trabaja (opcional).
  3. PATCH status=APROBADA → ConductRecord vuelve a APROBADO.
  4. PATCH status=REPROBADA → ConductRecord queda REPROBADO_EN_CONDUCTA.

Transiciones inválidas (volver atrás desde APROBADA/REPROBADA, etc.) son rechazadas por el endpoint con 400.

15.6 Endpoints

  • POST /api/courses/[id]/conduct — crea incident; si campos MEP están llenos, sync ConductRecord + propaga suspensión.
  • GET /api/courses/[id]/conduct?aggregate=1&studentId=&periodId= — retorna record + incidents.
  • DELETE /api/courses/[id]/conduct/[reportId] — borra incident y resync.
  • GET /api/coordinator/compliance/mep/conduct-summary?periodId= — agregado para tablero.
  • POST /api/coordinator/compliance/mep/remediations — asignar.
  • PATCH /api/coordinator/compliance/mep/remediations/[id] — avanzar estado.
  • GET /api/student/conduct?periodId= — vista del propio estudiante.

15.7 UI

  • Docente: modal de crear reporte de conducta gana sección "Es incidente regulatorio MEP" (oculta si pack inactivo). Badge "MEP" y "Suspensión" en lista de reportes.
  • Coordinador / admin: tablero en /coordinator/compliance/mep/conduct con counts por status, tabla de estudiantes con acciones inline, top 10 incidentes recientes.
  • Admin dashboard: widget de alertas con counts agregados de periodos abiertos.
  • Estudiante: vista propia en /student/conduct con su nota, desglose por severidad, lista de incidentes, panel de remediación si aplica.

16. Phase 2.5 — IDL Preescolar (Art. 27°)

Educación Preescolar no usa boleta numérica. El reporte oficial es cualitativo: Informe Descriptivo de Logro (IDL).

16.1 Modelo

  • IdlReport (unique studentId × periodId): status DRAFT / COMPLETO / ENTREGADO + recomendaciones libres + relación a evaluaciones por área.
  • IdlAreaEvaluacion (unique reportId × area): nivelLogro + observación del docente por cada área.

16.2 Áreas y niveles

5 áreas estándar REA cubriendo Materno-Interactivo y Transición:

  • MOTOR_GRUESO — caminar, correr, saltar, equilibrio
  • MOTOR_FINO — pinza, recortar, encajar, garabateo
  • COMUNICACION — vocabulario, expresión, comprensión, escucha
  • COGNITIVO — atención, memoria, resolución de problemas, conceptos
  • SOCIOEMOCIONAL — regulación, convivencia, autonomía, identidad

3 niveles de logro: INICIANDO / DESARROLLANDO / CONSOLIDADO.

16.3 Authoring

El docente del aula llena el IDL de cada estudiante desde /teacher/courses/[id]/idl?periodId=. La página muestra la lista de estudiantes con su status y un drawer lateral con las 5 cards (una por área) + textarea de recomendaciones al hogar + 3 botones (Cerrar / Guardar borrador / Marcar completo). El upsert es atómico: si modificás solo MOTOR_FINO, las demás áreas se preservan.

16.4 Generación PDF

El endpoint POST /api/coordinator/compliance/mep/reports/generate/boleta bifurca automáticamente cuando el curso es PREESCOLAR y llama a generateIdlGrupoCurso en lugar del generador de boleta numérica. Misma API pública; la decisión interna es transparente al consumidor.

El PDF incluye header MEP institucional, una página por estudiante con tabla de las 5 áreas (nivel coloreado por status + observación), bloque de recomendaciones, cita explícita al Art. 27°. Si el estudiante no tiene IDL llenado, página con bloque ámbar "Sin contenido — el docente todavía no completó la evaluación".

16.5 Endpoint

  • GET /api/teacher/courses/[courseId]/idl/[studentId]?periodId= — retorna IdlReport actual.
  • PUT /api/teacher/courses/[courseId]/idl/[studentId]?periodId= — upsert atómico de report + evaluaciones por área en una transacción.

17. Phase 2.5 — Firma del docente

Cada docente puede cargar una imagen de su firma escaneada/digital desde su perfil. La firma se inserta automáticamente en el footer del Reporte de Aula interno y del IDL preescolar generado para sus cursos.

17.1 Modelo

Campo aditivo en User: signatureUrl String?. Nullable; centros sin docentes que carguen firma no notan nada.

17.2 Endpoint de upload

POST /api/teacher/upload-signature: formidable, máx 1MB, solo PNG/JPEG. Sube a R2 con key signatures/{userId}/{uuid}.{ext}. Retorna URL relativa /api/files/view?key=... servida vía proxy auth.

17.3 Render en PDF

Al generar el Reporte de Aula o IDL, el generador hace fetch de la URL, convierte la imagen a dataURL base64 y llama jsPDF.addImage en posición fija sobre la línea de firma del footer. Best-effort: si la imagen no se puede cargar, el PDF se emite sin firma con texto "Sin imagen de firma".

Aclaración legal importante: esta imagen NO constituye Firma Digital del BCCR (la única firma electrónica con valor jurídico pleno en Costa Rica). Es solo una imagen visual para identificar al docente firmante en documentos internos. La UI rotula el campo como "Imagen de firma" para no inducir a confusión.

18. Phase 3 — Acta de Promoción anual

Documento final del año lectivo que decide si cada estudiante es promovido al siguiente nivel. Evalúa simultáneamente académica + conducta + asistencia. La conducta puede bloquear la promoción aunque la académica esté aprobada.

18.1 Modelo

  • ActaPromocion (unique studentId × year): cachea status, counts, conductaStatus, conductaNotaFinal, breakdown JSON detallado por asignatura. Inmutable salvo regeneración (upsert).

18.2 Lógica de promoción (función pura)

computeActaPromocion({
  asignaturas,         // resultados anuales por curso
  conductRecords,      // ConductRecord de todos los periodos del año
  esPreescolar?,       // true si todos los cursos son nivel PREESCOLAR
}) → { status, asignaturasAprobadas, asignaturasReprobadas,
       reprobadasLabels, conductaStatus, conductaNotaFinal, motivo }

Reglas:

  1. Conducta REPROBADO_EN_CONDUCTA en cualquier periodo del año → status REPROBADO_EN_CONDUCTA (repite año). La conducta gana sobre académica. El sistema toma el peor status del año, no el último.
  2. Si conducta ok:
    • 0 asignaturas reprobadas → PROMOVIDO
    • 1-3 reprobadas → APLAZADO_ACADEMICO (convocatoria de ampliación)
    • >3 reprobadas → REPROBADO_ACADEMICO (repite año)
  3. Preescolar → PROMOVIDO_CONDICIONADO (coord valida por criterio de asistencia/avance, Art. 50.a).

18.3 Generador

generateActaPromocionSombrilla({umbrellaAdminId, year, studentIds?, persist, emittedById}) calcula breakdown por estudiante, llama compute, upsert ActaPromocion y renderiza PDF con una página por estudiante.

Limitación conocida del cálculo: hoy la nota anual por asignatura se calcula como promedio aritmético simple entre periodos del año, no aplicando los pesos REA por periodo. El PDF lo documenta en footer. Para emisión oficial al MEP, la coordinación debe verificar el breakdown contra las boletas oficiales emitidas. Mejora pendiente: cambiar el promedio simple a promedio de las notas finales por periodo calculadas con pesos REA (que ya existen en boletaEstudiante).

18.4 UI

En /coordinator/compliance/mep/actas: input de año, botones Emitir/Regenerar y Descargar PDF, 5 count cards por status, tabla de estudiantes con nota+conducta+resultado. Idempotente: regenerar para el mismo año no duplica filas.

18.5 Endpoints

  • GET /api/coordinator/compliance/mep/actas-promocion?year= — lista actas + counts.
  • POST /api/coordinator/compliance/mep/actas-promocion body {year, studentIds?, format?}. Si format=pdf stream del PDF; sino JSON.

18.6 Art. 50° — Aprobación del año (detalle regulatorio)

El Art. 50° del REA 2026 regula la condición final del estudiante al cierre del curso lectivo. Es la norma que determina si una persona estudiante es promovida al siguiente nivel, queda aplazada con derecho a pruebas de ampliación, o repite el año. El módulo lo implementa en actaPromocion/compute.ts y cada inciso se mapea explícitamente a una rama de computeActaPromocion.

18.6.1 Condiciones según ciclo

NivelPromovido si…Aplazado si…Reprobado si…
I y II Ciclo EGBAprueba todas las asignaturas (mínimo 65) y conducta APROBADO.Reprueba 1 a 3 asignaturas con conducta APROBADO → convocatoria de ampliación.Reprueba más de 3 asignaturas, o conducta REPROBADO_EN_CONDUCTA en cualquier periodo.
III Ciclo EGB regularAprueba todas las asignaturas (mínimo 65) y conducta APROBADO.Reprueba 1 a 3 asignaturas con conducta APROBADO.Reprueba más de 3, o conducta REPROBADO_EN_CONDUCTA.
III Ciclo bilingüe / DiversificadaAprueba todas (mínimo 70) y conducta APROBADO.Reprueba 1 a 3, conducta APROBADO.Reprueba más de 3, o conducta REPROBADO_EN_CONDUCTA.
Preescolar (Art. 50.a)Asistencia ≥ 80% del curso lectivo y sin riesgo de exclusión disciplinaria.Asistencia < 80% sin justificación válida.

18.6.2 La conducta bloquea la promoción

El REA es explícito: REPROBADO_EN_CONDUCTA en cualquier periodo del año implica repetición, aunque la persona estudiante haya aprobado todas las asignaturas. No hay compensación entre conducta y académica. computeActaPromocion evalúa primero la conducta agregada del año (peorstatus entre periodos, no el último): si el peor es REPROBADO_EN_CONDUCTA, el status final lo es también, cortocircuitando el resto del cálculo.

Un estudiante con APLAZADO_EN_CONDUCTA en cualquier periodo puede ser promovido si la remediación (ConductRemediation) cierra como APROBADA y el ConductRecord recalcula a APROBADO antes de emitir el Acta. Si cierra como REPROBADA, escala automáticamente a REPROBADO_EN_CONDUCTA.

18.6.3 Aplazado y convocatoria de ampliación

El status APLAZADO_ACADEMICO no es definitivo: la persona estudiante tiene derecho a pruebas de ampliación por cada asignatura reprobada en el calendario que define el MEP cada año. Aprobar las ampliaciones cambia el resultado a PROMOVIDO; reprobar al menos una mantiene el aplazado o lo convierte en reprobado según política institucional.

Implementación en el módulo (Phase 3.1): el modelo ConvocatoriaAmpliacion registra una fila por (estudiante × año × asignaturaCodigo) con la convocatoria + el resultado (nota + aprobada). Desde /coordinator/compliance/mep/actas el coordinador gestiona las convocatorias tocando "Ampliaciones" en cada fila APLAZADO_ACADEMICO: ve las asignaturas reprobadas del breakdown del Acta y puede convocar, registrar nota, marcar aprobada o reprobada. Cuando todas están resueltas, activá el toggle "Re-emisión con ampliaciones" y volvé a Emitir para que el cálculo aplique: si todas las ampliaciones aprueban, el status final pasa a PROMOVIDO.

El cómputo respeta la regla del Art. 50°: la conducta REPROBADA bloquea la promoción aunque todas las ampliaciones académicas aprueben. Audit trail completo en ActivityLog con los tipos mep.ampliacion.created, mep.ampliacion.resolved,mep.ampliacion.deleted. Cross-umbrella isolation: una sombrilla solo ve y modifica sus propias ampliaciones (filtro por umbrellaAdminId).

18.6.4 Preescolar (Art. 50.a)

Para Educación Preescolar no aplica el cálculo numérico: la promoción depende de la asistencia mínima del 80% al curso lectivo, sumada a un Informe Descriptivo de Logro (IDL, Art. 27°) que muestre avance. Si todos los cursos del estudiante son nivelEducativo='PREESCOLAR',computeActaPromocion retorna PROMOVIDO_CONDICIONADO y la coordinación valida manualmente contra el % de asistencia anual.

18.6.5 Casos especiales no implementados

  • Adecuación significativa (Art. 28° párr. final): el cálculo del promedio sigue usando los pesos del nivel ordinario, no se ajustan. El módulo lo respeta; el seguimiento individualizado lo hace el PEI fuera del módulo.
  • Traslado entre centros mid-year: la persona estudiante puede tener notas parciales de otro centro. El módulo no las importa automáticamente; el coordinador debe registrar manualmente las submissions previas antes de emitir el Acta.
  • Estudiantes con disposición transitoria 2025→2026: arrastres de materias previos al REA 2026 no aplican; cada centro maneja esos casos según oficio individual del MEP.

19. Lo que el módulo NO hace (scope explícito)

19.1 Fuera de scope

  • Certificados de conclusión: 6° grado, 9° año, bachillerato.
  • Pruebas Nacionales Estandarizadas (PNE): integración para 6° y bachillerato.
  • Boleta de conducta separada: si el centro emite la conducta como documento aparte. El módulo la incluye dentro de la boleta cumulativa.
  • Entrega automática al portal del MEP: el centro sigue presentando los documentos por los canales oficiales del Ministerio.
  • Vista del encargado legal: requiere modelar primero un rol guardian — decisión de producto fuera de este módulo.

19.2 Decisiones explícitas

  • El admin NO puede modificar pesos de componentes (legalmente fijos).
  • El admin NO puede generar reportes oficiales en periodos fuera de febrero-diciembre.
  • El módulo no modifica el grading legacy (gradebook/index.js sigue con evaluationWeight para sombrillas sin pack activo).
  • El módulo no reemplaza el registro diario de asistencia. AttendanceRecord se sigue marcando como siempre.

20. Estrategia de testing

20.1 Cobertura

175 unit tests + 19 integration tests = 194 verdes:

  • grading.test.ts — matemática pura del cálculo
  • validateBoletaREA.test.ts — 3 capas + edge cases
  • autoSlots.test.ts — idempotencia del bootstrap
  • weights/__tests__/ — invariante: cada entry JSON suma 1.0; catálogo; heurística
  • validators/__tests__/ — calendario, escala, identificación
  • conduct/__tests__/compute.test.ts — 13 tests del cálculo de Conducta
  • actaPromocion/__tests__/compute.test.ts — 9 tests del Acta
  • e2e.integration.test.ts — flujo completo Phase 1-2 contra DB+R2+SMTP reales
  • conduct-mep.integration.test.ts — 8 tests flujo Conducta end-to-end
  • idl-preescolar.integration.test.ts — 6 tests upsert IDL + workflow status
  • acta-promocion.integration.test.ts — 5 tests emisión + idempotencia + PDF stream
  • cross-umbrella-leak.integration.test.ts — 6 tests aislamiento por sombrilla

20.2 Verificación de datos del MEP

Pesos del JSON y fechas del calendario fueron verificados contra: PDF oficial del Decreto 45509-MEP (verificación visual página por página, 11 mayo 2026); circular del calendario escolar 2026; sistema calendario.mep.go.cr. Errores de transcripción se corrigieron; discrepancias del reglamento se documentaron.

21. Deuda técnica conocida

21.1 Convivencia de dos paths

LugarLegacyNuevoFecha objetivo de retiro
AttendanceRecordstatus='EXCUSED'justified=truePendiente migracion de datos
ComplianceMepSettingsevaluationCategoryWeightsPesos resueltos por reglamentoRETIRADO

21.2 Catálogo de asignaturas no oficial

El MEP no publica un catálogo centralizado con códigos normalizados; las claves snake_case fueron derivadas del texto literal de los Arts. 40°-46°. Cubre >95% de centros. Trabajo futuro opcional: scraping de los programas de estudio publicados en mep.go.cr.

21.3 Plantillas almacenadas pero no consumidas

ComplianceReportTemplate permite subir plantillas custom, pero los generadores actuales usan templates hardcoded. La feature de overlay queda como trabajo futuro.

21.4 Acta — cálculo de nota anual

Hoy promedio aritmético simple entre periodos. Lo correcto regulatoriamente es promediar las notas finales por periodo (que ya usan pesos REA en boletaEstudiante). Mejora pendiente; el PDF documenta el disclaimer.

21.5 Discrepancias del reglamento sin resolver

Los Arts. 41.n y 46.b tienen errores en el texto del decreto (documentados en 2.3). El módulo aplica interpretaciones razonables; la confirmación formal del MEP queda pendiente.

22. Extensión: agregar un pack de otro país

La arquitectura está pensada para que un pack adicional (ej. sep_mx para México, min_co para Colombia) se agregue sin tocar el código existente.

lib/compliance/packs/sep_mx/
├── index.ts                # declara el pack
├── weights/                # matriz del reglamento mexicano
├── grading.ts              # cálculo (puede ser idéntico a mep_cr o distinto)
├── validateBoleta.ts       # validación de blockers
├── validators/             # preconditions específicos de México
├── reports/                # generadores PDF/XLSX para SEP
├── calendar/               # ciclo escolar mexicano
├── storage.ts              # reusa R2 con keys distintas
├── audit.ts
├── mail.ts
└── __tests__/

El bootstrap se extiende y la sombrilla acepta múltiples packs simultáneos en compliancePacks: String[]. Lo que se comparte entre packs: core/types, registry, permissions, R2, ActivityLog, /api/files/view, modelos genéricos (AcademicPeriod, Course, Assignment, Quiz, Submission, AttendanceRecord, User).

Apéndice A: Referencias regulatorias

  • Decreto Ejecutivo 45509-MEP — REA 2026. La Gaceta 40, 27 de febrero de 2026.
  • Decreto Ejecutivo 40862-MEP — Reglamento anterior (2018), derogado.
  • Calendario Escolar 2026 — mep.go.cr/educatico/calendario-escolar-2026
ArtículoTemaImplementación
Art. 3°División del curso lectivo en 2 periodoscalendar/seedYear.ts
Art. 26°Escala de calificación y redondeograding.ts
Art. 27°Evaluación preescolar (IDL)reports/idlPreescolar.ts
Art. 28°8 componentes de la calificaciónMepComponenteOficial enum
Art. 36°Justificación y derecho a reposiciónSubmission.reposicionPendiente
Art. 37°Tabla escalonada de asistenciacomputeAsistenciaArt37
Arts. 40°-46°Pesos por nivel/asignatura/modalidadweights/rea-2026.json
Art. 47°Mínimos de aprobaciónminimoAprobacion()
Art. 48°Ponderación anual 50%-50%grading.ts
Art. 49°Eximir de última pruebaSubmission.eximido
Art. 50°Aprobación del año (requiere conducta) + pruebas de ampliaciónactaPromocion/compute.ts + ConvocatoriaAmpliacion

Apéndice B: Glosario

B.1 Términos regulatorios (REA / MEP)

MEP
Ministerio de Educación Pública de Costa Rica.
REA 2026
Reglamento de Evaluación de los Aprendizajes y de la Conducta, vigente desde 2026 (Decreto 45509-MEP).
EGB
Educación General Básica (I, II y III Ciclo).
Diversificada
Los últimos dos o tres años de secundaria según modalidad.
EPJA
Educación para Personas Jóvenes y Adultas.
CONED
Colegio Nacional de Educación a Distancia.
IPEC
Instituto Profesional de Educación Comunitaria.
CINDEA
Centro Integrado de Educación de Adultos.
DIMEX
Documento de Identidad Migratoria para Extranjeros (12 dígitos en CR).
PEI
Programación Educativa Individual — plan individualizado para estudiantes con adecuaciones significativas.
Adecuación significativa
Modificación curricular para estudiantes con necesidades educativas especiales. Bajo Art. 28° párr. final, NO se ajustan los pesos de los componentes de la calificación; el seguimiento es vía PEI.
Apoyo curricular
Categoría del estudiante: NINGUNO, ACCESO, NO_SIGNIFICATIVO, SIGNIFICATIVO. Aparece en la boleta y permite trazar atención individualizada.
Tipo de centro
Modalidad institucional registrada en ComplianceMepSettings.tipoCentro: REGULAR_PUBLICO, REGULAR_PRIVADO, BILINGUE, TECNICO_PROFESIONAL, CONSERVATORIO, etc. Determina junto con nivel y asignatura qué pesos legales aplican.
Pruebas de ampliación
Convocatoria oficial post-cierre del año para que estudiantes APLAZADO_ACADEMICO recuperen las asignaturas reprobadas. Calendario definido por el MEP. Implementadas en el módulo vía ConvocatoriaAmpliacion + toggle "Re-emisión con ampliaciones" desde el panel de Actas.
Reposición pendiente
Item de evaluación que la persona estudiante no rindió por ausencia justificada y queda agendado para reposición (Art. 36°). Excluye al item del cálculo; la boleta se marca como Provisional hasta que se reponga.
Eximir
Beneficio del Art. 49°: estudiante con ≥90 en P1 y ≥90 en cada componente de P2 se exime de la última prueba del último periodo. Se autocalifica 100. Requiere mínimo 2 pruebas por periodo en la asignatura.
Aplazado
Estatus de fin de año de quien queda debiendo asignaturas pero tiene derecho a pruebas de ampliación. NO es banda de notas; es estatus binario al cierre del año (Art. 50°).
Arrastre de materias
Práctica histórica de promover al siguiente nivel con materias pendientes. Eliminado por el REA 2026: reprobar implica repetir el año completo (con disposición transitoria para casos 2025 hacia atrás).

B.2 Componentes de la calificación (Art. 28° y 40°-46°)

TC — Trabajo Cotidiano
Observación y producción diaria del estudiante en clase. Es el componente de mayor peso en la mayoría de asignaturas (Art. 29°).
PE — Portafolio de Evidencias
Compilación de trabajos del estudiante que documentan su proceso (Art. 30°). Nuevo en REA 2026.
TA — Tareas
Asignaciones para hacer fuera del aula (Art. 31°).
PR — Pruebas
Evaluaciones formales escritas (Art. 32°). Hay un mínimo legal por periodo según asignatura (minPruebas).
PY — Proyecto
Trabajo extenso de investigación o producción (Art. 33°).
DA — Demostración de lo Aprendido
Evidencia práctica de logro (Art. 34°). Nuevo en REA 2026.
IS — Instrumento de Evaluación Sumativa
Evaluación final integradora (Art. 35°). Nuevo en REA 2026.
AS — Asistencia
Componente derivado automáticamente del registro de asistencia con la tabla escalonada del Art. 37°. NO se construye con items; se calcula a partir de ausencias injustificadas en el periodo.
Diagnóstico y formativo
Categoría de asignaturas (Cultura Indígena, Paz y Convivencia, Orientación) sin pesos numéricos. Se reportan vía Informe Descriptivo de Logro, no con boleta numérica.

B.3 Documentos oficiales del módulo

Boleta cumulativa
Documento legal por estudiante, por periodo, con la tabla de TODAS sus asignaturas + conducta. Generada por boletaEstudiante.ts. Es lo que el centro entrega al encargado y al MEP.
Reporte de aula (interno)
Documento por curso y docente con las notas del grupo. Uso interno del docente, NO es boleta oficial.
IDL
Informe Descriptivo de Logro (preescolar, Art. 27°). Reporte cualitativo con 5 áreas del desarrollo. Reemplaza la boleta numérica para PREESCOLAR.
Acta de Promoción
Documento anual con la condición final de cada estudiante (PROMOVIDO, APLAZADO_ACADEMICO, REPROBADO_ACADEMICO, REPROBADO_EN_CONDUCTA, PROMOVIDO_CONDICIONADO). Único por estudiante × año.
Reporte de matrícula
Listado oficial de estudiantes matriculados con sus datos de identificación, requerido por el MEP al inicio del año.
Reporte anual de asistencia
Listado oficial de asistencia agregada por estudiante, requerido al cierre del año.

B.4 Términos del producto EduShield

Sombrilla
Agrupación administrativa de usuarios. Un admin titular es dueño de una sombrilla; coordinadores y docentes operan bajo ella. Es el límite del aislamiento multi-tenant: todo dato del módulo se filtra por umbrellaAdminId.
Compliance pack
Módulo opcional pluggable que implementa el cumplimiento de un país. mep_cr es el pack para Costa Rica. La sombrilla activa packs en UmbrellaSettings.compliancePacks.
Coordinador
Rol institucional con permisos para generar reportes, gestionar conducta y emitir actas. Opera bajo la sombrilla. Distinto de admin (admin es el titular del centro).
ConductRecord
Agregado por estudiante × periodo de incidentes MEP. Contiene notaFinal (0-100), totalRebajado, counts por severidad y status (EN_CURSO / APROBADO / APLAZADO_EN_CONDUCTA / REPROBADO_EN_CONDUCTA).
ConductReport
Incidente individual de conducta registrado contra un estudiante. Cuando lleva mepSeverity entra al cálculo regulatorio del ConductRecord.
ConductRemediation
Workflow de acción socioeducativa para estudiantes con APLAZADO_EN_CONDUCTA. Estados: ASIGNADO → EN_PROCESO → APROBADA / REPROBADA. Su resolución re-evalúa el ConductRecord.
ActivityLog
Audit trail inmutable. Toda acción del módulo persiste con type='mep.*' para trazabilidad regulatoria.
Boleta provisional
Boleta emitida con al menos un item en reposición pendiente. Marcada visualmente y exige regeneración cuando se aplique la reposición.
Periodo cerrado
AcademicPeriod.isClosed=true: bloquea la creación de boletas nuevas; solo se re-imprimen versiones existentes.
Phase 1 / 2 / 2.5 / 3
Etapas internas de implementación del pack: Phase 1 = pesos + boleta + matrícula; Phase 2 = workflow de aprobación; Phase 2.5 = conducta + IDL + firma; Phase 3 = Acta de Promoción + cierre de año.

Última actualización: 11 de mayo de 2026 — Phase 3 completo, módulo en producción. Volver a los Términos del servicio.