╔═══════════════════════════════════════════════════════════════════════════════════╗ ║ TABLA: social_features.teacher_reports ║ ║ Persistencia de Reportes Generados por Profesores ║ ╚═══════════════════════════════════════════════════════════════════════════════════╝ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ ESTRUCTURA DE TABLA │ └─────────────────────────────────────────────────────────────────────────────────┘ ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Columna ┃ Tipo ┃ Descripción ┃ ┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ 🔑 IDENTIFICACIÓN │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ id │ UUID │ PK, Identificador único del reporte │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ 🔗 RELACIONES │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ teacher_id │ UUID │ FK → auth_management.profiles │ │ │ │ Profesor que generó el reporte │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ classroom_id │ UUID (NULL) │ FK → social_features.classrooms │ │ │ │ Aula asociada (NULL si es individual) │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ tenant_id │ UUID │ FK → auth_management.tenants │ │ │ │ Tenant (multi-tenancy) │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ 📝 METADATOS DEL REPORTE │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ report_name │ VARCHAR(255) │ Nombre descriptivo del reporte │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ report_type │ VARCHAR(50) │ Tipo: individual | classroom | │ │ │ │ progress | analytics │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ report_format │ VARCHAR(10) │ Formato: pdf | excel | csv │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ 📊 ESTADÍSTICAS │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ student_count │ INTEGER │ Número de estudiantes en el reporte │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ period_start │ DATE │ Inicio del período reportado │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ period_end │ DATE │ Fin del período reportado │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ 📁 ARCHIVO │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ file_path │ TEXT │ Ruta del archivo generado │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ file_size_bytes │ BIGINT │ Tamaño del archivo en bytes │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ ⏰ TIMESTAMPS │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ generated_at │ TIMESTAMPTZ │ Momento de generación del reporte │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ created_at │ TIMESTAMPTZ │ Creación del registro en BD │ ├───────────────────┼──────────────┼────────────────────────────────────────────┤ │ updated_at │ TIMESTAMPTZ │ Última actualización (auto-trigger) │ └───────────────────┴──────────────┴────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ FOREIGN KEYS │ └─────────────────────────────────────────────────────────────────────────────────┘ teacher_id ──────────────┐ │ ON DELETE CASCADE ├───► auth_management.profiles(id) │ classroom_id ────────────┤ │ ON DELETE SET NULL ├───► social_features.classrooms(id) │ tenant_id ───────────────┤ │ ON DELETE CASCADE └───► auth_management.tenants(id) ┌─────────────────────────────────────────────────────────────────────────────────┐ │ ÍNDICES │ └─────────────────────────────────────────────────────────────────────────────────┘ 🔍 idx_teacher_reports_teacher_id → teacher_id Optimiza: SELECT * FROM teacher_reports WHERE teacher_id = ? 🔍 idx_teacher_reports_tenant_id → tenant_id Optimiza: SELECT * FROM teacher_reports WHERE tenant_id = ? 🔍 idx_teacher_reports_generated_at → generated_at DESC Optimiza: SELECT * FROM teacher_reports ORDER BY generated_at DESC 🔍 idx_teacher_reports_classroom_id → classroom_id (WHERE classroom_id IS NOT NULL) Optimiza: SELECT * FROM teacher_reports WHERE classroom_id = ? Índice parcial: Solo indexa registros con classroom_id no nulo 🔍 idx_teacher_reports_report_type → report_type Optimiza: SELECT * FROM teacher_reports WHERE report_type = ? ┌─────────────────────────────────────────────────────────────────────────────────┐ │ CHECK CONSTRAINTS │ └─────────────────────────────────────────────────────────────────────────────────┘ ✓ report_type IN ('individual', 'classroom', 'progress', 'analytics') ✓ report_format IN ('pdf', 'excel', 'csv') ┌─────────────────────────────────────────────────────────────────────────────────┐ │ TRIGGERS │ └─────────────────────────────────────────────────────────────────────────────────┘ ⚡ trg_teacher_reports_updated_at BEFORE UPDATE → gamilit.update_updated_at_column() Actualiza automáticamente updated_at en cada UPDATE ┌─────────────────────────────────────────────────────────────────────────────────┐ │ ROW LEVEL SECURITY (RLS) │ └─────────────────────────────────────────────────────────────────────────────────┘ 🔒 RLS HABILITADO 📋 POLÍTICAS: 1️⃣ teacher_reports_teacher_policy (SELECT) ├─ Usuarios: Profesores ├─ Condición: teacher_id = current_user_id └─ Efecto: Solo ven sus propios reportes 2️⃣ teacher_reports_admin_policy (SELECT) ├─ Usuarios: super_admin, admin_teacher ├─ Condición: tenant_id = current_tenant_id AND role IN (...) └─ Efecto: Ven todos los reportes del tenant ┌─────────────────────────────────────────────────────────────────────────────────┐ │ CASOS DE USO │ └─────────────────────────────────────────────────────────────────────────────────┘ 📊 REPORTE INDIVIDUAL ├─ report_type: 'individual' ├─ classroom_id: NULL ├─ student_count: 1 └─ Ejemplo: Reporte de progreso de un estudiante específico 📊 REPORTE DE AULA ├─ report_type: 'classroom' ├─ classroom_id: ├─ student_count: 25 (ejemplo) └─ Ejemplo: Reporte de desempeño de toda una clase 📊 REPORTE DE PROGRESO ├─ report_type: 'progress' ├─ period_start: 2025-01-01 ├─ period_end: 2025-06-30 └─ Ejemplo: Reporte de progreso semestral 📊 REPORTE DE ANALYTICS ├─ report_type: 'analytics' ├─ report_format: 'excel' └─ Ejemplo: Análisis estadístico exportable ┌─────────────────────────────────────────────────────────────────────────────────┐ │ EJEMPLO DE INSERT │ └─────────────────────────────────────────────────────────────────────────────────┘ INSERT INTO social_features.teacher_reports ( teacher_id, classroom_id, tenant_id, report_name, report_type, report_format, student_count, period_start, period_end, file_path, file_size_bytes ) VALUES ( 'a1b2c3d4-e5f6-7890-abcd-ef1234567890', -- teacher_id 'f1e2d3c4-b5a6-9780-dcba-fe0987654321', -- classroom_id 't1e2n3a4-n5t6-i7d8-9abc-def123456789', -- tenant_id 'Reporte de Progreso - Matemáticas 3A - Semestre 1', 'classroom', 'pdf', 28, '2025-01-01', '2025-06-30', '/storage/reports/2025/06/report_mat3a_s1.pdf', 1048576 -- 1 MB ); ┌─────────────────────────────────────────────────────────────────────────────────┐ │ INTEGRACIÓN CON BACKEND │ └─────────────────────────────────────────────────────────────────────────────────┘ 📁 Entity: apps/backend/src/modules/social-features/entities/teacher-report.entity.ts 📁 DTO: apps/backend/src/modules/social-features/dto/teacher-report.dto.ts 📁 Service: apps/backend/src/modules/social-features/services/teacher-reports.service.ts 📁 Controller: apps/backend/src/modules/social-features/controllers/teacher-reports.controller.ts ┌─────────────────────────────────────────────────────────────────────────────────┐ │ ENDPOINTS SUGERIDOS │ └─────────────────────────────────────────────────────────────────────────────────┘ POST /api/teacher-reports Generar nuevo reporte GET /api/teacher-reports Listar reportes (filtros: type, classroom_id) GET /api/teacher-reports/:id Obtener reporte específico DELETE /api/teacher-reports/:id Eliminar reporte GET /api/teacher-reports/:id/download Descargar archivo del reporte ═══════════════════════════════════════════════════════════════════════════════════ Generado por Database-Agent | 2025-11-26 | GAMILIT Platform ═══════════════════════════════════════════════════════════════════════════════════