Skip to content

feat(admin): dashboard gestione ruoli /admin + endpoint /me (#235 Fase 4) - #242

Merged
gzileni merged 1 commit into
mainfrom
feat/admin-dashboard-235
Jul 21, 2026
Merged

feat(admin): dashboard gestione ruoli /admin + endpoint /me (#235 Fase 4)#242
gzileni merged 1 commit into
mainfrom
feat/admin-dashboard-235

Conversation

@gzileni

@gzileni gzileni commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Fase 4: la dashboard admin che consuma l'API della Fase 2.

Backend

  • GET /me{ subject, email, role } (gated require_user): la UI conosce il ruolo dell'utente corrente per governare il link e la pagina admin, senza indovinare. Risolve/sincronizza il ruolo come require_role (dev-bypass → admin).

Frontend

  • /admin (dietro DashboardGate): elenco utenti da GET /admin/users, cambio ruolo via PATCH /admin/users/{id}/role con select (admin/regione/comune/cittadino). Gestisce 403 (accesso riservato) e i messaggi d'errore del backend (self-lockout, 404, 422).
  • useAuth().role: lib/auth.tsx fa un fetch best-effort di /me (in dev → admin); mai bloccante.
  • UserMenu: voce «🛡️ Amministrazione» mostrata solo se role === "admin".

Verifica

Backend 505 passed (+1 test /me); tsc pulito; next build static export 28 pagine (incl. /admin); next lint senza errori.

Il backend resta la fonte di verità dell'autorizzazione: la pagina è gated client-side e ogni endpoint /admin/* richiede require_admin.

Stato #235

✅ Fasi 1, 2, 3, 6, 4. Resta la Fase 5 (schermate registrazione SPID + email-OTP, configurazione Keycloak).

Parte di #235.

🤖 Generated with Claude Code

…Fase 4)

Backend:
- GET /me → { subject, email, role } (require_user), così la UI conosce il ruolo
  per governare il link admin e la pagina. resolve_role come require_role (dev→admin).

Frontend:
- app/admin/page.tsx: dashboard admin-only (dietro DashboardGate) — elenco utenti
  da GET /admin/users, cambio ruolo via PATCH con select (admin/regione/comune/
  cittadino), gestione 403 (accesso riservato) e messaggi errore (self-lockout ecc).
- lib/auth.tsx: useAuth espone  (fetch best-effort /me; in dev→admin).
- SiteHeader/UserMenu: voce «Amministrazione» solo se role==admin.

Backend 505 passed; tsc + next build (28 pagine, incl. /admin) + lint OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb6361c517

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +88 to +89
const res = await apiFetch("/me", { token });
if (res.ok) resolvedRole = ((await res.json())?.role as string) ?? null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid blocking auth readiness on /me

When a signed-in user's backend is slow or temporarily unreachable, this awaited role lookup keeps setState({ isLoaded: true, ... }) from running, so every <SignedIn>/<SignedOut> gate (including DashboardGate and the header) stays in its unloaded state until /me settles. Since the role fetch is described as best-effort, load the OIDC profile first and resolve role separately or with a timeout so a degraded admin-role check does not blank authenticated routes.

Useful? React with 👍 / 👎.

setError(null);
try {
const token = await getToken();
const res = await apiFetch("/admin/users", { token });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add pagination for the admin user list

In deployments with more than 100 users, this call only retrieves the backend's first default page (limit defaults to 100 in opendata_backend/routers/admin.py and supports offset), but the new dashboard presents the result as the complete user list with no way to advance pages. Older users therefore cannot be found or have their roles changed from this UI; pass explicit paging params and expose next/previous controls or fetch all pages intentionally.

Useful? React with 👍 / 👎.

@gzileni
gzileni merged commit 6b0732e into main Jul 21, 2026
27 checks passed
@gzileni
gzileni deleted the feat/admin-dashboard-235 branch July 21, 2026 14:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant