Add scouthub-eventi-fe

This commit is contained in:
Lorenzo Sanesi
2026-07-25 12:03:40 +02:00
parent 08271b8a15
commit 6a55cfa991
56 changed files with 11742 additions and 0 deletions
+172
View File
@@ -0,0 +1,172 @@
# scouthub-eventi-fe
Frontend Angular per la gestione degli **eventi** Scouthub (calendario per branca, con
sotto-eventi a due livelli), affianca `scouthub-attivita-fe`, `scouthub-home-fe` e
`scouthub-magazzino-fe` nello stesso ecosistema. Parla con `scouthub-eventi-be` per le API e con
Keycloak per l'autenticazione.
Componenti standalone (nessun NgModule), routing con lazy loading per feature, Angular Material
per la UI.
## Stato del progetto
Le viste calendario (annuale, mensile) e il form di creazione/modifica evento sono implementati e
funzionanti. L'intera app è privata (richiede login): non esiste ancora una vista pubblica del
calendario.
## Struttura cartelle
```
src/app/
core/
auth/
keycloak.provider.ts provideKeycloakAngular() — login OIDC Authorization Code + PKCE
auth-context.ts extractAuthContext() — ruoli + branche ("groups") dal token
branca-access.ts hasBrancaAccess()/hasAnyBrancaAccess(), rispecchia assertBrancaAccess del BE
require-branca-access.guard.ts guard di routing per creazione/modifica evento
require-auth.guard.ts requireAuthGuard — richiede login, altrimenti avvia keycloak.login()
eventi-api.service.ts client HTTP verso GET/POST/PUT /eventi (dettaglio, crea, aggiorna)
utils/
colore-tipo.ts colore deterministico per "tipo" evento (hash su palette fissa)
nomi-mesi.ts nomi mesi in italiano per le viste calendario
vista-annuale/ feature "calendario annuale" (/vista-annuale, lazy-loaded)
vista-annuale-api.service.ts client verso GET /eventi?vista=anno
vista-mensile/ feature "calendario mensile" (/vista-mensile, lazy-loaded, home di default)
vista-mensile-api.service.ts client verso GET /eventi?vista=mese, filtro branca lato client
vista-evento/ feature "dettaglio/form evento" (/vista-evento, lazy-loaded)
evento-form/ form condiviso per crea/modifica/sotto-evento
src/environments/ environment.ts / environment.development.ts
public/
silent-check-sso.html richiesto dal flusso check-sso silenzioso di Keycloak
```
### Modulo di autenticazione
- **Login**: `provideKeycloak` (in `keycloak.provider.ts`) usa il client pubblico
`scouthub-frontend`**condiviso con tutti gli altri frontend** (`scouthub-attivita-fe`,
`scouthub-home-fe`, `scouthub-magazzino-fe`) — con Authorization Code Flow + PKCE,
`onLoad: 'check-sso'` e refresh automatico del token via `withAutoRefreshToken` (logout
automatico dopo 5 minuti di inattività).
- **requireAuthGuard** (`core/require-auth.guard.ts`): applicato sulla route radice in
`app.routes.ts`, protegge quindi tutte le sotto-route in un colpo solo (l'app non ha aree
pubbliche).
- **extractAuthContext** (`core/auth/auth-context.ts`): rispecchia lato client la stessa logica
di `verify-token.middleware.ts` sul backend — i ruoli sono `realm_access.roles` più i ruoli
sull'organizzazione attiva (claim `organization`), le branche vengono dal claim standard
`groups` (path tipo `/Lupetti`, normalizzati togliendo lo slash iniziale). Non esiste ancora un
claim branca dedicato.
- **hasBrancaAccess / hasAnyBrancaAccess** (`core/auth/branca-access.ts`): `capo-gruppo` ha
accesso in scrittura a qualunque branca dell'organizzazione; `capo-unita` solo alle branche a
cui appartiene. Usate solo per nascondere via routing gli entry point non pertinenti: **il
controllo autoritativo resta lato backend** (`assertBrancaAccess` su `POST`/`PUT /eventi`).
- Le chiamate verso `eventiApiBaseUrl` ricevono automaticamente l'header
`Authorization: Bearer <token>` tramite l'interceptor `includeBearerTokenInterceptor` di
`keycloak-angular`, condizionato via regex sull'URL base dell'API in `app.config.ts`.
### Feature `vista-mensile` (`/vista-mensile`, home di default)
Calendario del mese corrente/selezionato: carica **tutti** gli eventi del mese (radice e figli,
trasversali a tutte le branche) tramite `GET /eventi?vista=mese`, e filtra lato client per branca
tramite un select — così il filtro resta popolato con tutte le branche presenti nel mese anche
dopo aver selezionato una branca specifica.
### Feature `vista-annuale` (`/vista-annuale`)
Vista d'insieme dell'anno: per ogni giorno con almeno un evento radice, mostra un conteggio e
l'elenco sintetico (titolo/tipo/branca) tramite `GET /eventi?vista=anno`. Nessun dettaglio
descrizione/risorse in questa vista (aggregato leggero, coerente con quanto espone il backend).
### Feature `vista-evento` (`/vista-evento`)
- `/vista-evento/:id` — dettaglio completo di un evento, con i suoi eventuali figli (2° livello)
e le risorse collegate create da altri backend (`RisorsaCollegata`).
- `/vista-evento/nuovo` — crea un evento radice su una branca a scelta tra quelle dell'utente
(`requireCreaEventoGuard`, visibile solo a chi ha accesso ad almeno una branca).
- `/vista-evento/:id/modifica` — modifica un evento esistente (`requireBrancaAccessEventoGuard`,
carica prima l'evento per conoscerne la branca e poter decidere l'accesso).
- `/vista-evento/:id/sotto-evento` — crea un sotto-evento del padre `:id`; il form eredita
branca/vincoli di data dal genitore e blocca il campo branca. Non disponibile se `:id` è già
esso stesso un sotto-evento (massimo due livelli di annidamento, imposto anche lato backend).
Il form (`evento-form/`) valida che la data/ora di fine non preceda l'inizio e, in modalità
sotto-evento/modifica-di-un-figlio, vincola l'intervallo selezionabile a quello del genitore;
resta comunque il backend l'autorità finale su questi vincoli.
## Prerequisiti
- Node.js 20+
- I servizi dell'ecosistema Scouthub in esecuzione: Keycloak e `scouthub-eventi-be`
(vedi `docker-compose.yml` e `scouthub-eventi-be/README.md` nella root del repo)
## Configurazione ambiente
`src/environments/environment.ts` (produzione) e `environment.development.ts` (dev, usato
automaticamente da `ng serve`/`ng build --configuration development`) espongono:
- `keycloakBaseUrl` — URL base dell'istanza Keycloak (default `http://localhost:8081`, coerente
con `KEYCLOAK_PORT` in `.env` alla root del repo)
- `keycloakRealm` — realm Keycloak (`scouthub`)
- `keycloakClientId` — client pubblico condiviso già definito in `keycloak/realm-export.json`
(`scouthub-frontend`)
- `eventiApiBaseUrl` — URL base di `scouthub-eventi-be` (default `http://localhost:8084`)
## Collegare Keycloak in locale
1. Avviare Keycloak (e Postgres) dalla root del repo:
```bash
docker compose up -d keycloak-db keycloak
```
Il realm `scouthub` viene importato automaticamente da `keycloak/realm-export.json` al primo
avvio (`--import-realm`).
2. Il client pubblico `scouthub-frontend` ha `redirectUris`/`webOrigins` che includono anche
`http://localhost:4204` (porta di default di questo progetto, vedi sotto) — se si cambia porta,
aggiornare `keycloak/realm-export.json` di conseguenza e reimportare il realm (o aggiornarlo
da console admin Keycloak).
3. `provideKeycloakAngular()` (`src/app/core/auth/keycloak.provider.ts`) inizializza il client con
`onLoad: 'check-sso'`: all'avvio l'app verifica in un iframe nascosto se esiste già una sessione
Keycloak, senza forzare subito un redirect di login.
## Collegare scouthub-eventi-be in locale
1. Avviare `scouthub-eventi-be` seguendo il suo README (`npm run dev`, porta di default `8084`).
2. Le richieste verso `eventiApiBaseUrl` ricevono automaticamente l'header
`Authorization: Bearer <token>` tramite l'interceptor `includeBearerTokenInterceptor` di
`keycloak-angular`, configurato in `app.config.ts`.
## Development server
Questo progetto usa la porta `4204` (per non collidere con `scouthub-attivita-fe` sulla `4200`,
`scouthub-home-fe` sulla `4201` e `scouthub-magazzino-fe` sulla `4203`):
```bash
ng serve
```
Apri il browser su `http://localhost:4204/`.
## Build
```bash
ng build
```
Artefatti di build in `dist/scouthub-eventi-fe/browser` (percorso usato anche dal `Dockerfile`
multistage node→nginx).
## Test
```bash
ng test
```
Esegue gli unit test con il builder `@angular/build:unit-test` (Vitest).
## Versione Angular CLI usata per lo scaffold
```
Angular CLI : 22.0.7
Angular : 22.0.8
Node.js : 24.16.0
Package Manager : npm 11.12.0
Operating System : win32 x64
```