longevity: revisione finale - codice cliente non riusabile, ruoli allineati, middleware verificato
- creaCliente: il codice si deduce dal massimo fra identity E longevity (non piu' solo identity), cosi' un client_code cancellato dall'anagrafica non torna mai disponibile e non si attribuiscono le misure di un vecchio cliente a uno nuovo. Compensazione se la scrittura su longevity fallisce dopo quella su identity. - ROLES unica fonte in auth.ts (Role e isRole derivati); users.astro e users/new.astro usano quella lista invece di array scritti a mano che dimenticavano cliente/trainer. - Commento falso su cosa protegge il middleware, riscritto: rimanda a isProtectedPath. - vitest.config.ts: alias per astro:middleware (stesso bersaglio della pipeline vite di Astro), cosi' src/middleware.ts e' finalmente importabile e testabile in isolamento - prima nessun test lo caricava davvero. - export.test.ts: asserzione posizionale per colonna, non piu' solo intestazioni scritte a mano; intercetta un riordino della SELECT che disallinea etichette e valori. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import Admin from '../../layouts/Admin.astro';
|
||||
import { getDb } from '../../lib/db';
|
||||
import { listUsers } from '../../lib/auth';
|
||||
import { listUsers, ROLES } from '../../lib/auth';
|
||||
export const prerender = false;
|
||||
const users = listUsers(getDb());
|
||||
const me = Astro.locals.user!;
|
||||
@@ -45,7 +45,7 @@ const me = Astro.locals.user!;
|
||||
<td>{u.username}{u.id === me.id && ' (tu)'}</td>
|
||||
<td>
|
||||
<select class="role-sel arole" data-id={u.id} data-role={u.role} aria-label={`Ruolo di ${u.username}`}>
|
||||
{['user', 'superuser', 'piattaforme', 'admin'].map((r) => <option value={r} selected={u.role === r}>{r}</option>)}
|
||||
{ROLES.map((r) => <option value={r} selected={u.role === r}>{r}</option>)}
|
||||
</select>
|
||||
</td>
|
||||
<td class="uactions">
|
||||
|
||||
@@ -2,7 +2,19 @@
|
||||
// Creazione di un utente, su pagina propria come per gli articoli: l'elenco resta pulito e
|
||||
// il modulo ha spazio per le sue spiegazioni.
|
||||
import Admin from '../../../layouts/Admin.astro';
|
||||
import { ROLES } from '../../../lib/auth';
|
||||
export const prerender = false;
|
||||
|
||||
// Descrizioni solo per la UI: se un ruolo nuovo non è qui, compare comunque nella tendina
|
||||
// (fonte di validità unica: ROLES), semplicemente senza spiegazione accanto.
|
||||
const DESCRIZIONI: Partial<Record<(typeof ROLES)[number], string>> = {
|
||||
user: 'scrive i propri articoli',
|
||||
superuser: 'articoli e contenuti del sito',
|
||||
piattaforme: 'solo Campus e Stress Index',
|
||||
admin: 'accesso completo',
|
||||
cliente: 'solo il proprio fascicolo Longevity',
|
||||
trainer: 'gestionale Longevity',
|
||||
};
|
||||
---
|
||||
<Admin title="Nuovo utente">
|
||||
<h1>Nuovo utente</h1>
|
||||
@@ -17,10 +29,7 @@ export const prerender = false;
|
||||
|
||||
<label class="alabel" for="role">Ruolo</label>
|
||||
<select class="afield" id="role" name="role">
|
||||
<option value="user">user — scrive i propri articoli</option>
|
||||
<option value="superuser">superuser — articoli e contenuti del sito</option>
|
||||
<option value="piattaforme">piattaforme — solo Campus e Stress Index</option>
|
||||
<option value="admin">admin — accesso completo</option>
|
||||
{ROLES.map((r) => <option value={r}>{r}{DESCRIZIONI[r] ? ` — ${DESCRIZIONI[r]}` : ''}</option>)}
|
||||
</select>
|
||||
|
||||
<div class="aactions">
|
||||
|
||||
Reference in New Issue
Block a user