Remove build_errors.txt and validate_auth.sh scripts; clean up unused imports and fix type inference issues in lms-service.
This commit is contained in:
@@ -1,372 +0,0 @@
|
|||||||
# OpenCCB - Resumen de Configuración y Despliegue
|
|
||||||
## Fecha: 26 de Marzo de 2026
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Resumen del Proyecto
|
|
||||||
|
|
||||||
**OpenCCB** es una plataforma LMS/CMS de código abierto desplegada en **AWS EC2** con nginx-proxy para SSL automático.
|
|
||||||
|
|
||||||
**Servidor AWS:**
|
|
||||||
- **Host**: `ec2-18-224-137-67.us-east-2.compute.amazonaws.com`
|
|
||||||
- **Usuario**: `ubuntu`
|
|
||||||
- **SSH Key**: `ubuntu.pem`
|
|
||||||
- **Región**: us-east-2 (Ohio)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Configuración Actual
|
|
||||||
|
|
||||||
### Dominios
|
|
||||||
- `studio.norteamericano.com` - CMS/Admin
|
|
||||||
- `learning.norteamericano.com` - LMS/Estudiantes
|
|
||||||
|
|
||||||
### Arquitectura
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────┐
|
|
||||||
│ AWS EC2 │
|
|
||||||
│ │
|
|
||||||
│ ┌─────────────┐ ┌──────────────────────────┐ │
|
|
||||||
│ │ nginx │───▶│ Studio + CMS │ │
|
|
||||||
│ │ proxy │ │ (Next.js + Rust) │ │
|
|
||||||
│ │ :80, :443 │ │ :3000, :3001 │ │
|
|
||||||
│ └──────┬──────┘ └──────────┬───────────────┘ │
|
|
||||||
│ │ │ │
|
|
||||||
│ │ ┌─────────────────┘ │
|
|
||||||
│ │ │ │
|
|
||||||
│ ▼ ▼ │
|
|
||||||
│ ┌─────────────┐ ┌──────────────────────────┐ │
|
|
||||||
│ │ acme │ │ Experience + LMS │ │
|
|
||||||
│ │ companion │ │ (Next.js + Rust) │ │
|
|
||||||
│ │ (Let's │ │ :3003, :3002 │ │
|
|
||||||
│ │ Encrypt) │ └──────────┬───────────────┘ │
|
|
||||||
│ └─────────────┘ │ │
|
|
||||||
│ │ │
|
|
||||||
│ ┌──────────▼───────────────┐ │
|
|
||||||
│ │ PostgreSQL + PGVector │ │
|
|
||||||
│ │ :5432 │ │
|
|
||||||
│ └──────────────────────────┘ │
|
|
||||||
└─────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Comandos de Despliegue
|
|
||||||
|
|
||||||
### Desde tu máquina local:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ejecutar deploy
|
|
||||||
./deploy.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
El script preguntará:
|
|
||||||
1. Nombre del administrador
|
|
||||||
2. Email del administrador
|
|
||||||
3. Contraseña (oculta)
|
|
||||||
4. Nombre de la organización
|
|
||||||
5. ¿Usar SSL? [y/N]
|
|
||||||
- **y**: Usará HTTPS (con o sin staging)
|
|
||||||
- **N**: Usará HTTP (recomendado para staging)
|
|
||||||
6. ¿Usar STAGING? [y/N] (solo si elegiste SSL)
|
|
||||||
- **y**: Certificados de prueba (sin rate limits)
|
|
||||||
- **N**: Certificados reales (con rate limits)
|
|
||||||
|
|
||||||
### Conexión al servidor:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh -i "ubuntu.pem" ubuntu@ec2-18-224-137-67.us-east-2.compute.amazonaws.com
|
|
||||||
cd /var/www/openccb
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ Problemas Conocidos y Soluciones
|
|
||||||
|
|
||||||
### 1. Login Pegado / Error de Conexión API
|
|
||||||
|
|
||||||
**Problema**: El botón de login se queda procesando infinitamente.
|
|
||||||
|
|
||||||
**Causa**: Las URLs de la API incluyen el puerto `:3001` incorrectamente.
|
|
||||||
|
|
||||||
**Solución Aplicada**:
|
|
||||||
- Actualizado `web/studio/src/lib/api.ts` para hardcodear las URLs de producción
|
|
||||||
- El código ahora detecta el hostname y usa la URL sin puerto
|
|
||||||
|
|
||||||
**Comandos para Solucionar**:
|
|
||||||
```bash
|
|
||||||
# Conectarse al servidor
|
|
||||||
ssh -i "ubuntu.pem" ubuntu@ec2-18-224-137-67.us-east-2.compute.amazonaws.com
|
|
||||||
cd /var/www/openccb
|
|
||||||
|
|
||||||
# Detener todo
|
|
||||||
sudo docker compose down
|
|
||||||
|
|
||||||
# Eliminar imágenes cacheadas
|
|
||||||
sudo docker rmi openccb-studio 2>/dev/null || true
|
|
||||||
sudo docker images | grep openccb | awk '{print $3}' | xargs sudo docker rmi -f 2>/dev/null || true
|
|
||||||
|
|
||||||
# Limpiar caché de Docker
|
|
||||||
sudo docker builder prune -af
|
|
||||||
sudo docker system prune -af
|
|
||||||
|
|
||||||
# Reconstruir DESDE CERO (CRÍTICO usar --no-cache)
|
|
||||||
sudo docker compose build --no-cache studio
|
|
||||||
|
|
||||||
# Iniciar todo
|
|
||||||
sudo docker compose up -d
|
|
||||||
|
|
||||||
# Esperar 1 minuto
|
|
||||||
sleep 60
|
|
||||||
|
|
||||||
# Verificar
|
|
||||||
sudo docker compose ps
|
|
||||||
docker logs openccb-studio --tail 20
|
|
||||||
```
|
|
||||||
|
|
||||||
**Verificación en el Navegador**:
|
|
||||||
1. Abrir ventana de incógnito (Ctrl+Shift+N)
|
|
||||||
2. Ir a `http://studio.norteamericano.com`
|
|
||||||
3. Abrir consola (F12) → Pestaña Network
|
|
||||||
4. Intentar loguearse
|
|
||||||
5. Verificar que la URL sea: `http://studio.norteamericano.com/auth/login` (SIN puerto)
|
|
||||||
|
|
||||||
### 2. Rate Limit de Let's Encrypt
|
|
||||||
|
|
||||||
**Problema**: Se alcanzó el límite de 5 certificados por semana.
|
|
||||||
|
|
||||||
**Solución Temporal**:
|
|
||||||
- Usar HTTP en lugar de HTTPS
|
|
||||||
- O usar Let's Encrypt Staging (certificados de prueba)
|
|
||||||
|
|
||||||
**Fecha de Reinicio**: 2026-03-27 04:21:42 UTC
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Archivos Modificados
|
|
||||||
|
|
||||||
### 1. `deploy.sh`
|
|
||||||
- ✅ Pregunta datos del administrador
|
|
||||||
- ✅ Pregunta sobre SSL y Staging
|
|
||||||
- ✅ Actualiza docker-compose.yml según elección (HTTP/HTTPS)
|
|
||||||
- ✅ Reconstruye contenedores con `--no-cache`
|
|
||||||
- ✅ Verifica variables de entorno en los contenedores
|
|
||||||
- ✅ Muestra URLs correctas según protocolo elegido
|
|
||||||
|
|
||||||
### 2. `docker-compose.yml`
|
|
||||||
- ✅ URLs en HTTP por defecto
|
|
||||||
- ✅ Ambos argumentos de build para studio:
|
|
||||||
- `NEXT_PUBLIC_CMS_API_URL: http://studio.norteamericano.com`
|
|
||||||
- `NEXT_PUBLIC_LMS_API_URL: http://learning.norteamericano.com`
|
|
||||||
- ✅ Variables de entorno correctas
|
|
||||||
|
|
||||||
### 3. `web/studio/Dockerfile`
|
|
||||||
- ✅ Agrega `ARG NEXT_PUBLIC_LMS_API_URL`
|
|
||||||
- ✅ Agrega `ENV NEXT_PUBLIC_LMS_API_URL`
|
|
||||||
|
|
||||||
### 4. `web/studio/src/lib/api.ts`
|
|
||||||
- ✅ Corrige función `getApiBaseUrl` para producción
|
|
||||||
- ✅ Hardcodea URLs para `studio.norteamericano.com` y `learning.norteamericano.com`
|
|
||||||
- ✅ Elimina el puerto de las URLs en producción
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔐 Credenciales (Ejemplo)
|
|
||||||
|
|
||||||
**Usuario Administrador**:
|
|
||||||
- Email: `admin@norteamericano.com`
|
|
||||||
- Contraseña: `Admin123!` (o la que se haya configurado)
|
|
||||||
|
|
||||||
**Base de Datos** (en `/var/www/openccb/.env`):
|
|
||||||
```
|
|
||||||
DB_PASSWORD=<generada_aleatoriamente>
|
|
||||||
JWT_SECRET=<generada_aleatoriamente>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Comandos Útiles
|
|
||||||
|
|
||||||
### Ver estado de servicios
|
|
||||||
```bash
|
|
||||||
sudo docker compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ver logs
|
|
||||||
```bash
|
|
||||||
# Todos los servicios
|
|
||||||
sudo docker compose logs -f
|
|
||||||
|
|
||||||
# Servicio específico
|
|
||||||
docker logs openccb-studio --tail 50
|
|
||||||
docker logs openccb-experience --tail 50
|
|
||||||
docker logs acme-companion --tail 50
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verificar variables de entorno
|
|
||||||
```bash
|
|
||||||
# Studio
|
|
||||||
sudo docker exec openccb-studio env | grep NEXT_PUBLIC
|
|
||||||
|
|
||||||
# Experience
|
|
||||||
sudo docker exec openccb-experience env | grep NEXT_PUBLIC
|
|
||||||
|
|
||||||
# Debería mostrar:
|
|
||||||
# NEXT_PUBLIC_CMS_API_URL=http://studio.norteamericano.com
|
|
||||||
# NEXT_PUBLIC_LMS_API_URL=http://learning.norteamericano.com
|
|
||||||
```
|
|
||||||
|
|
||||||
### Reconstruir contenedores
|
|
||||||
```bash
|
|
||||||
# Todo
|
|
||||||
sudo docker compose build --no-cache
|
|
||||||
sudo docker compose up -d
|
|
||||||
|
|
||||||
# Solo studio
|
|
||||||
sudo docker compose build --no-cache studio
|
|
||||||
sudo docker compose up -d studio
|
|
||||||
```
|
|
||||||
|
|
||||||
### Limpiar caché de Docker
|
|
||||||
```bash
|
|
||||||
# Limpiar builder
|
|
||||||
sudo docker builder prune -af
|
|
||||||
|
|
||||||
# Limpiar sistema
|
|
||||||
sudo docker system prune -af
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verificar certificados SSL
|
|
||||||
```bash
|
|
||||||
docker logs acme-companion --tail 50
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Próximos Pasos
|
|
||||||
|
|
||||||
### 1. Reconstruir Studio con --no-cache
|
|
||||||
```bash
|
|
||||||
ssh -i "ubuntu.pem" ubuntu@ec2-18-224-137-67.us-east-2.compute.amazonaws.com
|
|
||||||
cd /var/www/openccb
|
|
||||||
|
|
||||||
sudo docker compose down
|
|
||||||
sudo docker rmi openccb-studio 2>/dev/null || true
|
|
||||||
sudo docker builder prune -af
|
|
||||||
sudo docker compose build --no-cache studio
|
|
||||||
sudo docker compose up -d
|
|
||||||
sleep 60
|
|
||||||
sudo docker compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Probar Login
|
|
||||||
- Abrir ventana de incógnito
|
|
||||||
- Ir a `http://studio.norteamericano.com`
|
|
||||||
- Ver consola (F12) → Network
|
|
||||||
- Verificar URL: `http://studio.norteamericano.com/auth/login`
|
|
||||||
- Intentar loguearse
|
|
||||||
|
|
||||||
### 3. Verificar Funcionalidades
|
|
||||||
- [ ] Login de administrador
|
|
||||||
- [ ] Creación de cursos
|
|
||||||
- [ ] Subida de archivos
|
|
||||||
- [ ] Integración con LMS
|
|
||||||
- [ ] Certificados SSL generados
|
|
||||||
|
|
||||||
### 4. Cambiar a HTTPS (Después del Rate Limit)
|
|
||||||
```bash
|
|
||||||
# Después del 2026-03-27
|
|
||||||
./deploy.sh
|
|
||||||
# Responder "y" a "¿Usar SSL?"
|
|
||||||
# Responder "n" a "¿Usar STAGING?"
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Solución de Problemas Comunes
|
|
||||||
|
|
||||||
### Login se queda procesando
|
|
||||||
```bash
|
|
||||||
# Verificar URL en consola del navegador
|
|
||||||
# Debe ser: http://studio.norteamericano.com/auth/login
|
|
||||||
# NO debe tener :3001
|
|
||||||
|
|
||||||
# Si tiene puerto, reconstruir con --no-cache
|
|
||||||
sudo docker compose build --no-cache studio
|
|
||||||
sudo docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error 502 Bad Gateway
|
|
||||||
```bash
|
|
||||||
# Verificar que los servicios están corriendo
|
|
||||||
sudo docker compose ps
|
|
||||||
|
|
||||||
# Ver logs
|
|
||||||
docker logs openccb-studio --tail 50
|
|
||||||
docker logs nginx-proxy --tail 50
|
|
||||||
|
|
||||||
# Reiniciar
|
|
||||||
sudo docker compose restart
|
|
||||||
```
|
|
||||||
|
|
||||||
### Variables NEXT_PUBLIC faltantes
|
|
||||||
```bash
|
|
||||||
# Ver docker-compose.yml
|
|
||||||
cat docker-compose.yml | grep -A 10 "studio:"
|
|
||||||
|
|
||||||
# Verificar en contenedor
|
|
||||||
sudo docker exec openccb-studio env | grep NEXT_PUBLIC
|
|
||||||
|
|
||||||
# Reconstruir
|
|
||||||
sudo docker compose build --no-cache studio
|
|
||||||
```
|
|
||||||
|
|
||||||
### Certificados SSL no se generan
|
|
||||||
```bash
|
|
||||||
# Ver logs
|
|
||||||
docker logs acme-companion --tail 100
|
|
||||||
|
|
||||||
# Verificar DNS
|
|
||||||
dig studio.norteamericano.com
|
|
||||||
dig learning.norteamericano.com
|
|
||||||
|
|
||||||
# Verificar puertos
|
|
||||||
sudo netstat -tlnp | grep :80
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Notas Importantes
|
|
||||||
|
|
||||||
1. **HTTP vs HTTPS**: Actualmente se usa HTTP porque:
|
|
||||||
- Los certificados de staging no son válidos para producción
|
|
||||||
- Las llamadas API entre dominios requieren HTTP o certificados válidos
|
|
||||||
|
|
||||||
2. **Rate Limit**: Let's Encrypt permite 5 certificados por semana por dominio. El límite se reinicia el 2026-03-27.
|
|
||||||
|
|
||||||
3. **--no-cache es CRÍTICO**: Siempre usar `--no-cache` al reconstruir Studio para que los cambios en el código se apliquen. Docker usa caché por defecto.
|
|
||||||
|
|
||||||
4. **Ventana de Incógnito**: Después de reconstruir, siempre probar en ventana de incógnito para evitar caché del navegador.
|
|
||||||
|
|
||||||
5. **URLs Hardcodeadas**: El código ahora tiene las URLs de producción hardcodeadas para `studio.norteamericano.com` y `learning.norteamericano.com`. Esto evita problemas con variables de entorno.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Contacto y Soporte
|
|
||||||
|
|
||||||
**Documentación**:
|
|
||||||
- `DESPLIEGUE.md` - Instrucciones de despliegue
|
|
||||||
- `README.md` - Documentación general
|
|
||||||
- `docker-compose.yml` - Configuración de servicios
|
|
||||||
|
|
||||||
**Archivos de Configuración**:
|
|
||||||
- `/var/www/openccb/.env` - Variables de entorno
|
|
||||||
- `/var/www/openccb/docker-compose.yml` - Servicios Docker
|
|
||||||
- `web/studio/Dockerfile` - Build de Studio
|
|
||||||
- `web/studio/src/lib/api.ts` - Configuración de APIs
|
|
||||||
- `deploy.sh` - Script de despliegue
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Última Actualización**: 26 de Marzo de 2026
|
|
||||||
**Estado**: ✅ Solución aplicada - Pendiente reconstruir con --no-cache y probar login
|
|
||||||
@@ -1,468 +0,0 @@
|
|||||||
# OpenCCB - Project Context
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
**OpenCCB (Open Comprehensive Course Backbone)** is an open-source Learning Management System (LMS) and Content Management System (CMS) platform built for performance, security, and scalability. It provides a complete infrastructure for course creation, student management, and AI-powered learning features.
|
|
||||||
|
|
||||||
### Architecture
|
|
||||||
|
|
||||||
The project uses a **unified container architecture** with the following structure:
|
|
||||||
|
|
||||||
| Service | Ports | Description |
|
|
||||||
|---------|-------|-------------|
|
|
||||||
| **Studio + CMS** | 3000/3001 | Next.js admin frontend + Rust CMS API |
|
|
||||||
| **Experience + LMS** | 3003/3002 | Next.js student frontend + Rust LMS API |
|
|
||||||
| **Database** | 5433 | PostgreSQL 16 (shared, separate DBs: `openccb_cms`, `openccb_lms`) |
|
|
||||||
|
|
||||||
### Technology Stack
|
|
||||||
|
|
||||||
**Backend:**
|
|
||||||
- Rust Edition 2024 (workspace with 3 crates)
|
|
||||||
- Web Framework: Axum 0.8
|
|
||||||
- Database: SQLx 0.8 with PostgreSQL 16
|
|
||||||
- Authentication: JWT (jsonwebtoken 9.3), bcrypt
|
|
||||||
- Security: HMAC, SHA2, OpenID Connect (SSO)
|
|
||||||
- Rate Limiting: tower-governor 0.7
|
|
||||||
|
|
||||||
**Frontend:**
|
|
||||||
- Next.js 14 (App Router)
|
|
||||||
- React 18 + TypeScript 5
|
|
||||||
- Styling: Tailwind CSS 3.4
|
|
||||||
- UI: Lucide React, Framer Motion, React Markdown
|
|
||||||
- Mermaid diagrams for dynamic visualization
|
|
||||||
|
|
||||||
**Infrastructure:**
|
|
||||||
- Docker & Docker Compose
|
|
||||||
- Single-tenant design (premium module)
|
|
||||||
- Local AI: Ollama (Llama 3.2) + Faster-Whisper
|
|
||||||
|
|
||||||
**Key Features:**
|
|
||||||
- AI-powered course generation and quiz creation
|
|
||||||
- Discussion forums with nested replies
|
|
||||||
- LTI 1.3 Tool Provider (Canvas, Moodle integration)
|
|
||||||
- Monetization via Mercado Pago
|
|
||||||
- Live learning with Jitsi integration
|
|
||||||
- Student portfolios with Open Badges
|
|
||||||
- Predictive analytics (dropout risk detection)
|
|
||||||
- Multi-language support (EN, ES, PT)
|
|
||||||
- Gamification (XP, levels, badges, leaderboards)
|
|
||||||
- **Semantic search with PGVector** (question bank, knowledge base)
|
|
||||||
- **RAG-enhanced AI tutor** with contextual retrieval
|
|
||||||
- **MySQL integration** (study plans, courses import)
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
openccb/
|
|
||||||
├── services/
|
|
||||||
│ ├── cms-service/ # Rust CMS API (course management, content creation)
|
|
||||||
│ │ ├── migrations/ # SQLx database migrations
|
|
||||||
│ │ └── src/
|
|
||||||
│ └── lms-service/ # Rust LMS API (student experience, grades)
|
|
||||||
│ └── src/
|
|
||||||
├── shared/
|
|
||||||
│ └── common/ # Shared Rust library (auth, models, utils)
|
|
||||||
├── web/
|
|
||||||
│ ├── studio/ # Next.js CMS frontend (admin/instructor)
|
|
||||||
│ └── experience/ # Next.js LMS frontend (student)
|
|
||||||
├── e2e/ # Playwright end-to-end tests
|
|
||||||
├── scripts/ # Utility scripts (auth, database)
|
|
||||||
└── [config files]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rust Workspace Members
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[workspace]
|
|
||||||
members = [
|
|
||||||
"services/cms-service",
|
|
||||||
"services/lms-service",
|
|
||||||
"shared/common",
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building and Running
|
|
||||||
|
|
||||||
### Docker (Recommended)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Start all services
|
|
||||||
docker-compose up --build
|
|
||||||
|
|
||||||
# Start in detached mode
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Rebuild and start
|
|
||||||
docker-compose up -d --build
|
|
||||||
|
|
||||||
# Clean install (removes volumes)
|
|
||||||
docker-compose down -v && docker-compose up --build
|
|
||||||
|
|
||||||
# Run E2E tests
|
|
||||||
docker-compose --profile test up e2e
|
|
||||||
```
|
|
||||||
|
|
||||||
### Local Development
|
|
||||||
|
|
||||||
**Prerequisites:**
|
|
||||||
- Rust (Edition 2024)
|
|
||||||
- Node.js 18+
|
|
||||||
- PostgreSQL 16
|
|
||||||
- sqlx-cli: `cargo install sqlx-cli --no-default-features --features postgres`
|
|
||||||
|
|
||||||
**Backend (Rust):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# CMS Service (port 3001)
|
|
||||||
cd services/cms-service
|
|
||||||
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms cargo run
|
|
||||||
|
|
||||||
# LMS Service (port 3002)
|
|
||||||
cd services/lms-service
|
|
||||||
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_lms cargo run
|
|
||||||
|
|
||||||
# With debug logging
|
|
||||||
RUST_LOG=debug cargo run -p cms-service
|
|
||||||
```
|
|
||||||
|
|
||||||
**Frontend (Next.js):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Studio (CMS Frontend - port 3000)
|
|
||||||
cd web/studio
|
|
||||||
npm install
|
|
||||||
npm run dev
|
|
||||||
|
|
||||||
# Experience (LMS Frontend - port 3003)
|
|
||||||
cd web/experience
|
|
||||||
npm install
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### Installation Script
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Full installation with database setup
|
|
||||||
./install.sh
|
|
||||||
|
|
||||||
# Fast mode (skip dependency checks)
|
|
||||||
./install.sh --fast
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development Commands
|
|
||||||
|
|
||||||
### Code Quality
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Frontend linting and formatting
|
|
||||||
cd web/studio && npm run lint:fix
|
|
||||||
cd web/studio && npm run format
|
|
||||||
cd web/studio && npm run type-check
|
|
||||||
|
|
||||||
# Same commands available in web/experience
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Reset database (delete and recreate)
|
|
||||||
./reset_db.sh
|
|
||||||
|
|
||||||
# Run migrations manually
|
|
||||||
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms \
|
|
||||||
sqlx migrate run --source services/cms-service/migrations
|
|
||||||
|
|
||||||
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_lms \
|
|
||||||
sqlx migrate run --source services/lms-service/migrations
|
|
||||||
```
|
|
||||||
|
|
||||||
### Health Checks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# CMS Service
|
|
||||||
curl http://localhost:3001/health
|
|
||||||
curl http://localhost:3001/health/live
|
|
||||||
curl http://localhost:3001/health/ready
|
|
||||||
|
|
||||||
# LMS Service
|
|
||||||
curl http://localhost:3002/health
|
|
||||||
curl http://localhost:3002/health/live
|
|
||||||
curl http://localhost:3002/health/ready
|
|
||||||
```
|
|
||||||
|
|
||||||
### Utilities
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Generate secure JWT secret
|
|
||||||
./generate_jwt_secret.sh
|
|
||||||
|
|
||||||
# Clear session
|
|
||||||
./clear_session.sh
|
|
||||||
|
|
||||||
# Validate authentication
|
|
||||||
./validate_auth.sh
|
|
||||||
|
|
||||||
# Diagnose auth issues
|
|
||||||
./diagnose_auth.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Endpoints
|
|
||||||
|
|
||||||
### Authentication (CMS - port 3001)
|
|
||||||
|
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| POST | `/auth/register` | Create new user |
|
|
||||||
| POST | `/auth/login` | Login and get JWT token |
|
|
||||||
| GET | `/auth/profile` | Get current user profile |
|
|
||||||
|
|
||||||
### Course Management (CMS)
|
|
||||||
|
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| POST | `/courses` | Create course |
|
|
||||||
| POST | `/courses/generate` | AI-generate course structure |
|
|
||||||
| GET | `/courses/{id}/export` | Export course to JSON |
|
|
||||||
| POST | `/courses/import` | Import course from JSON |
|
|
||||||
| DELETE | `/courses/{id}` | Delete course |
|
|
||||||
| POST | `/lessons` | Add lesson to module |
|
|
||||||
| POST | `/assets/upload` | Upload media/document |
|
|
||||||
|
|
||||||
### Learning Experience (LMS - port 3002)
|
|
||||||
|
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| POST | `/enroll` | Enroll in course |
|
|
||||||
| POST | `/grades` | Submit lesson score |
|
|
||||||
| GET | `/notifications` | Get user notifications |
|
|
||||||
| POST | `/notifications/{id}/read` | Mark notification as read |
|
|
||||||
|
|
||||||
### Discussion Forums (LMS)
|
|
||||||
|
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| GET | `/courses/{id}/discussions` | List threads |
|
|
||||||
| POST | `/courses/{id}/discussions` | Create thread |
|
|
||||||
| GET | `/discussions/{id}` | Get thread with replies |
|
|
||||||
| POST | `/discussions/{id}/posts` | Reply to thread |
|
|
||||||
| POST | `/posts/{id}/vote` | Vote on post |
|
|
||||||
| POST | `/posts/{id}/endorse` | Mark post as correct (instructor) |
|
|
||||||
|
|
||||||
### AI Features
|
|
||||||
|
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| POST | `/lessons/{id}/transcribe` | Start transcription |
|
|
||||||
| POST | `/lessons/{id}/generate-quiz` | Generate quiz with AI |
|
|
||||||
| POST | `/lessons/{id}/chat` | Chat with lesson tutor |
|
|
||||||
| GET | `/lessons/{id}/feedback` | Get AI feedback |
|
|
||||||
| GET | `/courses/{id}/dropout-risks` | Get dropout risk analysis |
|
|
||||||
| POST | `/question-bank/embeddings/generate` | Generate embeddings for questions |
|
|
||||||
| POST | `/question-bank/{id}/embedding/regenerate` | Regenerate question embedding |
|
|
||||||
| GET | `/question-bank/semantic-search` | Search questions semantically |
|
|
||||||
| GET | `/question-bank/similar/{id}` | Find similar questions (duplicates) |
|
|
||||||
| POST | `/question-bank/generate-with-rag` | Generate question with RAG + 4 skills |
|
|
||||||
| POST | `/knowledge-base/embeddings/generate` | Generate knowledge base embeddings |
|
|
||||||
| GET | `/knowledge-base/semantic-search` | Search knowledge base semantically |
|
|
||||||
|
|
||||||
## Environment Configuration
|
|
||||||
|
|
||||||
Copy `.env.example` to `.env` and configure:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Database
|
|
||||||
CMS_DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms
|
|
||||||
LMS_DATABASE_URL=postgresql://user:password@localhost:5433/openccb_lms
|
|
||||||
|
|
||||||
# JWT Secret (generate with ./generate_jwt_secret.sh)
|
|
||||||
JWT_SECRET=your_secure_secret
|
|
||||||
|
|
||||||
# AI Configuration
|
|
||||||
AI_PROVIDER=local
|
|
||||||
LOCAL_WHISPER_URL=http://localhost:9000
|
|
||||||
LOCAL_OLLAMA_URL=http://localhost:11434
|
|
||||||
LOCAL_LLM_MODEL=llama3.2:3b
|
|
||||||
EMBEDDING_MODEL=nomic-embed-text
|
|
||||||
|
|
||||||
# Frontend URLs
|
|
||||||
NEXT_PUBLIC_CMS_API_URL=http://localhost:3001
|
|
||||||
NEXT_PUBLIC_LMS_API_URL=http://localhost:3002
|
|
||||||
|
|
||||||
# Backend-to-backend (LMS -> CMS)
|
|
||||||
CMS_API_URL=http://studio:3001
|
|
||||||
```
|
|
||||||
|
|
||||||
### Default Credentials
|
|
||||||
|
|
||||||
After running `./install.sh`, the default admin user is:
|
|
||||||
- **Email**: `admin@norteamericano.cl`
|
|
||||||
- **Password**: `Admin123!`
|
|
||||||
|
|
||||||
You can customize these during installation.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
### E2E Tests (Playwright)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests
|
|
||||||
cd e2e && npx playwright test
|
|
||||||
|
|
||||||
# Run with UI
|
|
||||||
cd e2e && npx playwright test --ui
|
|
||||||
|
|
||||||
# Run specific test file
|
|
||||||
cd e2e && npx playwright test tests/auth.spec.ts
|
|
||||||
|
|
||||||
# Generate report
|
|
||||||
cd e2e && npx playwright show-report
|
|
||||||
```
|
|
||||||
|
|
||||||
### Backend Tests
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run Rust tests
|
|
||||||
cargo test -p cms-service
|
|
||||||
cargo test -p lms-service
|
|
||||||
cargo test -p common
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Conventions
|
|
||||||
|
|
||||||
### Rust Code Style
|
|
||||||
|
|
||||||
- Use workspace dependencies from root `Cargo.toml`
|
|
||||||
- Shared code goes in `shared/common`
|
|
||||||
- Use `sqlx::query!` macros for compile-time SQL verification
|
|
||||||
- Error handling with `thiserror` and `anyhow`
|
|
||||||
- Tracing for logging (`tracing::info!`, `tracing::debug!`)
|
|
||||||
|
|
||||||
### Frontend Code Style
|
|
||||||
|
|
||||||
- TypeScript strict mode enabled
|
|
||||||
- Tailwind CSS for styling
|
|
||||||
- Lucide React for icons
|
|
||||||
- Framer Motion for animations
|
|
||||||
- Components in `src/components/`
|
|
||||||
- Pages in `src/app/` (Next.js App Router)
|
|
||||||
|
|
||||||
### Database
|
|
||||||
|
|
||||||
- Separate databases for CMS and LMS
|
|
||||||
- Migrations managed by SQLx
|
|
||||||
- UUIDs for primary keys
|
|
||||||
- Timestamps with timezone (timestamptz)
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
|
|
||||||
- JWT-based authentication
|
|
||||||
- Bcrypt password hashing
|
|
||||||
- Role-based access control (admin, instructor, student)
|
|
||||||
- OpenID Connect support for SSO
|
|
||||||
|
|
||||||
## Common Issues
|
|
||||||
|
|
||||||
### CORS Errors (Login/Registro)
|
|
||||||
|
|
||||||
Si ves errores de CORS al intentar loguearte:
|
|
||||||
|
|
||||||
```
|
|
||||||
Access to fetch at 'http://localhost:3001/auth/login' from origin 'http://localhost:3000'
|
|
||||||
has been blocked by CORS policy
|
|
||||||
```
|
|
||||||
|
|
||||||
**Solución**: Asegúrate de que el rate limiter NO esté aplicado a las rutas de autenticación.
|
|
||||||
En `services/cms-service/src/main.rs`, el `GovernorLayer` debe estar solo en `protected_routes`,
|
|
||||||
no en `public_routes`.
|
|
||||||
|
|
||||||
### Rate Limiter Bloqueando Peticiones
|
|
||||||
|
|
||||||
**Estado actual**: El rate limiter (`tower_governor`) está **deshabilitado** debido a problemas de compatibilidad con el middleware de autenticación.
|
|
||||||
|
|
||||||
Si quieres habilitarlo en producción:
|
|
||||||
|
|
||||||
1. Agrega `GovernorLayer` solo a rutas protegidas usando `.route_layer()`
|
|
||||||
2. Configúralo después del middleware de autenticación
|
|
||||||
3. Ajusta los límites (por defecto: 10 req/s, burst 50)
|
|
||||||
|
|
||||||
```rust
|
|
||||||
.protected_routes
|
|
||||||
.route_layer(middleware::from_fn(org_extractor_middleware))
|
|
||||||
.route_layer(GovernorLayer { config: governor_conf })
|
|
||||||
```
|
|
||||||
|
|
||||||
**Advertencia**: Si el rate limiter está mal configurado, las peticiones a `/courses`, `/auth/login`, etc. pueden fallar con error 500 sin logs.
|
|
||||||
|
|
||||||
### Port Conflicts
|
|
||||||
|
|
||||||
If port 5432 is occupied, the setup uses 5433:
|
|
||||||
```bash
|
|
||||||
# Check if port is in use
|
|
||||||
lsof -i :5432
|
|
||||||
lsof -i :5433
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Connection Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check if PostgreSQL is running
|
|
||||||
docker ps | grep postgres
|
|
||||||
|
|
||||||
# Check database connectivity
|
|
||||||
docker exec openccb-db-1 pg_isready -U user
|
|
||||||
```
|
|
||||||
|
|
||||||
### PGVector Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check if pgvector extension is enabled
|
|
||||||
docker exec -it openccb-db-1 psql -U user -d openccb_cms -c "SELECT * FROM pg_extension WHERE extname = 'vector';"
|
|
||||||
|
|
||||||
# If not enabled, run migration
|
|
||||||
DATABASE_URL=postgresql://user:password@localhost:5433/openccb_cms \
|
|
||||||
sqlx migrate run --source services/cms-service/migrations
|
|
||||||
```
|
|
||||||
|
|
||||||
### Embedding Generation Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check if Ollama is running
|
|
||||||
curl http://localhost:11434/api/tags
|
|
||||||
|
|
||||||
# Pull embedding model
|
|
||||||
docker exec -it ollama ollama pull nomic-embed-text
|
|
||||||
|
|
||||||
# Test embedding generation
|
|
||||||
curl -X POST http://localhost:11434/api/embeddings \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"model": "nomic-embed-text", "prompt": "Hello world"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Frontend Build Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clear Next.js cache
|
|
||||||
rm -rf web/studio/.next
|
|
||||||
rm -rf web/experience/.next
|
|
||||||
|
|
||||||
# Reinstall dependencies
|
|
||||||
cd web/studio && rm -rf node_modules && npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rust Compilation Issues
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clean and rebuild
|
|
||||||
cargo clean
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
# Update dependencies
|
|
||||||
cargo update
|
|
||||||
```
|
|
||||||
|
|
||||||
## Related Documentation
|
|
||||||
|
|
||||||
- `README.md` - Comprehensive user documentation with API manual
|
|
||||||
- `OPTIMIZATIONS.md` - Performance optimizations implemented
|
|
||||||
- `roadmap.md` - Project roadmap and feature status
|
|
||||||
- `diagnose_auth.sh` - Authentication debugging script
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
const { Client } = require('pg');
|
|
||||||
|
|
||||||
async function checkEnrollments() {
|
|
||||||
const client = new Client({
|
|
||||||
connectionString: "postgresql://user:password@localhost:5432/openccb_lms"
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await client.connect();
|
|
||||||
console.log("Connected to LMS DB");
|
|
||||||
|
|
||||||
console.log("\n--- Users ---");
|
|
||||||
const users = await client.query("SELECT id, email, organization_id, full_name FROM users");
|
|
||||||
console.table(users.rows);
|
|
||||||
|
|
||||||
console.log("\n--- Enrollments ---");
|
|
||||||
const enrollments = await client.query("SELECT id, user_id, course_id, organization_id FROM enrollments");
|
|
||||||
console.table(enrollments.rows);
|
|
||||||
|
|
||||||
console.log("\n--- Courses ---");
|
|
||||||
const courses = await client.query("SELECT id, title, organization_id FROM courses");
|
|
||||||
console.table(courses.rows);
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Error:", err);
|
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkEnrollments();
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
const mysql = require('mysql2/promise');
|
|
||||||
|
|
||||||
async function checkMySQL() {
|
|
||||||
try {
|
|
||||||
const conn = await mysql.createConnection('mysql://root:Smith3976!@ec2-18-222-25-254.us-east-2.compute.amazonaws.com:3306/sige_sam_v3');
|
|
||||||
console.log('Conectado a MySQL\n');
|
|
||||||
|
|
||||||
// Mostrar tablas
|
|
||||||
const [tables] = await conn.query('SHOW TABLES');
|
|
||||||
console.log('=== TABLAS ===');
|
|
||||||
console.table(tables);
|
|
||||||
|
|
||||||
// Estructura de curso
|
|
||||||
console.log('\n=== ESTRUCTURA DE curso ===');
|
|
||||||
const [cursoCols] = await conn.query('DESCRIBE curso');
|
|
||||||
console.table(cursoCols);
|
|
||||||
|
|
||||||
// Estructura de plandeestudios
|
|
||||||
console.log('\n=== ESTRUCTURA DE plandeestudios ===');
|
|
||||||
const [planCols] = await conn.query('DESCRIBE plandeestudios');
|
|
||||||
console.table(planCols);
|
|
||||||
|
|
||||||
// Ver algunos cursos de ejemplo
|
|
||||||
console.log('\n=== CURSOS (ejemplo) ===');
|
|
||||||
const [cursos] = await conn.query('SELECT * FROM curso LIMIT 5');
|
|
||||||
console.table(cursos);
|
|
||||||
|
|
||||||
// Ver planes de estudio
|
|
||||||
console.log('\n=== PLANES DE ESTUDIO (ejemplo) ===');
|
|
||||||
const [planes] = await conn.query('SELECT * FROM plandeestudios LIMIT 5');
|
|
||||||
console.table(planes);
|
|
||||||
|
|
||||||
// Buscar tabla con idDetalleContrato
|
|
||||||
console.log('\n=== Buscando tablas con idDetalleContrato ===');
|
|
||||||
const [detalleTables] = await conn.query(`
|
|
||||||
SELECT TABLE_NAME, COLUMN_NAME
|
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
|
||||||
WHERE TABLE_SCHEMA = 'sige_sam_v3'
|
|
||||||
AND COLUMN_NAME LIKE '%idDetalle%'
|
|
||||||
`);
|
|
||||||
console.table(detalleTables);
|
|
||||||
|
|
||||||
// Estructura de detallecontrato
|
|
||||||
console.log('\n=== ESTRUCTURA DE detallecontrato ===');
|
|
||||||
const [detalleCols] = await conn.query('DESCRIBE detallecontrato');
|
|
||||||
console.table(detalleCols);
|
|
||||||
|
|
||||||
// Estructura de prueba (banco de preguntas)
|
|
||||||
console.log('\n=== ESTRUCTURA DE prueba ===');
|
|
||||||
const [pruebaCols] = await conn.query('DESCRIBE prueba');
|
|
||||||
console.table(pruebaCols);
|
|
||||||
|
|
||||||
// Ver algunos detallecontrato
|
|
||||||
console.log('\n=== DETALLE CONTRATO (ejemplo) ===');
|
|
||||||
const [detalles] = await conn.query('SELECT * FROM detallecontrato LIMIT 5');
|
|
||||||
console.table(detalles);
|
|
||||||
|
|
||||||
// Ver banco de preguntas
|
|
||||||
console.log('\n=== BANCO DE PREGUNTAS (ejemplo) ===');
|
|
||||||
const [preguntas] = await conn.query('SELECT * FROM bancopreguntas LIMIT 5');
|
|
||||||
console.table(preguntas);
|
|
||||||
|
|
||||||
// Ver tipo_nota
|
|
||||||
console.log('\n=== TIPO NOTA ===');
|
|
||||||
const [tiposNota] = await conn.query('SELECT * FROM tiponota');
|
|
||||||
console.table(tiposNota);
|
|
||||||
|
|
||||||
await conn.end();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error:', err.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkMySQL();
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Script para limpiar tokens antiguos y forzar re-login
|
|
||||||
|
|
||||||
echo "=== Limpiando tokens antiguos de localStorage ==="
|
|
||||||
echo ""
|
|
||||||
echo "Por favor, ejecuta esto en la consola del navegador (F12 → Console):"
|
|
||||||
echo ""
|
|
||||||
echo "localStorage.removeItem('studio_token');"
|
|
||||||
echo "localStorage.removeItem('studio_user');"
|
|
||||||
echo "location.reload();"
|
|
||||||
echo ""
|
|
||||||
echo "Luego vuelve a hacer login con:"
|
|
||||||
echo " Email: juan.allende@gmail.com"
|
|
||||||
echo " Password: apoca11"
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
echo "=== DIAGNÓSTICO DE AUTENTICACIÓN ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# 1. Verificar que el backend acepta login
|
|
||||||
echo "1. Probando LOGIN directo al backend..."
|
|
||||||
RESPONSE=$(curl -s -X POST http://localhost:3001/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"email":"juan.allende@gmail.com","password":"password123"}')
|
|
||||||
|
|
||||||
TOKEN=$(echo $RESPONSE | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
|
|
||||||
|
|
||||||
if [ -z "$TOKEN" ]; then
|
|
||||||
echo "❌ ERROR: No se pudo obtener token del backend"
|
|
||||||
echo "Respuesta: $RESPONSE"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "✅ Token obtenido exitosamente"
|
|
||||||
echo "Token: ${TOKEN:0:50}..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "2. Probando acceso a /courses CON el token..."
|
|
||||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
||||||
-H "Authorization: Bearer $TOKEN" \
|
|
||||||
http://localhost:3001/courses)
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
||||||
echo "✅ Acceso a /courses exitoso (200)"
|
|
||||||
else
|
|
||||||
echo "❌ Acceso a /courses falló con código: $HTTP_CODE"
|
|
||||||
# Mostrar respuesta completa
|
|
||||||
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:3001/courses
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "3. Verificando JWT_SECRET en el contenedor..."
|
|
||||||
JWT_SECRET=$(docker exec openccb-studio-1 env | grep JWT_SECRET | cut -d'=' -f2)
|
|
||||||
echo "JWT_SECRET actual: $JWT_SECRET"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== INSTRUCCIONES ==="
|
|
||||||
echo "Si el test 2 fue exitoso, el problema está en el navegador."
|
|
||||||
echo "Ejecuta en la consola del navegador (F12):"
|
|
||||||
echo ""
|
|
||||||
echo " localStorage.clear();"
|
|
||||||
echo " location.reload();"
|
|
||||||
echo ""
|
|
||||||
echo "Luego vuelve a hacer login."
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Invalid credentials
|
|
||||||
Generated
-301
@@ -1,301 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "openccb",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"dependencies": {
|
|
||||||
"mysql2": "^3.20.0",
|
|
||||||
"pg": "^8.17.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/node": {
|
|
||||||
"version": "25.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz",
|
|
||||||
"integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"undici-types": "~7.18.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/aws-ssl-profiles": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/denque": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/generate-function": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-property": "^1.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/iconv-lite": {
|
|
||||||
"version": "0.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
|
|
||||||
"integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/express"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-property": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/long": {
|
|
||||||
"version": "5.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
|
||||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
|
||||||
"node_modules/lru.min": {
|
|
||||||
"version": "1.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz",
|
|
||||||
"integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"bun": ">=1.0.0",
|
|
||||||
"deno": ">=1.30.0",
|
|
||||||
"node": ">=8.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/wellwelwel"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mysql2": {
|
|
||||||
"version": "3.20.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.20.0.tgz",
|
|
||||||
"integrity": "sha512-eCLUs7BNbgA6nf/MZXsaBO1SfGs0LtLVrJD3WeWq+jPLDWkSufTD+aGMwykfUVPdZnblaUK1a8G/P63cl9FkKg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"aws-ssl-profiles": "^1.1.2",
|
|
||||||
"denque": "^2.1.0",
|
|
||||||
"generate-function": "^2.3.1",
|
|
||||||
"iconv-lite": "^0.7.2",
|
|
||||||
"long": "^5.3.2",
|
|
||||||
"lru.min": "^1.1.4",
|
|
||||||
"named-placeholders": "^1.1.6",
|
|
||||||
"sql-escaper": "^1.3.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/named-placeholders": {
|
|
||||||
"version": "1.1.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.6.tgz",
|
|
||||||
"integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"lru.min": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg": {
|
|
||||||
"version": "8.17.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.17.2.tgz",
|
|
||||||
"integrity": "sha512-vjbKdiBJRqzcYw1fNU5KuHyYvdJ1qpcQg1CeBrHFqV1pWgHeVR6j/+kX0E1AAXfyuLUGY1ICrN2ELKA/z2HWzw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"pg-connection-string": "^2.10.1",
|
|
||||||
"pg-pool": "^3.11.0",
|
|
||||||
"pg-protocol": "^1.11.0",
|
|
||||||
"pg-types": "2.2.0",
|
|
||||||
"pgpass": "1.0.5"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 16.0.0"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"pg-cloudflare": "^1.3.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"pg-native": ">=3.0.1"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"pg-native": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-cloudflare": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/pg-connection-string": {
|
|
||||||
"version": "2.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.10.1.tgz",
|
|
||||||
"integrity": "sha512-iNzslsoeSH2/gmDDKiyMqF64DATUCWj3YJ0wP14kqcsf2TUklwimd+66yYojKwZCA7h2yRNLGug71hCBA2a4sw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/pg-int8": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-pool": {
|
|
||||||
"version": "3.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz",
|
|
||||||
"integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peerDependencies": {
|
|
||||||
"pg": ">=8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-protocol": {
|
|
||||||
"version": "1.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz",
|
|
||||||
"integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/pg-types": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"pg-int8": "1.0.1",
|
|
||||||
"postgres-array": "~2.0.0",
|
|
||||||
"postgres-bytea": "~1.0.0",
|
|
||||||
"postgres-date": "~1.0.4",
|
|
||||||
"postgres-interval": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pgpass": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"split2": "^4.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-array": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-bytea": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-date": {
|
|
||||||
"version": "1.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
|
||||||
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-interval": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"xtend": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/safer-buffer": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/split2": {
|
|
||||||
"version": "4.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
|
||||||
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/sql-escaper": {
|
|
||||||
"version": "1.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.3.3.tgz",
|
|
||||||
"integrity": "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"bun": ">=1.0.0",
|
|
||||||
"deno": ">=2.0.0",
|
|
||||||
"node": ">=12.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/mysqljs/sql-escaper?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/undici-types": {
|
|
||||||
"version": "7.18.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
|
|
||||||
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/xtend": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"mysql2": "^3.20.0",
|
|
||||||
"pg": "^8.17.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,620 +0,0 @@
|
|||||||
Checking lms-service v0.1.0 (/home/juan/dev/openccb/services/lms-service)
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers.rs:154:22
|
|
||||||
|
|
|
||||||
154 | let categories = sqlx::query!(
|
|
||||||
| ______________________^
|
|
||||||
155 | | "SELECT id, name FROM grading_categories WHERE course_id = $1 ORDER BY name",
|
|
||||||
156 | | course_id
|
|
||||||
157 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers.rs:163:20
|
|
||||||
|
|
|
||||||
163 | let students = sqlx::query!(
|
|
||||||
| ____________________^
|
|
||||||
164 | | r#"
|
|
||||||
165 | | SELECT
|
|
||||||
166 | | u.id,
|
|
||||||
... |
|
|
||||||
180 | | org_ctx.id
|
|
||||||
181 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers.rs:193:27
|
|
||||||
|
|
|
||||||
193 | let detailed_grades = sqlx::query_as!(
|
|
||||||
| ___________________________^
|
|
||||||
194 | | UserCategoryGrade,
|
|
||||||
195 | | r#"
|
|
||||||
196 | | SELECT
|
|
||||||
... |
|
|
||||||
205 | | course_id
|
|
||||||
206 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers.rs:896:24
|
|
||||||
|
|
|
||||||
896 | let dependencies = sqlx::query_as!(
|
|
||||||
| ________________________^
|
|
||||||
897 | | LessonDependency,
|
|
||||||
898 | | r#"
|
|
||||||
899 | | SELECT ld.*
|
|
||||||
... |
|
|
||||||
905 | | id
|
|
||||||
906 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers.rs:1004:30
|
|
||||||
|
|
|
||||||
1004 | let unmet_dependencies = sqlx::query!(
|
|
||||||
| ______________________________^
|
|
||||||
1005 | | r#"
|
|
||||||
1006 | | SELECT ld.prerequisite_lesson_id, p.title as prereq_title, ld.min_score_percentage
|
|
||||||
1007 | | FROM lesson_dependencies ld
|
|
||||||
... |
|
|
||||||
1020 | | claims.sub
|
|
||||||
1021 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_announcements.rs:55:23
|
|
||||||
|
|
|
||||||
55 | let cohorts = sqlx::query!(
|
|
||||||
| _______________________^
|
|
||||||
56 | | "SELECT cohort_id FROM announcement_cohorts WHERE announcement_id = $1",
|
|
||||||
57 | | a.id
|
|
||||||
58 | | )
|
|
||||||
| |_________^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:21:46
|
|
||||||
|
|
|
||||||
21 | let existing: Option<CourseSubmission> = sqlx::query_as!(
|
|
||||||
| ______________________________________________^
|
|
||||||
22 | | CourseSubmission,
|
|
||||||
23 | | "SELECT * FROM course_submissions WHERE user_id = $1 AND lesson_id = $2",
|
|
||||||
24 | | claims.sub,
|
|
||||||
25 | | lesson_id
|
|
||||||
26 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:33:23
|
|
||||||
|
|
|
||||||
33 | let updated = sqlx::query_as!(
|
|
||||||
| _______________________^
|
|
||||||
34 | | CourseSubmission,
|
|
||||||
35 | | r#"
|
|
||||||
36 | | UPDATE course_submissions
|
|
||||||
... |
|
|
||||||
43 | | lesson_id
|
|
||||||
44 | | )
|
|
||||||
| |_________^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:53:22
|
|
||||||
|
|
|
||||||
53 | let submission = sqlx::query_as!(
|
|
||||||
| ______________________^
|
|
||||||
54 | | CourseSubmission,
|
|
||||||
55 | | r#"
|
|
||||||
56 | | INSERT INTO course_submissions (user_id, course_id, lesson_id, organization_id, content)
|
|
||||||
... |
|
|
||||||
64 | | payload.content
|
|
||||||
65 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:83:22
|
|
||||||
|
|
|
||||||
83 | let submission = sqlx::query_as!(
|
|
||||||
| ______________________^
|
|
||||||
84 | | CourseSubmission,
|
|
||||||
85 | | r#"
|
|
||||||
86 | | SELECT s.*
|
|
||||||
... |
|
|
||||||
105 | | org_ctx.id
|
|
||||||
106 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:122:22
|
|
||||||
|
|
|
||||||
122 | let submission = sqlx::query!(
|
|
||||||
| ______________________^
|
|
||||||
123 | | "SELECT user_id FROM course_submissions WHERE id = $1",
|
|
||||||
124 | | payload.submission_id
|
|
||||||
125 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:143:20
|
|
||||||
|
|
|
||||||
143 | let existing = sqlx::query!(
|
|
||||||
| ____________________^
|
|
||||||
144 | | "SELECT id FROM peer_reviews WHERE submission_id = $1 AND reviewer_id = $2",
|
|
||||||
145 | | payload.submission_id,
|
|
||||||
146 | | claims.sub
|
|
||||||
147 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:160:18
|
|
||||||
|
|
|
||||||
160 | let review = sqlx::query_as!(
|
|
||||||
| __________________^
|
|
||||||
161 | | PeerReview,
|
|
||||||
162 | | r#"
|
|
||||||
163 | | INSERT INTO peer_reviews (submission_id, reviewer_id, score, feedback, organization_id)
|
|
||||||
... |
|
|
||||||
171 | | org_ctx.id
|
|
||||||
172 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: error communicating with database: Connection refused (os error 111)
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:187:19
|
|
||||||
|
|
|
||||||
187 | let reviews = sqlx::query_as!(
|
|
||||||
| ___________________^
|
|
||||||
188 | | PeerReview,
|
|
||||||
189 | | r#"
|
|
||||||
190 | | SELECT pr.*
|
|
||||||
... |
|
|
||||||
196 | | lesson_id
|
|
||||||
197 | | )
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error[E0412]: cannot find type `AnalyticsFilter` in module `common::models`
|
|
||||||
--> services/lms-service/src/handlers.rs:1736:42
|
|
||||||
|
|
|
||||||
1736 | Query(filter): Query<common::models::AnalyticsFilter>,
|
|
||||||
| ^^^^^^^^^^^^^^^ not found in `common::models`
|
|
||||||
|
|
||||||
error[E0412]: cannot find type `RecommendationResponse` in this scope
|
|
||||||
--> services/lms-service/src/handlers.rs:1802:18
|
|
||||||
|
|
|
||||||
1802 | ) -> Result<Json<RecommendationResponse>, (StatusCode, String)> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
|
||||||
|
|
|
||||||
help: consider importing this struct
|
|
||||||
|
|
|
||||||
1 + use common::models::RecommendationResponse;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0412]: cannot find type `RecommendationResponse` in this scope
|
|
||||||
--> services/lms-service/src/handlers.rs:1945:22
|
|
||||||
|
|
|
||||||
1945 | let ai_response: RecommendationResponse = response
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
|
||||||
|
|
|
||||||
help: consider importing this struct
|
|
||||||
|
|
|
||||||
1 + use common::models::RecommendationResponse;
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0425]: cannot find function `dangerous_insecure_decode` in crate `jsonwebtoken`
|
|
||||||
--> services/lms-service/src/lti.rs:107:51
|
|
||||||
|
|
|
||||||
107 | let claims: serde_json::Value = jsonwebtoken::dangerous_insecure_decode(&payload.id_token)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `jsonwebtoken`
|
|
||||||
|
|
||||||
warning: unused imports: `SubmitAssignmentPayload` and `SubmitPeerReviewPayload`
|
|
||||||
--> services/lms-service/src/handlers.rs:12:44
|
|
||||||
|
|
|
||||||
12 | Module, Notification, Organization, SubmitAssignmentPayload, SubmitPeerReviewPayload, User, UserResponse,
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
|
|
||||||
|
|
||||||
warning: unused import: `crate::lti`
|
|
||||||
--> services/lms-service/src/handlers.rs:14:5
|
|
||||||
|
|
|
||||||
14 | use crate::lti;
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:154:22
|
|
||||||
|
|
|
||||||
154 | let categories = sqlx::query!(
|
|
||||||
| ______________________^
|
|
||||||
155 | | "SELECT id, name FROM grading_categories WHERE course_id = $1 ORDER BY name",
|
|
||||||
156 | | course_id
|
|
||||||
... |
|
|
||||||
159 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:160:15
|
|
||||||
|
|
|
||||||
160 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
160 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:163:20
|
|
||||||
|
|
|
||||||
163 | let students = sqlx::query!(
|
|
||||||
| ____________________^
|
|
||||||
164 | | r#"
|
|
||||||
165 | | SELECT
|
|
||||||
166 | | u.id,
|
|
||||||
... |
|
|
||||||
182 | | .fetch_all(&pool)
|
|
||||||
183 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:184:15
|
|
||||||
|
|
|
||||||
184 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
184 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:193:27
|
|
||||||
|
|
|
||||||
193 | let detailed_grades = sqlx::query_as!(
|
|
||||||
| ___________________________^
|
|
||||||
194 | | UserCategoryGrade,
|
|
||||||
195 | | r#"
|
|
||||||
196 | | SELECT
|
|
||||||
... |
|
|
||||||
207 | | .fetch_all(&pool)
|
|
||||||
208 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:209:15
|
|
||||||
|
|
|
||||||
209 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
209 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:896:24
|
|
||||||
|
|
|
||||||
896 | let dependencies = sqlx::query_as!(
|
|
||||||
| ________________________^
|
|
||||||
897 | | LessonDependency,
|
|
||||||
898 | | r#"
|
|
||||||
899 | | SELECT ld.*
|
|
||||||
... |
|
|
||||||
907 | | .fetch_all(&pool)
|
|
||||||
908 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:1004:30
|
|
||||||
|
|
|
||||||
1004 | let unmet_dependencies = sqlx::query!(
|
|
||||||
| ______________________________^
|
|
||||||
1005 | | r#"
|
|
||||||
1006 | | SELECT ld.prerequisite_lesson_id, p.title as prereq_title, ld.min_score_percentage
|
|
||||||
1007 | | FROM lesson_dependencies ld
|
|
||||||
... |
|
|
||||||
1022 | | .fetch_all(&pool)
|
|
||||||
1023 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `for<'r> DailyProgress: FromRow<'r, _>` is not satisfied
|
|
||||||
--> services/lms-service/src/handlers.rs:1461:49
|
|
||||||
|
|
|
||||||
1461 | let daily_completions = sqlx::query_as::<_, common::models::DailyProgress>(
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'r> FromRow<'r, _>` is not implemented for `DailyProgress`
|
|
||||||
|
|
|
||||||
= help: the following other types implement trait `FromRow<'r, R>`:
|
|
||||||
`()` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2)` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2, T3)` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2, T3, T4)` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2, T3, T4, T5)` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2, T3, T4, T5, T6)` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2, T3, T4, T5, T6, T7)` implements `FromRow<'r, R>`
|
|
||||||
`(T1, T2, T3, T4, T5, T6, T7, T8)` implements `FromRow<'r, R>`
|
|
||||||
and 58 others
|
|
||||||
note: required by a bound in `sqlx::query_as`
|
|
||||||
--> /home/juan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sqlx-core-0.8.6/src/query_as.rs:345:8
|
|
||||||
|
|
|
||||||
342 | pub fn query_as<'q, DB, O>(sql: &'q str) -> QueryAs<'q, DB, O, <DB as Database>::Arguments<'q>>
|
|
||||||
| -------- required by a bound in this function
|
|
||||||
...
|
|
||||||
345 | O: for<'r> FromRow<'r, DB::Row>,
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `query_as`
|
|
||||||
|
|
||||||
error[E0599]: the method `fetch_all` exists for struct `QueryAs<'_, Postgres, DailyProgress, PgArguments>`, but its trait bounds were not satisfied
|
|
||||||
--> services/lms-service/src/handlers.rs:1476:6
|
|
||||||
|
|
|
||||||
1461 | let daily_completions = sqlx::query_as::<_, common::models::DailyProgress>(
|
|
||||||
| _____________________________-
|
|
||||||
1462 | | r#"
|
|
||||||
1463 | | SELECT
|
|
||||||
1464 | | TO_CHAR(created_at, 'YYYY-MM-DD') as date,
|
|
||||||
... |
|
|
||||||
1475 | | .bind(org_ctx.id)
|
|
||||||
1476 | | .fetch_all(&pool)
|
|
||||||
| | -^^^^^^^^^ method cannot be called on `QueryAs<'_, Postgres, DailyProgress, PgArguments>` due to unsatisfied trait bounds
|
|
||||||
| |_____|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
::: /home/juan/dev/openccb/shared/common/src/models.rs:349:1
|
|
||||||
|
|
|
||||||
349 | pub struct DailyProgress {
|
|
||||||
| ------------------------ doesn't satisfy `DailyProgress: FromRow<'r, PgRow>`
|
|
||||||
|
|
|
||||||
= note: the following trait bounds were not satisfied:
|
|
||||||
`DailyProgress: FromRow<'r, PgRow>`
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers.rs:1461:29
|
|
||||||
|
|
|
||||||
1461 | let daily_completions = sqlx::query_as::<_, common::models::DailyProgress>(
|
|
||||||
| _____________________________^
|
|
||||||
1462 | | r#"
|
|
||||||
1463 | | SELECT
|
|
||||||
1464 | | TO_CHAR(created_at, 'YYYY-MM-DD') as date,
|
|
||||||
... |
|
|
||||||
1476 | | .fetch_all(&pool)
|
|
||||||
1477 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_announcements.rs:55:23
|
|
||||||
|
|
|
||||||
55 | let cohorts = sqlx::query!(
|
|
||||||
| _______________________^
|
|
||||||
56 | | "SELECT cohort_id FROM announcement_cohorts WHERE announcement_id = $1",
|
|
||||||
57 | | a.id
|
|
||||||
... |
|
|
||||||
60 | | .await
|
|
||||||
| |______________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_announcements.rs:61:19
|
|
||||||
|
|
|
||||||
61 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
61 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:21:46
|
|
||||||
|
|
|
||||||
21 | let existing: Option<CourseSubmission> = sqlx::query_as!(
|
|
||||||
| ______________________________________________^
|
|
||||||
22 | | CourseSubmission,
|
|
||||||
23 | | "SELECT * FROM course_submissions WHERE user_id = $1 AND lesson_id = $2",
|
|
||||||
24 | | claims.sub,
|
|
||||||
... |
|
|
||||||
27 | | .fetch_optional(&pool)
|
|
||||||
28 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:29:15
|
|
||||||
|
|
|
||||||
29 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
29 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:33:23
|
|
||||||
|
|
|
||||||
33 | let updated = sqlx::query_as!(
|
|
||||||
| _______________________^
|
|
||||||
34 | | CourseSubmission,
|
|
||||||
35 | | r#"
|
|
||||||
36 | | UPDATE course_submissions
|
|
||||||
... |
|
|
||||||
45 | | .fetch_one(&pool)
|
|
||||||
46 | | .await
|
|
||||||
| |______________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:47:19
|
|
||||||
|
|
|
||||||
47 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
47 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:53:22
|
|
||||||
|
|
|
||||||
53 | let submission = sqlx::query_as!(
|
|
||||||
| ______________________^
|
|
||||||
54 | | CourseSubmission,
|
|
||||||
55 | | r#"
|
|
||||||
56 | | INSERT INTO course_submissions (user_id, course_id, lesson_id, organization_id, content)
|
|
||||||
... |
|
|
||||||
66 | | .fetch_one(&pool)
|
|
||||||
67 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:68:15
|
|
||||||
|
|
|
||||||
68 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
68 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:83:22
|
|
||||||
|
|
|
||||||
83 | let submission = sqlx::query_as!(
|
|
||||||
| ______________________^
|
|
||||||
84 | | CourseSubmission,
|
|
||||||
85 | | r#"
|
|
||||||
86 | | SELECT s.*
|
|
||||||
... |
|
|
||||||
107 | | .fetch_optional(&pool)
|
|
||||||
108 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:109:15
|
|
||||||
|
|
|
||||||
109 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
109 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:122:22
|
|
||||||
|
|
|
||||||
122 | let submission = sqlx::query!(
|
|
||||||
| ______________________^
|
|
||||||
123 | | "SELECT user_id FROM course_submissions WHERE id = $1",
|
|
||||||
124 | | payload.submission_id
|
|
||||||
... |
|
|
||||||
127 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:128:15
|
|
||||||
|
|
|
||||||
128 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
128 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:143:20
|
|
||||||
|
|
|
||||||
143 | let existing = sqlx::query!(
|
|
||||||
| ____________________^
|
|
||||||
144 | | "SELECT id FROM peer_reviews WHERE submission_id = $1 AND reviewer_id = $2",
|
|
||||||
145 | | payload.submission_id,
|
|
||||||
146 | | claims.sub
|
|
||||||
147 | | )
|
|
||||||
148 | | .fetch_optional(&pool)
|
|
||||||
149 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:150:15
|
|
||||||
|
|
|
||||||
150 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
150 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:160:18
|
|
||||||
|
|
|
||||||
160 | let review = sqlx::query_as!(
|
|
||||||
| __________________^
|
|
||||||
161 | | PeerReview,
|
|
||||||
162 | | r#"
|
|
||||||
163 | | INSERT INTO peer_reviews (submission_id, reviewer_id, score, feedback, organization_id)
|
|
||||||
... |
|
|
||||||
173 | | .fetch_one(&pool)
|
|
||||||
174 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:175:15
|
|
||||||
|
|
|
||||||
175 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
175 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:187:19
|
|
||||||
|
|
|
||||||
187 | let reviews = sqlx::query_as!(
|
|
||||||
| ___________________^
|
|
||||||
188 | | PeerReview,
|
|
||||||
189 | | r#"
|
|
||||||
190 | | SELECT pr.*
|
|
||||||
... |
|
|
||||||
198 | | .fetch_all(&pool)
|
|
||||||
199 | | .await
|
|
||||||
| |__________^ cannot infer type
|
|
||||||
|
|
||||||
error[E0282]: type annotations needed
|
|
||||||
--> services/lms-service/src/handlers_peer_review.rs:200:15
|
|
||||||
|
|
|
||||||
200 | .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ^ - type must be known at this point
|
|
||||||
|
|
|
||||||
help: consider giving this closure parameter an explicit type
|
|
||||||
|
|
|
||||||
200 | .map_err(|e: /* Type */| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0282, E0412, E0425, E0599.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
warning: `lms-service` (bin "lms-service") generated 2 warnings
|
|
||||||
error: could not compile `lms-service` (bin "lms-service") due to 47 previous errors; 2 warnings emitted
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# 1. Verificar Login de Juan
|
|
||||||
echo "Probando Login para juan.allende@gmail.com..."
|
|
||||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:3001/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"email":"juan.allende@gmail.com","password":"password123"}')
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
||||||
echo "ÉXITO: El login funcionó para juan.allende@gmail.com con password123"
|
|
||||||
else
|
|
||||||
echo "FALLO: El login falló con estado $HTTP_CODE"
|
|
||||||
# Imprimir cuerpo para depuración
|
|
||||||
curl -s -X POST http://localhost:3001/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"email":"juan.allende@gmail.com","password":"password123"}'
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Verificar Contexto de Organización (Scoping de Cursos)
|
|
||||||
echo "Probando Scoping de Cursos por Organización..."
|
|
||||||
# Login para obtener token
|
|
||||||
USER_DATA=$(curl -s -X POST http://localhost:3001/auth/login \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"email":"juan.allende@gmail.com","password":"password123"}')
|
|
||||||
TOKEN=$(echo "$USER_DATA" | jq -r '.token')
|
|
||||||
ORG_ID=$(echo "$USER_DATA" | jq -r '.user.organization_id')
|
|
||||||
|
|
||||||
if [ "$TOKEN" != "null" ]; then
|
|
||||||
echo "ÉXITO: Se obtuvo el token para juan.allende@gmail.com"
|
|
||||||
# Intentar listar cursos
|
|
||||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET http://localhost:3001/courses \
|
|
||||||
-H "Authorization: Bearer $TOKEN")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
||||||
echo "ÉXITO: Cursos recuperados correctamente con scope de organización"
|
|
||||||
else
|
|
||||||
echo "FALLO: Error al recuperar cursos (Estado: $HTTP_CODE)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. Verificar Cambio de Contexto de Admin (X-Organization-Id)
|
|
||||||
# Crear una organización ficticia para probar el cambio
|
|
||||||
echo "Probando Cambio de Contexto de Admin (X-Organization-Id)..."
|
|
||||||
NEW_ORG_ID=$(curl -s -X POST http://localhost:3001/organizations \
|
|
||||||
-H "Authorization: Bearer $TOKEN" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"name": "Prueba de Cambio de Contexto"}' | jq -r '.id')
|
|
||||||
|
|
||||||
if [ "$NEW_ORG_ID" != "null" ]; then
|
|
||||||
echo "ÉXITO: Nueva organización creada ($NEW_ORG_ID)"
|
|
||||||
# Intentar listar cursos usando el nuevo contexto de org
|
|
||||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET http://localhost:3001/courses \
|
|
||||||
-H "Authorization: Bearer $TOKEN" \
|
|
||||||
-H "X-Organization-Id: $NEW_ORG_ID")
|
|
||||||
|
|
||||||
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
||||||
echo "ÉXITO: El cambio de contexto funcionó vía X-Organization-Id"
|
|
||||||
else
|
|
||||||
echo "FALLO: El cambio de contexto falló (Estado: $HTTP_CODE)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "FALLO: No se pudo crear la organización de prueba"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "FALLO: No se pudo obtener el token para probar el contexto de organización"
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user