@@ -60,7 +60,7 @@ Tutte le impostazioni globali sono **flag build-time** nel file [`lib/config.ts`
| Variabile | Default | Descrizione |
| Variabile | Default | Descrizione |
|---|---|---|
|---|---|---|
| `EXTERNAL_LINK_ENABLED` | `true` | Mostra il tipo di card "External Link" nel menu dell'admin. Le card di quel tipo già esistenti restano comunque visibili e cliccabili anche se messo a `false`. |
| `EXTERNAL_LINK_ENABLED` | `true` | Mostra il tipo di card "External Link" nel menu dell'admin. Le card di quel tipo già esistenti restano comunque visibili e cliccabili anche se messo a `false`. |
| `FACTORY_PRESET_SAVE_ENABLED` | `false` | Mostra il bottone "💾 Salva come Factory Preset" nell'admin (funzione developer per ricreare/aggiornare il preset). Il bottone "🏭 Factory Reset" e lo stato del preset sono **sempre visibili** indipendentemente da questo flag — vedi [Factory Preset](#factory-preset-developer). L'endpoint API `POST /api/admin/factory-preset` resta attivo a prescindere. |
| `FACTORY_PRESET_SAVE_ENABLED` | `false` | Mostra il bottone "💾 Save as Factory Preset (dev)" nell'admin (funzione developer per ricreare/aggiornare il preset). Il bottone "🏭 Factory Reset" e lo stato del preset sono **sempre visibili** indipendentemente da questo flag — vedi [Factory Preset](#factory-preset-developer). L'endpoint API `POST /api/admin/factory-preset` resta attivo a prescindere. |
| `DEFAULT_FONT` | `''` | Font di default se il portale non ne ha impostato uno. Stringa vuota = font di sistema (Arial). Altrimenti il nome esatto di un file in `data/fonts/` (es. `"Geist-Variable.woff2"`). |
| `DEFAULT_FONT` | `''` | Font di default se il portale non ne ha impostato uno. Stringa vuota = font di sistema (Arial). Altrimenti il nome esatto di un file in `data/fonts/` (es. `"Geist-Variable.woff2"`). |
| `TEXT_LIMITS` | vedi sotto | Limiti caratteri di tutti i campi testuali. |
| `TEXT_LIMITS` | vedi sotto | Limiti caratteri di tutti i campi testuali. |
| `UPLOAD_LIMITS` | vedi sotto | Dimensioni massime upload per famiglia di file. |
| `UPLOAD_LIMITS` | vedi sotto | Dimensioni massime upload per famiglia di file. |
@@ -185,7 +185,7 @@ Copiare via questa cartella = backup completo. Sostituirla = ripristino completo
Lo stato applicativo (i dati) è **solo** il contenuto di `data/`: `cards.txt`, `portals.txt`, `uploads/`, `fonts/`. Tutto il resto — codice sorgente, `node_modules`, e gli asset di default in `public/` (es. `hero-bg.jpg`, `logo.png`) — **non** fa parte dello stato dati: arriva con il rilascio del software. "Azzerare" il CPC significa quindi sostituire `data/` con uno stato noto.
Lo stato applicativo (i dati) è **solo** il contenuto di `data/`: `cards.txt`, `portals.txt`, `uploads/`, `fonts/`. Tutto il resto — codice sorgente, `node_modules`, e gli asset di default in `public/` (es. `hero-bg.jpg`, `logo.png`) — **non** fa parte dello stato dati: arriva con il rilascio del software. "Azzerare" il CPC significa quindi sostituire `data/` con uno stato noto.
### Contenuti vs codice (due archivi distinti)
### Contenuti vs codice (due archivi distinti)
- **Backup dei contenuti**: archivia solo `data/` (lo fanno il pulsante "Scarica backup" e il comando `zip` documentato sotto). È ciò che si conserva e si ripristina.
- **Backup dei contenuti**: archivia solo `data/` (lo fanno il pulsante "Save backup (ZIP)" e il comando `zip` documentato sotto). È ciò che si conserva e si ripristina.
- **Aggiornamento del codice**: si sostituisce tutto **tranne** `data/`. I contenuti restano al loro posto.
- **Aggiornamento del codice**: si sostituisce tutto **tranne** `data/`. I contenuti restano al loro posto.
- Da CLI un reset conservativo è: `mv data data.old && <estrai-l-archivio-dei-contenuti>`. È l'equivalente del `tar zxf` citato dal QA — vedi nota su ZIP vs tar nella sezione [Backup](#backup-e-ripristino).
- Da CLI un reset conservativo è: `mv data data.old && <estrai-l-archivio-dei-contenuti>`. È l'equivalente del `tar zxf` citato dal QA — vedi nota su ZIP vs tar nella sezione [Backup](#backup-e-ripristino).
@@ -202,8 +202,8 @@ Per avere uno stato di partenza noto su ogni macchina nuova, includere nel pacch
Disponibile dall'admin in **Settings → Backup & Restore**.
Disponibile dall'admin in **Settings → Backup & Restore**.
### Dall'interfaccia
### Dall'interfaccia
- **⬇ Scarica backup ZIP** — scarica `interceptop-backup-<data>.zip` con card, configurazione, media e font (esclude i file temporanei).
- **⤴ Ripristina da ZIP…** — carica uno zip; dopo conferma sovrascrive lo stato attuale e ricarica la pagina. La cartella `data/` precedente viene conservata come `data.bak-<timestamp>/` come rete di sicurezza.
- **⬇ Save backup (ZIP)** — scarica `interceptop-backup-YYYYMMDD-hhmmss.zip` con card, configurazione, media e font (esclude i file temporanei).
- **⤴ Restore from ZIP** — carica uno zip; dopo conferma sovrascrive lo stato attuale e ricarica la pagina. La cartella `data/` precedente viene conservata come `data.bak-<timestamp>/` come rete di sicurezza.
Lo zip così prodotto è caricabile direttamente dal pulsante "Ripristina da ZIP…".
Lo zip così prodotto è caricabile direttamente dal pulsante "Restore from ZIP".
> **Struttura obbligatoria:** i file devono stare alla radice dello zip. Uno zip con tutto dentro una cartella `data/` verrà rifiutato con "cards.txt assente". Deve essere uno **ZIP**, non un `.tar`.
> **Struttura obbligatoria:** i file devono stare alla radice dello zip. Uno zip con tutto dentro una cartella `data/` verrà rifiutato con "cards.txt assente". Deve essere uno **ZIP**, non un `.tar`.
> **ZIP vs tar:** il CPC usa archivi **ZIP** (via `zip`/`unzip`), non `tar`. La finalità è la stessa di un `tar cf`/`tar zxf`: un singolo archivio dei soli contenuti, ripristinabile in un colpo. Il restore accetta lo ZIP prodotto dal pulsante "Scarica backup" o dal comando `zip` qui sopra.
> **ZIP vs tar:** il CPC usa archivi **ZIP** (via `zip`/`unzip`), non `tar`. La finalità è la stessa di un `tar cf`/`tar zxf`: un singolo archivio dei soli contenuti, ripristinabile in un colpo. Il restore accetta lo ZIP prodotto dal pulsante "Save backup (ZIP)" o dal comando `zip` qui sopra.
---
---
@@ -234,9 +234,9 @@ Stato "di fabbrica" ripristinabile con un click. Pensato per preparare preset st
Il preset è un file fisso: **`factory/preset.zip`** alla radice del progetto (fuori da `data/`, quindi non viene toccato dai reset; fuori da `public/`, quindi non scaricabile via web).
Il preset è un file fisso: **`factory/preset.zip`** alla radice del progetto (fuori da `data/`, quindi non viene toccato dai reset; fuori da `public/`, quindi non scaricabile via web).
### Dall'interfaccia (con flag attivo)
- **💾 Salva stato attuale come Factory Preset** — congela lo stato corrente in `factory/preset.zip`.
- **🏭 Factory Reset** — ripristina tutto al preset (disabilitato se il preset non esiste). La `data/` precedente resta come `data.bak-<timestamp>/`.
### Dall'interfaccia
- **🏭 Factory Reset** — sempre visibile. Ripristina tutto al preset (disabilitato se il preset non esiste). La `data/` precedente resta come `data.bak-<timestamp>/`.
- **💾 Save as Factory Preset (dev)** — visibile solo con `FACTORY_PRESET_SAVE_ENABLED = true`. Congela lo stato corrente in `factory/preset.zip`.
### Da riga di comando / API
### Da riga di comando / API
```bash
```bash
@@ -486,7 +486,7 @@ Sul server servono alcuni binari di sistema (richiamati direttamente, non via np
|---|---|---|
|---|---|---|
| `ffmpeg` | Transcodifica video non compatibili | Upload video che richiedono ricodifica → `503` |
| `ffmpeg` | Transcodifica video non compatibili | Upload video che richiedono ricodifica → `503` |
| `ffprobe` | Riconoscimento codec video | Come sopra |
| `ffprobe` | Riconoscimento codec video | Come sopra |
**Recupero dopo un ripristino sbagliato**: lo stato precedente è in `data.bak-<timestamp>/`. Ferma il server, rinomina quella cartella in `data/` e riavvia.
**Recupero dopo un ripristino sbagliato**: lo stato precedente è in `data.bak-<timestamp>/`. Ferma il server, rinomina quella cartella in `data/` e riavvia.
**Il bottone "Salva come Factory Preset" non compare**: è dietro il flag `FACTORY_PRESET_SAVE_ENABLED` in `lib/config.ts`. Mettilo a `true` e ricostruisci (di norma lo si tiene `false` in produzione). Il bottone "🏭 Factory Reset" e lo stato del preset restano comunque sempre visibili.
**Il bottone "Save as Factory Preset (dev)" non compare**: è dietro il flag `FACTORY_PRESET_SAVE_ENABLED` in `lib/config.ts`. Mettilo a `true` e ricostruisci (di norma lo si tiene `false` in produzione). Il bottone "🏭 Factory Reset" e lo stato del preset restano comunque sempre visibili.
<span className="block text-xs text-gray-600">Mostra il tipo “External Link” nel dropdown del Card Type. Le card esistenti di quel tipo restano comunque visibili e cliccabili.</span>
<span className="block text-sm font-semibold text-gray-900">Enable “External Link” type in the dropdown menu.</span>
<span className="block text-xs text-gray-600">Existing cards of this type will still remain visible and clickable, even if you disable the “External Link” type.</span>
</div>
</div>
</label>
</label>
</div>
</div>
@@ -884,7 +884,7 @@ export default function AdminDashboard() {
<h3 className="text-sm font-bold uppercase tracking-wider text-gray-600 mb-3">Backup & Restore</h3>
<h3 className="text-sm font-bold uppercase tracking-wider text-gray-600 mb-3">Backup & Restore</h3>
<p className="text-xs text-gray-500 mb-4">
<p className="text-xs text-gray-500 mb-4">
Il backup contiene card, configurazione portale, media (immagini, video, PDF) e font caricati. Il ripristino sovrascrive lo stato attuale; la cartella precedente viene conservata come <code>data.bak-<timestamp></code> per sicurezza.
The backup contains cards, portal configuration, media (images, videos, PDFs), and uploaded fonts. Restoring overwrites the current state. Clicking the “Save backup (ZIP)” button saves the Cards structure as <code>interceptop-backup-YYYYMMDD-hhmmss.zip</code>.
</p>
</p>
<div className="flex flex-wrap gap-3">
<div className="flex flex-wrap gap-3">
<button
<button
@@ -892,7 +892,7 @@ export default function AdminDashboard() {
Stato “di fabbrica” ripristinabile con un click. Il preset (<code>factory/preset.zip</code>) viene preparato sulla macchina di sviluppo e distribuito alle macchine MajorNet.
“Factory” state restorable with one click. The preset (<code>factory/preset.zip</code>) is prepared on the development machine and distributed to MajorNet machines.