# GTIBANPOS — Piattaforma di acquiring IBANWAY

> Documentazione tecnica di progetto e registro dei rilasci.
> Versione corrente: **v1.5.0** (2026-06-09). Il changelog completo è in fondo a questo file e nella pagina **Registro Release** (Impostazioni) del back-office GTPOS.
>
> **Ecosistema a 2 app mobile**: **IBANPOS** (SoftPOS esercente, incassa) e **PagoIBAN** (app PSU/pagatore, paga via QR conto-a-conto). Entrambe Flutter, distribuite da GTPOS.

---

## ⛔ STACK TECNOLOGICO — REGOLE NON NEGOZIABILI (leggere PRIMA di scrivere codice)

**Questo progetto è in JavaScript puro: Express + mysql2 (query SQL grezze). NON è NestJS, NON è TypeORM.**
Ogni prompt o spec che assume uno stack diverso (NestJS, TypeORM, Prisma, decoratori, `src/modules/`, migration TypeORM, entity) va **adattato a questo stack reale**. Non introdurre nuovi framework.

| Ambito | ✅ USARE (reale) | ❌ NON usare |
|---|---|---|
| Linguaggio backend | **JavaScript** (CommonJS, `require`) | TypeScript, decoratori |
| Framework | **Express** (`express.Router()`) | NestJS, Fastify, moduli `@Module` |
| DB access | **mysql2** con **SQL grezzo** (`db.query('SELECT …', [params])`) | TypeORM, Prisma, entity, repository |
| Migrazioni / schema | **`api/routes/admin.js` → `POST /api/v1/admin/setup-db`** (array `STATEMENTS` con `CREATE TABLE IF NOT EXISTS` + `TOLLERANTI` con `ALTER … ADD COLUMN`, idempotenti) | migration TypeORM, `typeorm_migrations`, CLI migrations |
| Struttura route | file in **`api/routes/*.js`** (un Router Express per area) | `src/modules/<x>/<x>.controller.ts`, DI, providers |
| Auth | **`jsonwebtoken`** + `api/middleware/auth.js` (`authMiddleware`, `rbac`, `can`) · password con **`bcryptjs`** | Passport, guards NestJS |
| Front-office | **HTML statico** servito da Express (`backoffice.html`, `pos.html`, `softpos.html`) + design system **`iw.css`**; SPA via funzione `goTo()` | React/Vue, build Vite/Webpack, JSX |
| App mobile | **Flutter/Dart** (progetto `IBANPOS`/PagoIBAN) | React Native |
| Storage file | **`storage_path`** locale / ownCloud | S3 / presigned URL (non configurato) |
| Importi | **centesimi** (`BIGINT`) | float/decimal in euro |
| Deploy | **git push → Hostinger auto-deploy** (Node app); poi `setup-db` se cambia lo schema | Docker, CI/CD pipeline, build step |

**Pattern obbligatori del progetto:**
- Nuova tabella/colonna → si aggiunge agli array di `admin.js` (`STATEMENTS`/`TOLLERANTI`), **mai** una migration TypeORM.
- Nuovo endpoint → nuovo file in `api/routes/` registrato in `index.js` con `app.use('/api/v1/<x>', require('./api/routes/<x>'))`.
- Niente `import`/`export` ES module: solo `require()` / `module.exports`.
- `DB_HOST=127.0.0.1` (IPv4, non `localhost`).

> Riferimento completo nella sezione **2. Stack tecnologico** qui sotto.

---

## 1. Panoramica

**GTIBANPOS** è la piattaforma di **POS acquiring** di **IBANWAY S.p.A.**. Gestisce l'intera filiera dell'accettazione pagamenti: anagrafiche commerciali (CRM), gerarchia dei punti di accettazione (POS), un **SoftPOS Account-to-Account** basato su **PIS / Open Banking** con relativa **app Android (IBANPOS)**, e un'area di **monitoraggio real-time** con **certificati di sicurezza** e **crittografia dei dati**.

- **Produzione:** https://ibanway.net (hosting **Hostinger**)
- **Repository:** GitHub `mdmhitaly/ibanway-poc` (branch `main`)
- **Deploy:** manuale da pannello Hostinger ("Salva e ridistribuisci")

