napi/CLAUDE.md

4.0 KiB

napi — Retroalimentación Personalizada a Estudiantes

Estado: PRODUCCIÓN — 2 grupos activos (2026-02-25)


Contexto

Proyecto minimalista para proporcionar retroalimentación personalizada a los estudiantes, cerrando el bucle profesor → alumno.

El profesor (Fénix) mantiene ficheros notas.md por alumno con:

  • Tabla resumen de todas las prácticas (nota + estado)
  • Feedback detallado por práctica
  • Próximos pasos concretos

Los alumnos acceden desde cualquier dispositivo con su navegador, sin instalar nada.

Sin backend. Sin base de datos. Sin framework. Sin CDN.


Grupos Activos

Grupo URL Alumnos Datos local Datos zzz
DDAW2 https://notas.qu3v3d0.tech 19 ~/napi-data/ /var/www/napi/data/
ASIR1 https://asir1.qu3v3d0.tech 21 ~/napi-data2/ /var/www/napi2/data/

Arquitectura

PROFESOR (aldebaran / anka4)         SERVIDOR (zzz / qu3v3d0.tech)
────────────────────────────         ─────────────────────────────
~/napi-data/   ←── sshfs ──→  /var/www/napi/data/   (DDAW2, 19 alumnos)
~/napi-data2/  ←── sshfs ──→  /var/www/napi2/data/  (ASIR1, 21 alumnos)

                                     /var/www/napi[2]/
                                       ├── viewer.html
                                       ├── marked.min.js
                                       └── twemoji.min.js

                                     Nginx + auth_pam → $remote_user
                                       → data/$remote_user/notas.md
                                       → viewer.html renderiza con marked.js

Stack

Componente Tecnología Dónde
Datos Ficheros notas.md (Markdown) zzz
Transporte sshfs mounts persistentes (systemd) aldebaran/anka4 → zzz
Servidor web Nginx (1 server block por grupo) zzz
Autenticación libnginx-mod-http-auth-pam zzz
Renderer marked.min.js + twemoji.min.js + viewer.html zzz
Notificaciones DDAW2 nginx-user-config-watcher.sh (v3) + XMPP zzz
Notificaciones ASIR1 python-upload-watcher.sh (v7) + XMPP zzz
SSL Certificado wildcard *.qu3v3d0.tech zzz

Alumnos

DDAW2 (19) — usernames = nombre de pila

anas, carlos, carlosv, daniel, danieln, erick, evelin, gianfranco,
giorgio, joel, jorge, josue, juanan, juanjesus, kasandra, marius,
miguel, pablo, patrick

SFTP chroot: /home/USER/html/

ASIR1 (21) — usernames = apellido en minúsculas

barja, barrios, cayo, contrera, duque, florea, gomes, izquierdo,
jara, lillo, linares, macedo, martinez, munoz, olcina, ponce,
posada, quiroz, reynoso, sierra, torrero

SFTP chroot: /home/USER/python/ · Contraseñas: leet-speak (a→4, e→3, i→1, o→0)


SSH / Conexión a zzz

ssh fenix@qu3v3d0.tech   # clave sin -i, fenix tiene sudo

Ficheros Clave

En zzz

Ruta Descripción
/var/www/napi/ App DDAW2 (viewer + marked + twemoji + data/)
/var/www/napi2/ App ASIR1 (idem)
/etc/nginx/sites-enabled/napi Server block DDAW2
/etc/nginx/sites-enabled/napi2 Server block ASIR1
/usr/local/bin/python-upload-watcher.sh Watcher ASIR1 (v7)
/usr/local/bin/nginx-user-config-watcher.sh Watcher DDAW2 (v3)
/usr/local/bin/xmpp-notify.py Bot XMPP one-shot

En aldebaran/anka4

Ruta Descripción
~/napi-data/ sshfs → DDAW2 data
~/napi-data2/ sshfs → ASIR1 data
~/.config/systemd/user/home-fenix-napi\x2ddata.mount Mount DDAW2
~/.config/systemd/user/home-fenix-napi\x2ddata2.mount Mount ASIR1

Pendiente

  • Renovar certificado SSL wildcard cuando expire (generado 2026-02-04, válido 365 días)