# Isoloir

Interface web (kiosque) pour une expérience en isoloir, **hébergée localement** et **sans
Internet**. La navigation entre les écrans se fait **uniquement par appels API** (déclenchés
ensuite par un Streamdeck). On ne peut qu'**avancer**, jamais revenir en arrière.

## Le parcours

1. **Configuration** (opérateur, clavier + souris) — nom de l'environnement, station, code postal.
2. **Bienvenue**
3. **Conditions d'utilisation** — trois choix : *accepter avec la vidéo*, *accepter sans la
   vidéo* (le consentement est enregistré dans les métadonnées), ou *refuser*. En cas de refus,
   une slide **« Vous ne pouvez pas participer »** s'affiche avec une barre de progression et
   renvoie au début après 15 s.
4. **Formulaire** — prénom, genre, âge, profession, code postal. Tous obligatoires :
   impossible d'avancer tant qu'ils ne sont pas remplis.
5. **Vous êtes prêt** — explication du déroulé.
6. **Questions** — une slide par question ; la question s'affiche seule, puis la caméra
   apparaît. Le bouton vert **démarre** (compte à rebours de 5 s, puis 1 min max, minuteur +
   barre, arrêt auto), puis **arrête** l'enregistrement. La vidéo est alors **rejouée** pour
   que la personne se revoie : le bouton **« Recommencer »** apparaît (utilisable **une seule
   fois**), et le bouton vert **valide** et passe à la question suivante.
7. **Remerciement** — puis retour automatique à *Bienvenue* pour le participant suivant.

Les questions et les durées (`maxRecordingSeconds`, `questionSoloSeconds`,
`recordCountdownSeconds`, `refusedRedirectSeconds`) sont dans [config.json](config.json). Les
listes du formulaire (genre, âge, profession) sont dans [form.json](form.json). Les stations
dans [stations.json](stations.json).

---

## 1. Installer (sur le booth)

1. Branchez la clé USB (ou décompressez le zip livré).
2. Double-cliquez **`install.bat`**.
3. L'application est copiée dans `%LOCALAPPDATA%\Isoloir` et un raccourci **« Isoloir »**
   apparaît sur le Bureau.
4. Si un installateur **Bitfocus Companion** (`.exe`) est présent dans `vendor/companion/`,
   le script le lance automatiquement — suivez l'assistant d'installation.

> Le paquet contient déjà tout le nécessaire (Node.js portable + dépendances). **Aucune
> connexion Internet ni installation n'est requise.**

### Configuration des boutons Companion (une fois)

