Separazione: le aree riservate diventano un'app propria (apps/platforms)

Campus, Stress Index e Longevity escono dal sito e diventano
apps.insanitylab.it, con utenti, sessioni, login e database propri.
Deciso da Adriano il 03/09/2026: una repo sola, due applicazioni
autosufficienti, cosi' che ognuna resti estraibile.

Misura che ha guidato il taglio: le tre aree condividevano col sito
SOLO l'identita' - ~170 righe fra auth.ts, middleware.ts e safe-next.ts.
Layout, librerie e dati erano gia' disgiunti.

Lato piattaforme:
- ruoli piattaforme/cliente/trainer/admin, senza quelli redazionali
- canAccessPath con default CHIUSO (nel sito era aperto: li' le rotte non
  elencate erano di chiunque fosse loggato, qui ogni sezione e' di qualcuno)
- tutta l'app protetta, si elencano le eccezioni invece dei prefissi protetti
- /api risponde 401/403, non un redirect verso una pagina di login
- tre database distinti: utenti, dati clinici senza nomi, mappatura coi nomi

Lato sito:
- ROLES tornano i tre redazionali; via le regole e il login pubblico
- il login del pannello RESPINGE un account emigrato invece di aprirgli una
  sessione: senza, landingFor lo mandava su /admin, il middleware glielo
  negava, e si formava un ciclo di redirect che sembra un guasto del sito
- l'header non mostra piu' un menu delle piattaforme: un link che esce

Verificato: sito 20 file / 146 test, piattaforme 26 file / 197 test, entrambi
i build passano, e l'app girata davvero in locale - il ruolo piattaforme entra
in Campus e viene rimbalzato da Longevity, il cliente il contrario.

Non ancora in produzione: manca il record DNS di apps.insanitylab.it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EndnceRA5WnA6rvA5iV9WL
This commit is contained in:
AdrianoDev
2026-09-03 11:21:12 +00:00
parent 510d7ca4ec
commit 6301f521fd
383 changed files with 8477 additions and 350 deletions
+5 -16
View File
@@ -1,6 +1,5 @@
---
import { site } from '../data/site';
import { piattaforme } from '../data/piattaforme';
import { t, contentImageUrl } from '../lib/content';
import { landingFor } from '../lib/auth';
interface Props {
@@ -10,11 +9,11 @@ interface Props {
}
const { user, canTags, showTags } = Astro.props;
const path = Astro.url.pathname;
const loginHref = `/login?next=${encodeURIComponent(path)}`;
// ⚠️ Le aree riservate (Campus, Stress Index, Longevity) dal 03/09/2026 NON sono in questo
// sito: vivono su apps.insanitylab.it, con utenti e sessioni propri. Qui resta un link che
// esce, non un menu — questo sito non sa più chi possa aprirle, ed è la separazione voluta.
const AREA_RISERVATA = 'https://apps.insanitylab.it';
const areaHref = user ? landingFor(user.role) : '/admin';
// Le piattaforme riservate compaiono nel menu solo a chi può davvero aprirle.
const canPiattaforme = user?.role === 'piattaforme' || user?.role === 'admin';
const inPiattaforme = piattaforme.some((p) => path === p.href || path.startsWith(`${p.href}/`));
---
<header class="hdr" id="site-header">
<div class="container hdr__in">
@@ -25,16 +24,6 @@ const inPiattaforme = piattaforme.some((p) => path === p.href || path.startsWith
<a href={item.href} class:list={['hdr__link', { 'is-active': path === item.href || (item.href !== '/' && path.startsWith(item.href)) }]}>{t(`global.nav.${i + 1}.label`)}</a>
)
))}
{canPiattaforme && (
<details class="plat">
<summary class:list={['hdr__link', 'hdr__link--bio', 'plat__btn', { 'is-active': inPiattaforme }]}>Piattaforme ▾</summary>
<div class="plat__panel">
{piattaforme.map((p) => (
<a href={p.href} class:list={['plat__item', { 'is-active': path === p.href || path.startsWith(`${p.href}/`) }]}>{p.label}</a>
))}
</div>
</details>
)}
</nav>
<div class="hdr__user">
{user ? (
@@ -49,7 +38,7 @@ const inPiattaforme = piattaforme.some((p) => path === p.href || path.startsWith
</div>
</details>
) : (
<a class="hdr__login" href={loginHref}>Accedi</a>
<a class="hdr__login" href={AREA_RISERVATA}>Area riservata</a>
)}
</div>
<button class="hdr__burger" id="nav-toggle" aria-label="Apri menu" aria-expanded="false">