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
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 porresolverPesos(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 arrancarCada 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 integrationLa 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.generatedmep.report.submitted_for_approvalmep.report.approvedmep.report.rejectedmep.report.marked_submittedmep.settings.updatedmep.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, toggleretiroAnticipadoComoAusencia.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
| Tabla | Campo | Descripción |
|---|---|---|
| Course | nivelEducativo | Enum. Conduce el resolverPesos. |
| Course | asignaturaCodigo | Clave snake_case del catálogo. |
| Course | umbrellaAdminId | Anchor para queries por sombrilla. |
| Course | weightsPendingMigration | Bool. Mientras true, no se emite boleta. |
| Assignment / Quiz | componenteOficial | Enum MepComponenteOficial. |
| Assignment | fechaProgramada | Fecha planeada (pruebas, proyectos). |
| Assignment | autoCreated | True para slots auto-generados. |
| Submission | eximido | Art. 49°: autocalifica 100. |
| Submission | reposicionPendiente | Art. 36°: marca boleta como provisional. |
| Submission | fechaReposicion | Fecha programada de reposición. |
| User | apoyoCurricular | Enum MepApoyoCurricular. Default NINGUNO. |
| User | signatureUrl | Imagen de firma para Reporte de Aula e IDL. |
| ConductReport | mepSeverity, periodId, triggersSuspension, suspensionStart/EndDate | Campos MEP opcionales aditivos. |
| AttendanceRecord | justified, justificationReason, justificationDocumentUrl, justificationSubmittedAt, lateMinutes, earlyDepartureMinutes, migrationNote | Schema 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 aplicamodalidadCentro: restringe a tipos de centroarticulo: para trazabilidad legal en la boletatipo: '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 | ResolverErrorAlgoritmo: 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álidosTIPO_CENTRO_TO_MODALIDADES: mapping a cadenas del JSONminimoAprobacion(nivel, opts): 65 default; 70 en III Ciclo bilingüe, Diversificada, EPJA IIIdecretoMetadata(): footer con referencia legalweights/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 injustificadas | Valor 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ás | 0 |
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_CERRADOWEIGHTS_PENDING_MIGRATIONNIVEL_NO_CONFIGURADOASIGNATURA_NO_CONFIGURADARESOLVER_NO_MATCHASIGNATURA_DIAGNOSTICO_FORMATIVOASSIGNMENT_SIN_COMPONENTECOMPONENTE_INCOMPLETOITEM_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_cractivo en la sombrilla ComplianceMepSettingscompleto (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
| Reporte | Formato | Inputs | Generador | Aprobación |
|---|---|---|---|---|
| Boleta de calificaciones | Curso + periodo | admin/coord | Requerida | |
| Reporte de matrícula | XLSX | Sombrilla completa | admin/coord | Requerida |
| Reporte anual de asistencia | XLSX o PDF | Año lectivo | admin/coord | Requerida |
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 + auditmep.report.generatedPOST /api/coordinator/compliance/mep/reports/[id]/submit-for-approval→ PENDING + email al admin + auditPOST /api/admin/compliance/mep/approvals/[id]/approve→ APPROVED + email al autor + auditPOST /api/admin/compliance/mep/approvals/[id]/reject→ REJECTED con razón + email + auditPOST /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
| Permiso | admin | coord | docente | estudiante |
|---|---|---|---|---|
| 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
| Evento | Fechas | Status |
|---|---|---|
| Capacitación docente | 9-20 febrero | pending → done |
| Inicio del curso lectivo | 23 febrero | pending → done |
| Entrega notas I periodo | 3 julio | pending → done/late |
| Vacaciones medio periodo | 6-17 julio | informativo |
| Entrega notas II periodo | 9 diciembre | pending → done/late |
| Cierre del curso lectivo | 9 diciembre | informativo |
| Graduaciones | 10-11 diciembre | informativo |
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 / GRAVISIMAperiodId String?— periodo lectivo al que cuentatriggersSuspension Boolean— gatilla suspensión 30 díassuspensionStartDate / 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)
| Severidad | Rebajo | Descripción |
|---|---|---|
| MUY_LEVE | −5 | Conductas menores que no afectan el clima de aula |
| LEVE | −10 | Conductas inadecuadas reiteradas o disruptivas leves |
| GRAVE | −20 | Daño material, ofensas, irrespeto significativo |
| MUY_GRAVE | −30 | Agresión, plagio mayor, acoso |
| GRAVISIMA | −50 | Faltas 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
AttendanceSessiondel estudiante en el rango, crea o actualiza elAttendanceRecordconstatus='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:
- POST con descripción del trabajo + vencimiento opcional → ConductRemediation status=ASIGNADO.
- PATCH status=EN_PROCESO mientras el estudiante trabaja (opcional).
- PATCH status=APROBADA → ConductRecord vuelve a APROBADO.
- 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/conductcon 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/conductcon 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:
- 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.
- Si conducta ok:
- 0 asignaturas reprobadas → PROMOVIDO
- 1-3 reprobadas → APLAZADO_ACADEMICO (convocatoria de ampliación)
- >3 reprobadas → REPROBADO_ACADEMICO (repite año)
- 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-promocionbody{year, studentIds?, format?}. Siformat=pdfstream 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
| Nivel | Promovido si… | Aplazado si… | Reprobado si… |
|---|---|---|---|
| I y II Ciclo EGB | Aprueba 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 regular | Aprueba 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 / Diversificada | Aprueba 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.jssigue con evaluationWeight para sombrillas sin pack activo). - El módulo no reemplaza el registro diario de asistencia.
AttendanceRecordse 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álculovalidateBoletaREA.test.ts— 3 capas + edge casesautoSlots.test.ts— idempotencia del bootstrapweights/__tests__/— invariante: cada entry JSON suma 1.0; catálogo; heurísticavalidators/__tests__/— calendario, escala, identificaciónconduct/__tests__/compute.test.ts— 13 tests del cálculo de ConductaactaPromocion/__tests__/compute.test.ts— 9 tests del Actae2e.integration.test.ts— flujo completo Phase 1-2 contra DB+R2+SMTP realesconduct-mep.integration.test.ts— 8 tests flujo Conducta end-to-endidl-preescolar.integration.test.ts— 6 tests upsert IDL + workflow statusacta-promocion.integration.test.ts— 5 tests emisión + idempotencia + PDF streamcross-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
| Lugar | Legacy | Nuevo | Fecha objetivo de retiro |
|---|---|---|---|
| AttendanceRecord | status='EXCUSED' | justified=true | Pendiente migracion de datos |
| ComplianceMepSettings | Pesos resueltos por reglamento | RETIRADO |
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ículo | Tema | Implementación |
|---|---|---|
| Art. 3° | División del curso lectivo en 2 periodos | calendar/seedYear.ts |
| Art. 26° | Escala de calificación y redondeo | grading.ts |
| Art. 27° | Evaluación preescolar (IDL) | reports/idlPreescolar.ts |
| Art. 28° | 8 componentes de la calificación | MepComponenteOficial enum |
| Art. 36° | Justificación y derecho a reposición | Submission.reposicionPendiente |
| Art. 37° | Tabla escalonada de asistencia | computeAsistenciaArt37 |
| Arts. 40°-46° | Pesos por nivel/asignatura/modalidad | weights/rea-2026.json |
| Art. 47° | Mínimos de aprobación | minimoAprobacion() |
| Art. 48° | Ponderación anual 50%-50% | grading.ts |
| Art. 49° | Eximir de última prueba | Submission.eximido |
| Art. 50° | Aprobación del año (requiere conducta) + pruebas de ampliación | actaPromocion/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_cres el pack para Costa Rica. La sombrilla activa packs enUmbrellaSettings.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
mepSeverityentra 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.