Si un fichier **`.companionconfig`** est fourni dans `vendor/companion/`, `install.bat` le
copie dans `Documents\Isoloir` et affiche la marche à suivre. L'import n'est pas
automatisable (Companion ne l'expose pas en ligne de commande) ; il se fait **une seule fois** :

1. Lancez Companion, ouvrez `http://localhost:8484`.
2. Onglet **Import / Export → Import**, choisissez le fichier `.companionconfig` copié.

Les visuels des boutons (coche / caméra barrée / croix / flèches, en versions active et
inactive) sont fournis dans [public/companion/](public/companion/) — à associer aux steps des
boutons dans Companion (step 1 = actif, step 2 = inactif, step 3 = « sans vidéo »).

### Verrouiller le clavier du participant (optionnel)

Pour empêcher le participant d'utiliser autre chose que les touches **alphanumériques**
(pas de touche Windows, Alt+Tab, raccourcis…), on installe un filtre clavier au niveau
système via le pilote **Interception** (voir [vendor/interception/README.txt](vendor/interception/README.txt)).

- **Mode automatique** (booth = portable) : le clavier **intégré** reste libre ; **tout
  clavier USB externe** (celui du participant) est restreint. Rien à reconfigurer si l'on
  change de clavier participant.
- **Poste fixe** sans clavier intégré : on épingle explicitement le clavier de l'opérateur
  (option `-Learn`).

Installation (**admin + redémarrage**) : double-cliquez **`install-keyfilter.bat`** (ou clic
droit sur [install-keyfilter.ps1](install-keyfilter.ps1) → *Exécuter avec PowerShell*). Le
filtre est ensuite lancé automatiquement par `start.bat`. Le raccourci **« Vérifier les
claviers »** (créé sur le Bureau) liste les claviers et leur classement. Détails dans
[documentation/install.md](documentation/install.md).

**Désactiver** : double-cliquez **`uninstall-keyfilter.bat`** (désinstalle le pilote,
redémarrage requis). Désactivation légère sans redémarrage : `uninstall-keyfilter.ps1 -KeepDriver`.

> ⚠️ Pilote noyau : peut être signalé par l'antivirus/SmartScreen ; à valider avec l'IT.

## 2. Lancer l'expérience

- Double-cliquez le raccourci **« Isoloir »** (ou `start.bat`).
- Le serveur démarre et **Microsoft Edge** s'ouvre en plein écran sur l'écran de configuration.
- Pour tout arrêter : fermez Edge (**Alt + F4**), le serveur s'arrête automatiquement.

## 3. Configurer l'environnement (au démarrage)

- Donnez un **nom** à l'environnement (ex. «  Fête de la Musique de Loches ») pour le reconnaître
  facilement, choisissez une **station** et saisissez un **code postal**, puis **Valider**.
  (Si le nom est laissé vide, un libellé « Station - Code postal » est généré automatiquement.)
- Si un environnement a déjà été configuré, un bouton **« Réutiliser »** permet de repartir
  avec le même identifiant de lieu (`envId`).
- Cet `envId` relie **toutes** les expériences réalisées à ce lieu.

## 4. Piloter l'expérience (Streamdeck / API)

Le Streamdeck a **5 boutons fixes**. Chacun appelle **toujours la même URL** ; c'est le
serveur qui interprète l'action **selon l'écran affiché** :

| Bouton | URL (fixe) |
| --- | --- |
| 🟢 Vert (✓) | `POST http://localhost:3000/api/button/green` |
| 🟠 Orange (↻) | `POST http://localhost:3000/api/button/orange` |
| 🔴 Rouge (✕) | `POST http://localhost:3000/api/button/red` |
| 🔼 Haut | `POST http://localhost:3000/api/button/up` |
| 🔽 Bas | `POST http://localhost:3000/api/button/down` |

Signification par écran (rappelée en bas de chaque slide) :

| Écran | 🟢 Vert | 🟠 Orange | 🔴 Rouge | 🔼/🔽 |
| --- | --- | --- | --- | --- |
| Bienvenue | Continuer | — | — | — |
| Conditions | Accepter avec vidéo | Accepter sans vidéo | Refuser | — |
| Formulaire | Champ suivant | Tout effacer | — | Choix précédent / suivant |
| Vous êtes prêt | Je participe | — | — | — |
| Questions | Démarrer → Arrêter → **Valider (question suivante)** | Recommencer (en relecture, 1×) | — | — |
| Merci | Revenir au début | — | — | — |

Exemple :

```bash
curl -X POST http://localhost:3000/api/button/green
```

> Sur le **formulaire**, le premier champ est sélectionné automatiquement pour une saisie
> clavier directe ; 🟢 passe au champ suivant, 🔼/🔽 changent l'option des champs à choix
> (genre, âge, profession). L'enregistrement s'arrête **automatiquement au bout d'une minute**.
>
> Les endpoints directs restent disponibles (`/api/next`, `/api/consent/*`, `/api/record/*`,
> `/api/restart`, `/api/environment/reset`) pour le débogage.

## 5. Récupérer les données

Tout est écrit dans **`Documents\Isoloir\recordings`** (dossier dédié, séparé du code) :

- `isoloir-<envId>-<sessionId>.json` — métadonnées de **session** (lieu, consentement,
  références des vidéos) ;
- `isoloir-<envId>-<sessionId>-q1.mp4` — réponse à la question 1 ;
- `isoloir-<envId>-<sessionId>-q2.mp4` — réponse à la question 2 (etc.).

Les fichiers d'une même session partagent le couple `<envId>-<sessionId>`, ce qui permet de
relier chaque vidéo à son lieu d'installation.

Le JSON de session contient le contexte (lieu, consentement), **les informations saisies au
formulaire** (prénom, genre, âge, profession, code postal du participant, et le téléphone si
recontact souhaité) et la liste
des vidéos.

> **Vie privée** : ces informations sont enregistrées **uniquement dans ce fichier côté
> serveur**. Le navigateur ne les mémorise pas (pas d'autofill ni de stockage local), et elles
> sont réinitialisées à chaque nouvelle session.

## 6. Mettre à jour

- Branchez la nouvelle clé (ou nouveau zip) et relancez **`install.bat`**.
- Le code est remplacé. Les fichiers **spécifiques au booth sont conservés** :
  `environment.json`, `stations.json`, `form.json`, `companion.json`.
- **`config.json` (questions et durées) est toujours remplacé** par la version du paquet, afin
  d'avoir en permanence la dernière version des questions.
- Les **enregistrements** (`Documents\Isoloir\recordings`) sont hors du dossier de code : ils
  ne sont jamais touchés par une mise à jour.

## 7. Dépannage

- **La webcam ne s'affiche pas** : vérifiez qu'aucune autre application ne l'utilise ; Edge
  est lancé avec l'auto-autorisation caméra (`--use-fake-ui-for-media-stream`).
- **Edge ne s'ouvre pas** : ouvrez manuellement `http://localhost:3000` dans Edge/Chrome.
- **Port déjà utilisé** : une instance tourne peut-être déjà (fermez-la) ou changez le port
  via la variable d'environnement `PORT`.
- **Enregistrement MP4 impossible** : l'affichage doit tourner sous Chromium récent
  (Edge/Chrome 110+).

---

## Développement (sur une machine avec Internet)

```bash
npm install
npm start
# puis ouvrir http://localhost:3000
```

### Préparer le paquet hors-ligne à livrer

1. Télécharger Node.js « Windows Binary (.zip) » x64 et copier `node.exe` dans
   `vendor/node/` (voir [vendor/node/README.txt](vendor/node/README.txt)).
2. Lancer `npm install` pour peupler `node_modules/`.
3. *(Optionnel, filtre clavier)* Déposer les binaires **Interception** et compiler
   `isoloir-keyfilter.exe` (voir [vendor/interception/README.txt](vendor/interception/README.txt)).
4. **Identifiants S3** : déposer à la racine `s3-credentials.json` (jeux `prod` et `test`,
   gitignoré). `install.bat` le chiffrera (DPAPI) sur la borne ; il n'y reste qu'un blob
   opaque. **Sans ce fichier, l'upload est désactivé** (le packaging avertit). ⚠️ Le zip
   généré contient alors les clés en clair : **à traiter comme confidentiel**.
5. Lancer **`npm run package`** → `dist/isoloir-<version>.zip` (racine = `install.bat`, tout
   le reste dans `isoloir/`). C'est le livrable USB/zip.

> Le passage **borne de test** se fait sur l'écran de configuration via le *Konami code*
> (↑ ↑ ↓ ↓ ← → ← → B A) : un bandeau « BORNE DE TEST » s'affiche et les clés **test** sont
> utilisées. Tant que l'upload n'est pas implémenté, le bouton « Envoyer les témoignages »
> **affiche** les identifiants actifs (vérification temporaire).

## Notes techniques

- Serveur **Node.js + Express**, état en mémoire, push temps réel via **SSE**.
- Affichage = **une seule page** à sections (pas de rechargement) pour garder la connexion
  SSE et le flux webcam stables.
- Enregistrement via l'**API MediaRecorder** (HTML5), sortie **MP4**, upload direct sur le
  serveur (pas de transcodage).
- `getUserMedia` fonctionne en HTTP sur `localhost`. Depuis une autre machine via IP réseau,
  il faudrait du HTTPS (hors périmètre actuel).
- Le **filtre clavier** (optionnel) agit hors de l'interface, au niveau du pilote **Interception** :
  filtrage **par périphérique** et par **scancode** (whitelist alphanumérique + Maj, indispensable
  en AZERTY). Source et binaires dans [vendor/interception/](vendor/interception/).
