Spaces:
Configuration error
Configuration error
ποΈ ARQUITECTURA DEL SISTEMA - Osorno Runners
π Diagrama de Arquitectura
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HUGGINGFACE SPACES β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β βββββββββββββββ ββββββββββββββββ β β
β β β Gradio βββββββββββ€ app.py β β β
β β β Framework β β (Python) β β β
β β β β β β β β
β β β βββββββββ β β ββββββββββ β β β
β β β βServer β β β β APIs β β β β
β β β βPort β β β β REST β β β β
β β β β 7860 β β β ββββββββββ β β β
β β βββββββ¬ββββββ β ββββββββ¬ββββββββ β β
β β β β β β β
β β βΌ β βΌ β β
β β ββββββββββββββββ΄βββββββββββββββββββββββββββββ β β
β β β index.html (Frontend) β β β
β β β ββββββββββββββββββββββββββββββββββββββββ β β β
β β β β HTML5 + CSS3 + JavaScript β β β β
β β β β - Login Form β β β β
β β β β - Dashboard β β β β
β β β β - Training Plan Creator β β β β
β β β β - Plan List β β β β
β β β β - PDF Export (jsPDF) β β β β
β β β ββββββββββββββββββββββββββββββββββββββββ β β β
β β βββββββββββββββββββββββββββββββββββββββββββββ β β
β β β β β
β β βΌ β β
β β βββββββββββββββββββββββββββββββββββββββββββ β β
β β β SQLite Database (Persistent) β β β
β β β β β β
β β β ββββββββββββββββββ ββββββββββββββββββ β β β
β β β β Tabla: users β β Tabla: planes β β β β
β β β β - username β β - id β β β β
β β β β - password β β - plan_data β β β β
β β β β - role β β - created_at β β β β
β β β β - name β β - created_by β β β β
β β β ββββββββββββββββββ β - athlete_name β β β β
β β β β - distance β β β β
β β β β - race_date β β β β
β β β ββββββββββββββββββ β β β
β β β β β β
β β β Archivo: osorno_runners.db β β β
β β βββββββββββββββββββββββββββββββββββββββββββ β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β URL: https://huggingface.co/spaces/USUARIO/osorno-runners β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β HTTPS
βΌ
ββββββββββββββββββββ
β NAVEGADOR β
β DEL USUARIO β
β β
β Chrome/Firefox β
β Safari/Edge β
ββββββββββββββββββββ
π Flujo de Datos
1οΈβ£ Login
Usuario ingresa credenciales
β
βΌ
index.html (Frontend)
β
β POST /api/login
βΌ
app.py (Backend)
β
β authenticate_user()
βΌ
SQLite (users table)
β
β Return user data
βΌ
Frontend muestra dashboard
2οΈβ£ Crear Plan
Usuario completa formulario
β
βΌ
index.html valida datos
β
β Genera plan con algoritmos JS
βΌ
CΓ‘lculos de:
- DuraciΓ³n (calculateWeeks)
- Kilometraje (getBaseKm)
- Zonas FC (calculateHRZones)
- Sesiones (generateWeekSessions)
β
β POST /api/save_plan
βΌ
app.py (Backend)
β
β save_plan_to_db()
βΌ
SQLite (planes table)
β
β Return plan ID
βΌ
Frontend muestra confirmaciΓ³n
3οΈβ£ Ver Planes
Usuario navega a "Ver Planes"
β
β GET /api/get_plans
βΌ
app.py (Backend)
β
β get_all_plans(username, role)
βΌ
SQLite query segΓΊn permisos:
- User: WHERE created_by = username
- Admin: SELECT * FROM planes
β
β Return JSON con planes
βΌ
Frontend renderiza lista de planes
4οΈβ£ Exportar PDF
Usuario click en "Exportar PDF"
β
βΌ
Frontend (jsPDF library)
β
β Lee datos del plan
β Genera PDF en el navegador
βΌ
Descarga automΓ‘tica del PDF
(No involucra backend)
5οΈβ£ Eliminar Plan (Solo Admin)
Admin click en "Eliminar"
β
β ConfirmaciΓ³n
βΌ
index.html
β
β DELETE /api/delete_plan
βΌ
app.py (Backend)
β
β delete_plan_from_db(plan_id)
βΌ
SQLite elimina registro
β
β Return success
βΌ
Frontend recarga lista de planes
π Sistema de AutenticaciΓ³n
ββββββββββββββββββββββββββββββββββββββββββ
β authenticate_user() β
β β
β Input: username, password β
β β β
β βΌ β
β Query: SELECT role, name β
β FROM users β
β WHERE username = ? AND β
β password = ? β
β β β
β βΌ β
β βββββββββββ¬βββββββββββ β
β β Found? β β β
β βΌ YES βΌ NO β β
β Return: Return: β β
β { None β β
β username, β β
β role, β β
β name β β
β } β β
ββββββββββββββββββββββββββββββββββββββββββ
πΎ Modelo de Datos
Tabla: users
CREATE TABLE users (
username TEXT PRIMARY KEY, -- 'USER', 'ADMIN'
password TEXT NOT NULL, -- '123' (cambiar en prod)
role TEXT NOT NULL, -- 'user', 'admin'
name TEXT NOT NULL -- 'Usuario', 'Administrador'
);
Ejemplo de datos:
ββββββββββββ¬βββββββββββ¬ββββββββ¬ββββββββββββββββββ
β username β password β role β name β
ββββββββββββΌβββββββββββΌββββββββΌββββββββββββββββββ€
β USER β 123 β user β Usuario β
β ADMIN β 123 β admin β Administrador β
ββββββββββββ΄βββββββββββ΄ββββββββ΄ββββββββββββββββββ
Tabla: planes
CREATE TABLE planes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
plan_data TEXT NOT NULL, -- JSON del plan completo
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by TEXT NOT NULL, -- Username del creador
athlete_name TEXT NOT NULL, -- Nombre del atleta
distance TEXT NOT NULL, -- '5K', '10K', '21K', '42K'
race_date TEXT NOT NULL -- Fecha de la carrera
);
Ejemplo de plan_data (JSON):
{
"id": 1,
"userData": {
"name": "Rodrigo GarcΓ©s",
"age": 40,
"experience": "intermedio",
"weight": 75,
"height": 175,
"imc": 24.5,
"hrMax": 180,
"hrRest": 60,
"vo2max": 45,
"distance": "42K",
"targetPace": "4:30",
"raceDate": "2025-04-20",
"trainingDays": ["lunes", "miΓ©rcoles", "viernes", "domingo"]
},
"totalWeeks": 20,
"weeklyPlans": [
{
"week": 1,
"period": "basico",
"sessions": [...],
"totalKm": 35
},
...
]
}
π Ciclo de Vida de un Plan
1. CREACIΓN
ββ Usuario completa formulario
ββ JS valida datos
ββ Algoritmos generan plan
ββ POST a /api/save_plan
ββ Guarda en SQLite
2. ALMACENAMIENTO
ββ plan_data como JSON TEXT
ββ Metadata en columnas separadas
ββ Timestamp automΓ‘tico
3. RECUPERACIΓN
ββ GET a /api/get_plans
ββ Query segΓΊn role
ββ Parse JSON
ββ Return array de planes
4. VISUALIZACIΓN
ββ Frontend recibe JSON
ββ Renderiza HTML dinΓ‘mico
ββ Muestra detalles
5. EXPORTACIΓN
ββ jsPDF en cliente
ββ Sin backend
ββ PDF descargado
6. ELIMINACIΓN (Admin)
ββ DELETE a /api/delete_plan
ββ Remove de SQLite
ββ Refresh lista
π Endpoints de la API
POST /api/login
Request: {"username": "USER", "password": "123"}
Response: {"success": true, "user": {...}}
POST /api/save_plan
Request: {"plan": "{...}", "username": "ADMIN"}
Response: {"success": true, "id": 1}
GET /api/get_plans
Request: {"username": "USER", "role": "user"}
Response: {"success": true, "plans": [...]}
DELETE /api/delete_plan
Request: {"plan_id": 1}
Response: {"success": true}
π§ Stack TecnolΓ³gico
Frontend
- HTML5
- CSS3 (Variables CSS, Flexbox, Grid)
- JavaScript (ES6+)
- jsPDF 2.5.1
- Font Awesome 6.4.0
Backend
- Python 3.8+
- Gradio 4.44.0
- SQLite3 (Built-in)
Infraestructura
- HuggingFace Spaces
- CPU basic (2 vCPU, 16 GB RAM)
- 50 GB Storage
- HTTPS automΓ‘tico
π MΓ©tricas de Rendimiento
TamaΓ±o de archivos:
ββ app.py: 7.3 KB
ββ index.html: 17.0 KB
ββ requirements.txt: 0.015 KB
ββ Total: ~24.3 KB
Base de datos:
ββ VacΓa: ~20 KB
ββ 10 planes: ~100 KB
ββ 100 planes: ~1 MB
ββ LΓmite HF: 50 GB
Tiempos de respuesta:
ββ Login: ~100 ms
ββ Crear plan: ~200 ms
ββ Cargar planes: ~150 ms
ββ Exportar PDF: ~1-2 seg (cliente)
π‘οΈ Seguridad
Implementado β
- AutenticaciΓ³n de usuarios
- ValidaciΓ³n de formularios
- Manejo de errores
- Logs de actividad
- SeparaciΓ³n de permisos
Por Implementar π
- Hashing de contraseΓ±as (bcrypt)
- Tokens de sesiΓ³n (JWT)
- Rate limiting
- SanitizaciΓ³n de inputs
- HTTPS forzado (HF lo hace)
π Escalabilidad
LΓmites Actuales
- SQLite: ~140 TB teΓ³rico (prΓ‘ctico: GB)
- HuggingFace: 50 GB storage
- Concurrent users: ~100
- Request/min: Ilimitado en HF
Para Escalar
- Migrar a PostgreSQL
- Implementar Redis para cache
- CDN para assets
- Load balancing
- Microservicios
Esta arquitectura es ideal para:
- β Prototipo rΓ‘pido
- β MVP (Minimum Viable Product)
- β Equipos pequeΓ±os (< 50 usuarios)
- β Presupuesto cero
Para producciΓ³n enterprise, considerar:
- Migrar a AWS/GCP/Azure
- Base de datos dedicada
- Backups automΓ‘ticos
- Monitoreo 24/7
- CI/CD pipeline