20f7cf4003
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.1 KiB
5.1 KiB
Sezione Campus — design
Data: 2026-07-25 · Branch: feature/campus · Stato: approvato (approccio A)
Obiettivo
Integrare le guide di studio del corso Biohacking Campus (progetto esterno
/data/Sorgenti/AI-OS/projects/personale/biohacking-campus) come sezione
riservata del sito InsanityLab, visibile soltanto agli utenti autenticati con
un ruolo dedicato. Le pagine devono adottare lo stile grafico del sito
(font, colori, CSS globale), non quello del generatore statico originale.
Requisiti
- Nuovo ruolo
campus: vede soltanto la sezione/campus; nessun accesso al pannello admin.adminaccede a tutto.superusereusernon accedono alla sezione campus. - Generazione contenuti: uno script legge le guide sorgente
(
*.studio.md) dal progetto biohacking-campus e produce i contenuti nel repo del sito. Rigenerabile a ogni aggiornamento del corso. - Gestione utenti: la pagina
/admin/usersesistente deve permettere di creare/assegnare il ruolocampus. - Navigazione dedicata: dentro
/campusnon compaiono Header e Footer del sito; navigazione propria (sidebar aree/capitoli) più un solo richiamo "← Torna alla home" verso/. - Protezione totale: pagine e immagini (assets slide) mai servite a utenti non autorizzati.
Architettura
Ruoli e accessi (src/lib/auth.ts, src/middleware.ts)
Role = 'admin' | 'superuser' | 'user' | 'campus'.RULESesteso:/campus/*→['campus', 'admin'](admin passa sempre già oggi per short-circuit).- Middleware:
/campus/*diventa percorso protetto (oltre a/admin,/api/admin). Non autenticato → redirect a/admin/login. landingFor('campus')→/campus(dopo il login l'utente campus atterra direttamente sulla sezione).- Il ruolo
campusNON deve accedere ai percorsi comuni dei loggati del pannello (blog admin, upload):canAccessAdminPathritornafalsepercampussu/admin/*e/api/admin/*non esplicitamente consentiti. /admin/users: aggiunta optioncampusnelle due select (nuovo utente, cambio ruolo).
Sync contenuti (scripts/sync-campus.mjs)
- Input: root del progetto biohacking-campus (arg CLI, default il path locale di sviluppo).
- Porta la struttura dati del generatore Python (
CHAPTERS,AREAS, regex intestazioni) in JS. Legge i*.studio.mddastudio/,qa/,slide/,accelerator/,lezioni-live/,speaker/,consulenze/,masterclass/. - Converte markdown → HTML con
marked(nuova devDependency) e riscrive i riferimenti alle immagini slide verso/campus/assets/.... - Output in
campus-content/(root repo, committato):nav.json— aree, capitoli, lezioni ordinate (slug, titolo, sottotitolo, docente, prev/next);pages/<slug>.html— frammento HTML del corpo di ogni guida;assets/— immagini slide copiate (~37 MB, commit una tantum).
- Idempotente: rigenera tutto e rimuove i file orfani.
Rendering (src/pages/campus/, src/layouts/Campus.astro)
Campus.astro: usaglobal.csse i font del sito; nessunHeader/Footer; sidebar con aree/capitoli/lezioni (voce corrente evidenziata) e link "← Torna alla home"; responsive con menu mobile.- Route SSR (runtime, non prerender — servono i file in
campus-content/):/campus— portale con le card delle aree (danav.json);/campus/[...slug]— pagina area (indice capitoli) o pagina guida (frammento HTML + breadcrumb + prev/next). Slug non trovato → 404.
/campus/assets/[...path]— endpoint che serve le immagini dacampus-content/assets/(protetto dal middleware come tutto/campus); path traversal rifiutato;Content-Typeda estensione; cache privata.- Lettura file a runtime da
CAMPUS_DIR(env, default./campus-content), con cache in memoria dinav.json.
Deploy (Dockerfile)
- Lo stage runtime copia solo
distescripts; si aggiungeCOPY --from=build /app/campus-content ./campus-content. /app/datae/app/uploadssono volumi:campus-content/resta fuori da entrambi, dentro l'immagine. Nessuna modifica acompose.yaml.
Error handling
campus-content/assente (sync mai eseguito):/campusrisponde 404 con messaggio esplicito nei log; il resto del sito non è impattato.- Slug o asset inesistente → 404. Path traversal su assets → 400.
- Sync: file
.studio.mdcon intestazione non riconosciuta → warning e skip, exit code ≠ 0 solo per errori I/O.
Testing
tests/auth-campus.test.ts: matrice ruoli × percorsi (campussu/campussì, su/admin/contentno;usersu/campusno; ecc.),landingFor,isRole('campus').tests/sync-campus.test.ts: parsing intestazioni (lezione, Q&A, slide, accelerator, consulenza, masterclass, speaker), generazione nav e frammenti su fixture minima, riscrittura path immagini.- Verifica manuale: login con utente
campus(vede solo campus),user(non vede campus), navigazione sidebar, immagini slide, mobile.
Fuori scope
- Nessun tracciamento progressi/completamento lezioni.
- Nessuna ricerca full-text.
- Nessuna migrazione automatica degli utenti esistenti al nuovo ruolo.