### Cos'è il SoftPOS A2A
IBANPOS **non** è un POS a carte. È un **PIS (Payment Initiation Service)** che inizia bonifici **SCT Inst** conto-a-conto tramite **Open Banking**:
il POS mostra un **QR** (formato **EPC069-12 SEPA** + deeplink dell'app **Vuolli PagoIBAN**); il cliente lo inquadra con la propria app bancaria/Vuolli e autorizza il pagamento. L'accettazione carte (VISA/MC/AMEX) è un'app separata — nel SoftPOS è previsto solo un **tasto placeholder "Carte"**.

Catena di pagamento (gli ultimi due nodi sono **simulati** in questa fase):
```
SoftPOS IBANPOS → GTPOS → OKSA (IBANWAY) → Fabrick → SCT Inst
                              └── simulati ──┘
```

---

## 2. Stack tecnologico e requisiti

| Ambito | Tecnologia |
|---|---|
| Backend | **Node.js + Express** (JavaScript, **non** TypeScript/NestJS — vincolo di progetto) |
| Database | **MySQL** via **mysql2** (query raw `db.query`) |
| Auth | **JWT** (`authMiddleware`), RBAC (`rbac`), password con **bcryptjs** |
| Protocollo bancario | **ISO 8583 CB2** (builder / parser / mac / fields-cb2) — gestito da GTPOS |
| Crittografia | **AES-256-GCM** (at-rest), **TLS 1.2+** (in transito), **JWT HS256** (token), **HMAC-SHA256** (MAC ISO 8583 DE64) |
| Front-end | HTML statico servito da Express + **design system IBANWAY** (`iw.css`) |
| App mobile | **Flutter / Dart** (Android: smartphone e POS Android) |
| QR SEPA | **EPC069-12** + deeplink Vuolli PagoIBAN |
| Open Banking | **PIS / SCT Inst**, connettori **OKSA / Fabrick** (simulati) |
| Deploy | **Hostinger** (Node app), GitHub come sorgente |

### Design system IBANWAY (`iw.css`)
- Colori: navy `#2B2E4A`, rosso `#E31E24`, superfici chiare.
- Font: **Jost** (display), **Inter** (testo), **JetBrains Mono** (monospace).
- Icone: **SVG piatte monocrome** stile Lucide (no emoji, no icone a colori) su **tutto** il progetto.
- Token CSS: `--iw-navy`, `--iw-red`, `--bg`, `--fg`, `--fg-muted`, `--font-display`, `--font-mono`…
- Classi: `iw-app`, `iw-sidebar`, `iw-card`, `iw-kpi`, `iw-badge`, `iw-btn`, `bo-page` (routing SPA via `goTo`).

### App Flutter — pacchetti
`dio` (HTTP + certificate pinning), `flutter_secure_storage` (Android Keystore), `qr_flutter`, `local_auth` (biometria), `safe_device` (root detection), `provider`, `intl`, `crypto`.
Config build: `compileSdk = 36`, `targetSdk = 34`, Java/Kotlin 17. Progetto locale in `C:\IBANPOS-flutter`.

---

## 3. Struttura del repository

```
ibanway-poc/
├── index.js                      # Entry Express: middleware, registrazione route, logging, static
├── api/
│   ├── db/connection.js          # Pool mysql2
│   ├── routes/
│   │   ├── admin.js              # /admin/setup-db, /admin/sync-staff (utenti→persone dipendenti)
│   │   ├── auth.js              # login/refresh + /auth/me (GET/PUT profilo), /auth/password
│   │   ├── ruoli.js            # Ruoli & Permessi: catalog, CRUD ruoli, matrice (admin)
│   │   ├── utenti.js          # Elenco utenti + assegnazione ruolo (admin)
│   │   ├── softpos.js           # pairing, activate (emette certificato), heartbeat, config, cert
│   │   ├── pis.js               # A2A PIS: initiate, status, simulate-pay, balance, refund
│   │   ├── monitor.js           # devices, activity, stats, volume, certificates, security, revoke
│   │   ├── merchant.js          # CRM aziende/merchant
│   │   ├── crm/…                # anagrafiche, documenti
│   │   ├── pos/…                # punti-vendita, casse, batch
│   │   └── psu/                 # PagoIBAN PSU: auth, profile, conti, pagamenti, backoffice
│   ├── middleware/
│   │   ├── auth.js             # authMiddleware, rbac, can (utenti back-office)
│   │   └── psuAuth.js          # autenticazione PSU (JWT con secret dedicato)
│   └── services/
│       ├── permessi.js          # Unica fonte di verità: MODULI, AZIONI, ruoli default + can()
│       ├── certificates.js      # issue / renew / verify certificati device (JWT)
│       ├── crypto.js            # AES-256-GCM encrypt/decrypt, maskPan, status()
│       ├── trust.js             # Device Trust: computeTrust / saveDeviceTrust
│       ├── psu.js               # PagoIBAN: token PSU, codici, IBAN mod-97
│       └── oksa.js              # connettore OKSA/Fabrick SIMULATO (initiate, status, balance)
├── backoffice.html               # Back-office GTPOS (SPA, design IBANWAY)
├── pos.html · softpos.html · index.html
├── downloads/
│   ├── app-info.json · ibanpos-latest.apk        # APK IBANPOS (SoftPOS)
│   └── pagoiban-info.json · pagoiban-latest.apk   # APK PagoIBAN (PSU)
├── iw.css, pos-data.js, it-banks.js, favicon.svg
├── SoftIBANPOS.md · TRUST.md      # Doc app SoftPOS · modello device trust
└── CLAUDE.md                     # Questo file

# App Flutter (progetti separati, non nel repo Git):
#   C:\IBANPOS-flutter      → app SoftPOS esercente (IBANPOS)
#   C:\PagoIBAN-flutter     → app pagatore PSU (PagoIBAN)
```

---

## 4. Moduli

### 4.1 CRM
- **Merchant**: anagrafica (ragione sociale, insegna, P.IVA/CF, indirizzi/sedi), conti bancari, legali rappresentanti.
- **Persone**: documento **CIE** (Carta d'Identità Elettronica) con data di rilascio, residenza con **cascata Provincia/Città**, PEC, email, **cellulare con prefisso internazionale a tendina**.
- **Legami bidirezionali Azienda↔Persona** con assegnazione **ruolo**.
- **Conto di accredito**: mostra dettagli banca completi (Banca, ABI, CAB, BIC) e logo istituto (favicon Google `s2/favicons?domain=…`).
- Validatori italiani (CF / P.IVA mod-11 / IBAN) **non bloccanti** (solo warning).

### 4.2 Gerarchia GT POS
`Istituto → Merchant → Punto Vendita → Cassa → Terminale → Transazione`.

### 4.3 SoftPOS A2A (IBANPOS)
- Display: **IBAN mascherato** (ABI/CAB visibili, cifre centrali con asterischi, ultime 5 visibili), QR EPC+Vuolli, saldi **riservati all'operatore** (mai sul display lato cliente).
- Endpoint `pis.js`: `POST /initiate` (genera payment_id, QR EPC, deeplink Vuolli, IBAN mascherato), `GET /:id/status`, `POST /:id/simulate-pay` (test → crea record `transazioni` con `circuito='a2a'`), `GET /balance`, `POST /:id/refund`.
- `oksa.js` (simulato): `initiatePayment`, `getPaymentStatus`, `getBalance(iban)` (saldo pseudo-stabile da sha256 dell'IBAN).

### 4.4 App Android Flutter (SoftIBANPOS / IBANPOS)
Schermate: attivazione (codice pairing), operatore, terminale, QR pagamento, storico, saldo, scontrino.
Sicurezza: Keystore, biometria, root detection, certificate pinning. Attivazione manuale via codice (scanner QR rimosso per compatibilità SDK).
Distribuzione: scaricabile da GTPOS (`/downloads`, `app-info.json`).
**Doc dedicata**: `SoftIBANPOS.md` (sviluppo software dell'app) + pagina back-office **Impostazioni → App SoftIBANPOS** con changelog e funzionalità dell'app.

### 4.5 Monitor GTPOS (real-time)
`monitor.js`: `GET /devices` (online se heartbeat < 5 min), `/activity` (feed da `api_log`), `/stats`, `/volume?by=ora|banca|area`, `/certificates`, `/security`, `POST /certificates/:id/revoke` (sospende anche il terminale).
Front-end: polling 4s, KPI live, volume per orario/banca/area geografica.

### 4.6 Sicurezza
- **Certificati device** (`certificates.js`): emessi all'attivazione (`issue({tid,merchantId,deviceId})` → serial `CRT-…`, fingerprint sha256, **JWT firmato 30 giorni**), revoca dei precedenti, **rinnovo** con counter. Rotazione periodica.
- **Crittografia** (`crypto.js`): AES-256-GCM con chiave da env `AES_MASTER_KEY` (hex 32 byte); `status()` espone algoritmi at-rest/in-transit/token/MAC.

### 4.7 Ruoli & Permessi (controllo accessi)
- **Unica fonte di verità** (`permessi.js`): **13 moduli × 12 azioni = 156 permessi**. Azioni: vedi, leggi, crea, scrivi, modifica, elimina, gestisci, configura, invia, sync, esporta, admin.
- **Livelli** L1–L6: L1–L2 ruoli di sistema (`fisso`), L3–L6 configurabili. Ruoli default: **Super Admin** (000, accesso totale, sola lettura), **Admin** (001), **Responsabile** (002), **Operatore** (003).
- **Schema**: `ruoli` (codice, livello, tipo, fisso, accesso_totale, sola_lettura), `ruolo_permessi` (righe `ruolo_id+modulo+azione`). `utenti.ruolo_id` affianca il campo legacy `ruolo` (transizione non-breaking).
- **API** (`ruoli.js`, admin): `GET /catalog`, `GET/POST/PUT/DELETE /ruoli`, `PUT /:id/permessi` (replace transazionale; bloccato su accesso_totale/sola_lettura). `utenti.js`: `GET /`, `PUT /:id/ruolo`.
- **UI**: Impostazioni → Ruoli & Accessi (card + matrice) e Utenti (assegna ruolo).
- **Enforcement (Fase 4, attivo)**: `getUserPermessi()` risolve i permessi effettivi; il middleware `can(modulo, azione)` protegge gli endpoint (applicato a **Ruoli** e **Utenti**; estensione agli altri moduli incrementale). `/auth/me` espone i permessi e il menu UI nasconde le sezioni senza `vedi`. **Rete anti-lockout**: ruolo legacy `admin` e ruoli ad `accesso_totale` passano sempre.

### 4.8 Utenti come Persone-dipendenti + Profilo
- **Ogni Utente è una Persona** (`persons.utente_id`) e **dipendente di IBANWAY** (`istituto` id=1) via `persons.datore_lavoro_id` + `tipo_rapporto='dipendente'`. Backfill: `POST /admin/sync-staff` (idempotente).
- **Profilo self-service** (`/auth/me` GET/PUT, `/auth/password`): l'utente aggiorna i contatti personali (email, PEC, cellulare, residenza) e la password; i dati anagrafici sono read-only (gestiti dall'admin). UI: menu utente in topbar → "Il mio profilo".

### 4.10 Device Trust (affidabilità dispositivo SoftPOS)
- L'app IBANPOS invia un **pacchetto di segnali** (binding, tamper, integrità, rete) all'attivazione e nei heartbeat. `trust.js` calcola un **punteggio 0–100** (alto/medio/basso) con motivazioni.
- **Schema**: `device_trust` (per `tid`). Segnali: android_id, fingerprint, root/emulatore, dev mode, StrongBox, lock screen, biometria, network/VPN, Play Integrity.
- **API** (`softpos.js`): `/activate` e `/heartbeat` accettano `device`; `GET /softpos/device/:tid/trust`; `/softpos/devices` espone trust_level/score. **UI**: colonna Trust nella lista SoftPOS → scheda completa. Doc: `TRUST.md`.

### 4.11 PagoIBAN — PSU (Payment Service User) — backend
Modulo per gli **utenti pagatori** che pagano conto-a-conto via QR (l'app PagoIBAN scansiona il QR generato dal SoftPOS/merchant).
- **6 tabelle**: `psu` (anagrafica + KYC + auth), `psu_documents`, `psu_conti` (saldi via AIS simulato), `psu_dispositivi`, `psu_sessions`, `psu_pagamenti`.
- **JWT dedicato** (`psuAuth.js`, secret `PSU_JWT_SECRET` con fallback): un token PSU non autentica come utente back-office.
- **API** (`api/routes/psu/`): `auth` (register/login/refresh/logout + dispositivi), `profile`, `conti` (CRUD + refresh-saldo), **`pagamenti`** (`scan` risolve `pis_payments`, **`autorizza`** = transazione atomica: controllo saldo/limite → `pis_payments`→paid → transazione A2A → `psu_pagamenti` → decremento saldo), `backoffice` (lista/dettaglio PSU, **CRUD**, approva KYC, stato).
- **UI back-office**: **PagoIBAN → Utenti PSU** (lista, filtri, scheda, crea/modifica/elimina, KYC, stato) + card download App PagoIBAN.
- Importi in **centesimi**. Riusa `pis_payments` (QR) e `oksa` (saldi).

### 4.12 App Flutter PagoIBAN (pagatore)
Progetto `C:\PagoIBAN-flutter` (separato dal repo). **Design System IBANWAY rosso+navy**, font Jost/Inter/JetBrains Mono, **Riverpod + go_router + Repository**, secure storage, Dio (refresh token).
- **11 schermate**: Login, Registrazione (1/2), Home (hero saldo, conti, ultimi pagamenti), Conti, Aggiungi conto (IBAN mod-97), Storico, Profilo, **Scan QR** (`mobile_scanner`), **Conferma** (selettore conti, timer, **biometria**), Esito, KYC, Dispositivi.
- **Sicurezza**: biometria su ogni pagamento, auto-logout 5 min, FLAG_SECURE, root detection, obfuscation.
- **Mock mode** (`API_BASE_URL` vuoto → dati demo) o **backend reale** GTPOS. Distribuzione: GTPOS → PagoIBAN → Utenti PSU (`/api/v1/psu/app-info`, `/downloads/pagoiban-latest.apk`).

### 4.9 Menu del back-office
`Panoramica` (Dashboard, Monitor) · **CRM** (Persone, Aziende) · **GTPOS** (Terminali, Transazioni, ISO 8583) · **PagoIBAN** (Utenti PSU) · `Sistema` (SoftPOS, VirtualPOS) · **Impostazioni** (Utenti, Ruoli & Accessi, Registro Release, App SoftIBANPOS).

---

## 5. Deploy & operazioni

### 5.1 Rilascio
1. Commit + push su `main` (GitHub).
2. Hostinger → **"Salva e ridistribuisci"** (riavvia il processo Node).
3. Se ci sono nuove tabelle/colonne: chiamare **`POST /api/v1/admin/setup-db`** (header Authorization Bearer) per creare/migrare lo schema.

### 5.2 Variabili d'ambiente (Hostinger)
| Var | Note |
|---|---|
| `DB_HOST` | **`127.0.0.1`** (IPv4 — *non* `localhost`/`::1`) |
| `DB_USER` / `DB_PASSWORD` / `DB_NAME` | credenziali MySQL |
| `AES_MASTER_KEY` | hex 32 byte per AES-256-GCM |
| `JWT_SECRET` | firma token |

### 5.3 setup-db
`admin.js` esegue due array:
- **STATEMENTS** — `CREATE TABLE` obbligatorie (incl. `api_log`, `softpos_certificates`, `pis_payments`, `softpos_pairing`).
- **TOLLERANTI** — `ALTER TABLE … ADD/MODIFY COLUMN` che ignorano "Duplicate column" (migrazioni idempotenti).

---

## 6. Convenzioni e lezioni apprese (gotcha)

- **Tecnologia immutabile:** Express + mysql2, **no** NestJS/TypeScript.
- **`DB_HOST=127.0.0.1`**: `localhost` risolve in `::1` (IPv6) e fallisce.
- **Pattern "codice giusto, DB/deploy non aggiornato":** verificare **sempre** via PowerShell/Chrome prima di dichiarare fatto; usare `setup-db` per allineare lo schema.
- **Regex inline in JS:** attenzione a `//` — `//(...)/` viene letto come **commento** e può rompere l'`if` (causa del 503 risolto in v1.0.0). Preferire `/(...)/`.
- **Logo banche:** Clearbit deprecato → usare `https://www.google.com/s2/favicons?domain=…&sz=64`.
- **Flutter su drive cloud (pCloud `P:`):** i build falliscono per lock sui file → lavorare in `C:\IBANPOS-flutter`.
- **`safe_device`:** API cambiata, `canMockLocation` rimosso.
- **Validatori IT:** non bloccanti (solo warning) per non impedire i salvataggi.

---

## 7. Versionamento

Versionamento semantico **MAJOR.MINOR.PATCH**:
- **MAJOR** — cambi incompatibili / riarchitetture.
- **MINOR** — nuove funzionalità retrocompatibili.
- **PATCH** — bugfix retrocompatibili.

### Come pubblicare una nuova release
1. Aggiornare il **CHANGELOG** qui sotto (nuova sezione in cima).
2. Aggiungere lo stesso contenuto come nuovo oggetto **in cima** all'array `RELEASES` in `backoffice.html` (pagina Release). Tipi: `add` (Nuovo), `fix` (Corretto), `sec` (Sicurezza), `tech` (Tecnico).
3. Se cambia l'app: aggiornare `downloads/app-info.json` e l'APK.
4. Commit + push + redeploy (+ `setup-db` se lo schema cambia).

---

## 8. CHANGELOG

### [1.5.0] — 2026-06-09 — *App PagoIBAN + area download*
**Nuovo**
- **App Flutter PagoIBAN** (pagatore PSU): 11 schermate, design IBANWAY, flusso scan→conferma(biometria)→autorizza, sicurezza (auto-logout, FLAG_SECURE, root detection, obfuscation). Compilata in release.
- **Area download in GTPOS** per PagoIBAN (`/api/v1/psu/app-info`, card nella pagina Utenti PSU). Ora 2 app: **IBANPOS** ed **PagoIBAN**.

### [1.4.0] — 2026-06-08 — *Modulo PagoIBAN PSU (backend + back-office)*
**Nuovo**
- 6 tabelle PSU + API Express (auth JWT dedicato, conti, **scan/autorizza** QR conto-a-conto con transazione atomica, dispositivi, storico). Riusa `pis_payments`.
- Back-office **PagoIBAN → Utenti PSU**: lista/filtri, scheda, **CRUD**, approvazione KYC, cambio stato.

**Tecnico**
- Adattato allo stack reale **Express + mysql2** (no NestJS/TypeORM). Regole di stack documentate in cima a questo file.

### [1.3.0] — 2026-06-08 — *Device Trust SoftPOS*
**Nuovo**
- Punteggio di **affidabilità del dispositivo** (alto/medio/basso) dai segnali del telefono; tabella `device_trust`, endpoint `/softpos/device/:tid/trust`, colonna Trust + scheda nel back-office. Doc `TRUST.md`. L'app IBANPOS invia il pacchetto device a attivazione/heartbeat.

### [1.2.0] — 2026-06-07 — *Enforcement permessi (Fase 4)*

**Nuovo**
- Middleware **`can(modulo, azione)`** applicato agli endpoint **Ruoli** e **Utenti** (vedi/crea/modifica/elimina/gestisci). Estensione agli altri moduli incrementale.
- `/auth/me` espone i permessi effettivi; il **menu** del back-office nasconde le sezioni senza permesso `vedi`.

**Sicurezza**
- **Rete anti-lockout**: ruolo legacy `admin` e ruoli ad `accesso_totale` hanno sempre accesso pieno (nessun rischio di blocco durante la transizione).

**Tecnico**
- `getUserPermessi(db, utente)` risolve i permessi da `ruolo_id` con fallback legacy.

### [1.1.2] — 2026-06-07 — *Scheda dettaglio transazione*

**Nuovo**
- Lista **Transazioni**: click su una riga → **scheda completa** dell'operazione (esito, importi, pagamento, merchant, terminale/punto vendita/cassa, operatore, IP, data/ora, ISO 8583 raw). Utile per indagini.
- **Indirizzo del terminale POS** (dal punto vendita, fallback sede merchant) con coordinate e **link a Google Maps**.

**Tecnico**
- `GET /api/v1/transazioni/:id` arricchito con join a `merchants`, `terminali`, `punti_vendita`, `casse` + indirizzo (`merchant_addresses`) e coordinate `lat/lng`.

### [1.1.1] — 2026-06-07 — *App SoftIBANPOS, favicon, hardening*

**Nuovo**
- Pagina **Impostazioni → App SoftIBANPOS**: registro di sviluppo dedicato all'app (funzionalità + changelog) e file **`SoftIBANPOS.md`** scaricabile.
- **Favicon IBANWAY** (`favicon.svg`, identica a REGVLA) su tutte le pagine.

**Sicurezza**
- `express.static` non serve più l'intera root del repo: introdotta **allow-list** dei soli asset front-end pubblici (`PUBLIC_FILES`), bloccando l'accesso HTTP ai sorgenti (`/api/*`, `index.js`, ecc.).

### [1.1.0] — 2026-06-07 — *Modulo Ruoli & Permessi + Profilo utente*

**Nuovo**
- Modulo **Ruoli & Accessi**: livelli L1–L6, matrice 13 moduli × 12 azioni (156 permessi), ruoli di default (Super Admin, Admin, Responsabile, Operatore), creazione/eliminazione ruoli custom.
- Ogni **Utente** è una **Persona** e **dipendente di IBANWAY S.p.A.** (backfill automatico via `sync-staff`) con assegnazione del ruolo dalla pagina Utenti.
- Area **"Il mio profilo"**: ogni utente aggiorna i propri contatti personali (email, PEC, cellulare, residenza) e cambia la password.
- Riassetto del menu: CRM (Persone, Aziende), GTPOS (Terminali, Transazioni, ISO 8583), Impostazioni (Utenti, Ruoli, Registro Release).
- Registro Release con convenzione di versionamento e download della documentazione (CLAUDE.md).

**Corretto**
- Monitor: il logging delle chiamate API ora viene effettivamente registrato (middleware spostato **prima** delle route — prima non veniva mai eseguito).

**Sicurezza**
- Endpoint diagnostico `/api/v1/db-test` protetto da autenticazione admin (prima esponeva la configurazione DB senza login).

**Tecnico**
- Nuove API: `/ruoli` (+ matrice), `/utenti`, `/auth/me`, `/auth/password`. Nuove tabelle `ruoli`, `ruolo_permessi`; colonne `utenti.ruolo_id/persona_id`, `persons.datore_lavoro_id/tipo_rapporto/mansione`.

### [1.0.0] — 2026-06-06 — *Prima release ufficiale*
Consolidamento della piattaforma di acquiring IBANWAY.

**Nuovo**
- CRM completo: Merchant (anagrafica, sedi, conti bancari, legali rappresentanti) e Persone con legami bidirezionali Azienda↔Persona e ruoli.
- Scheda Persona: CIE con data di rilascio, residenza con cascata Provincia/Città, PEC, email, cellulare con prefisso a tendina.
- Selettore conto di accredito con dettagli banca (Banca, ABI, CAB, BIC) e logo istituto.
- Gerarchia GT POS: Istituto → Merchant → Punto Vendita → Cassa → Terminale → Transazione.
- SoftPOS A2A "IBANPOS": pagamenti Account-to-Account via PIS Open Banking con QR (EPC SEPA + deeplink Vuolli PagoIBAN); IBAN mascherato; saldi riservati all'operatore.
- Catena di pagamento simulata SoftPOS → GTPOS → OKSA → Fabrick → SCT Inst.
- App Android Flutter IBANPOS compilabile (attivazione, operatore, QR pagamento, storico, saldo, scontrino).
- Area Download APK in GTPOS con info versione e QR.
- Monitor GTPOS real-time: POS collegati, attività, statistiche, volume per orario/banca/area geografica.

**Sicurezza**
- Certificati device firmati GTPOS (JWT 30 giorni) con emissione all'attivazione, rotazione e revoca.
- Crittografia AES-256-GCM at-rest, TLS in transito, JWT HS256, HMAC-SHA256 (MAC ISO 8583 DE64).

**Tecnico**
- Endpoint auto-setup DB (`/api/v1/admin/setup-db`).

**Corretto**
- Crash di avvio (503 su tutto il sito) dovuto a regex del middleware di logging interpretate come commenti.
