# Serveurs et API

Documentation des serveurs, API, authentification, accès aux données, configuration des environnements et services backend.

# Serveur principal NestJS

## Rôle

Le backend Web principal est une application NestJS située dans `uniksim-back-end/`. Elle centralise les API utilisateur, jeu, administration, support, notifications, push, mail et IA.

## Démarrage

Le point d’entrée est `src/main.ts`.

- Attend `aiServerReady` avant de créer l’application NestJS.
- Crée l’application à partir de `AppModule`.
- Active CORS pour le frontend local sur `http://localhost:4200`.
- Autorise les payloads JSON et URL-encoded jusqu’à 50 MB.
- Ajoute l’en-tête HSTS.
- Écoute sur le port `3000`.

## Assemblage du backend

`src/app.module.ts` branche les principaux sous-systèmes :

- TypeORM et les entités métier.
- JWT global avec expiration de 4 heures.
- i18n.
- fichiers statiques frontend.
- HTTP externe.
- services utilisateurs, jeu, administration, IA, support, Redis, notifications, Firebase et présence.
- gateway WebSocket du support.

## Contrôleurs importants

- `LoginController` : connexion et création de compte.
- `UserController` : fonctionnalités utilisateur connecté.
- `GameController` : endpoints consommés par le jeu/WebGL.
- `AdminController`, `AdminUserController`, `AdminPresenceController` : administration.
- `SupportController`, `SupportAdminController` : support.
- `NotificationController`, `PushController` : notifications et push.

# Administration : API NestJS et Admin Server Express

## Vue d’ensemble

L’administration backend d’Uniksim repose sur **deux couches distinctes** qu’il ne faut pas confondre :

1. **les routes d’administration de l’API NestJS principale**, protégées par des guards et reliées aux services backend;
2. **un serveur Express d’administration séparé** dans `uniksim-back-end/src/node.js/server/admin_server.js`, qui écoute localement sur le port `8105` et gère surtout des opérations historiques/BrainCloud et certains flux SSE.

## Architecture backend d’administration

```mermaid
flowchart LR
    CLIENT[Clients Web / outils internes] --> NEST[NestJS principal]
    CLIENT --> EXPRESS[Admin Server Express :8105]

    NEST --> AC[AdminController]
    NEST --> AUC[AdminUserController]
    NEST --> APC[AdminPresenceController]
    NEST --> SAC[SupportAdminController]

    AC --> AS[AdminService]
    AUC --> AUS[AdminUserService]
    APC --> PS[PresenceService]

    AS --> DB[(MySQL / TypeORM)]
    AUS --> DB
    PS --> REDIS[(Redis)]

    EXPRESS --> BC[BrainCloud]
    EXPRESS --> REDIS
    EXPRESS --> SSE[SSE / copie de simulations]

```

## 1. Administration dans l’API NestJS

Les contrôleurs d’administration sont regroupés dans `uniksim-back-end/src/app.controller.ts` et enregistrés dans `AppModule`.

- `AdminUserController` sous `/admin` : récupération et gestion d’informations utilisateurs.
- `AdminPresenceController` sous `/admin/presence` : présence en ligne, état de jeu et télémétrie.
- `AdminController` : autres opérations administratives.
- `SupportAdminController` : fonctions administratives du support.

La logique métier correspondante se trouve notamment dans `src/service/admin.service.ts`, `src/service/adminUser.service.ts` et `src/service/presence.service.ts`.

## 2. Admin Server Express séparé

Le fichier `src/node.js/server/admin_server.js` démarre un serveur Express distinct sur `ConstantsInUse.ADMIN_SERVER_PORT`, actuellement `8105`. Son URL locale de référence est définie par `ADMIN_SERVER_URL` dans `constantsVariable.js`.

Ce serveur est utilisé notamment pour :

- `POST /admin/adminCommand` : commandes d’administration BrainCloud telles que lecture de documents, récupération de simulations, copie de simulation et suppression d’un utilisateur d’une simulation;
- `POST /redisBulkCommands` : commandes Redis groupées;
- `GET /getActiveSimulations/...` : récupération des simulations actives;
- `GET /copySimNotification` : progression d’une copie de simulation via SSE;
- surveillance de certains jobs BrainCloud et relance lorsqu’ils disparaissent.

## Flux d’une commande Admin Server

```mermaid
sequenceDiagram
    participant C as Client / outil admin
    participant E as Admin Server Express
    participant B as BrainCloud
    participant R as Redis
    participant S as Flux SSE

    C->>E: Requête admin
    alt Commande BrainCloud
        E->>B: Exécute la commande
        B-->>E: Résultat
    else Commande Redis
        E->>R: redisBulkCommands(...)
        R-->>E: Résultat
    else Copie de simulation
        E->>B: Copie données / simulation
        E-->>S: Progression
        S-->>C: Événements SSE
    end
    E-->>C: Réponse

```

## Sécurité backend

Les routes NestJS utilisent notamment `AuthGuardAdmin` et `AuthGuardAdminUser`. Toute modification d’une route d’administration doit vérifier le guard attendu et le rôle autorisé.

## Fichiers principaux

- `uniksim-back-end/src/app.controller.ts`
- `uniksim-back-end/src/app.module.ts`
- `uniksim-back-end/src/node.js/server/admin_server.js`
- `uniksim-back-end/src/node.js/server/constantsVariable.js`
- `uniksim-back-end/src/service/admin.service.ts`
- `uniksim-back-end/src/service/adminUser.service.ts`
- `uniksim-back-end/src/service/presence.service.ts`

# Authentification et guards

## Vue d’ensemble

L’authentification combine JWT côté backend et des guards côté backend et frontend.

## Backend

- JWT configuré globalement dans `src/app.module.ts`.
- Secret provenant de `JwtConstants.secretJwt`.
- Durée de validité configurée à 4 heures.
- `AuthGuardUser` protège les endpoints utilisateur.
- `AuthGuardGame` protège les endpoints consommés par le jeu.
- `AuthGuardAdmin` et `AuthGuardAdminUser` protègent les fonctions administratives.

## Frontend

Les guards Angular sont dans `uniksimFrontEnd/src/app/service/auth/`. Les routes sont protégées directement dans `app.module.ts`.

`AuthInterceptorService` est enregistré comme `HTTP_INTERCEPTORS` afin d’appliquer la logique d’authentification aux appels HTTP.

## Connexion

`LoginController` expose notamment `signIn`, `signUp` et le login spécial Chenelière. La logique métier correspondante se trouve dans `src/service/login.service.ts`.

## Socket.IO et notifications du jeu

`socketAuthMiddleware` est installé sur `/account` et `/support`. Il vérifie le JWT avant tout handler puis stocke le payload dans `client.data.user`. Le token peut venir de `handshake.auth.token`, de la query ou de Authorization. Angular envoie `auth: { token }` via le transport commun `RealtimeSocket`.

Les rooms support sont soumises à l’appartenance à la conversation; `typing` exige d’avoir rejoint la room et `checkOnline` limite les non-admins à leurs admins assignés. Les sockets de présence appartiennent au namespace compte.

`POST /saveNotification` utilise `AuthGuardUser`. `GameNotificationService` vérifie le profil actif destinataire et les membres de la simulation BrainCloud; les types réservés au serveur sont refusés. Les routes d’inbox et d’installations FCM dérivent le compte de `request.user.sub`.

# Configuration, environnements et constantes

## Vue d’ensemble

La configuration backend est principalement répartie entre les fichiers d’environnement et `uniksim-back-end/src/node.js/server/constantsVariable.js`. Ce fichier centralise de nombreuses valeurs utilisées par les serveurs, les intégrations et les règles métier.

**Ne jamais recopier de secrets dans le wiki.** Le fichier contient des clés, mots de passe et credentials qui doivent rester dans le code ou une configuration sécurisée et ne doivent pas être documentés en clair.

## Fichiers d’environnement

- `dev.env` : environnement de développement.
- `dev2.env` : deuxième environnement de développement.
- `demo.env` : environnement demo.
- `live.env` : environnement live.

Les scripts de démarrage du backend sélectionnent explicitement l’un de ces fichiers via `node --env-file ... dist/main`.

## constantsVariable.js

Le fichier `src/node.js/server/constantsVariable.js` sert de registre central pour plusieurs familles de constantes.

- `SERVER_INSTANCE` : live, dev, demo, dev2 et demoLive.
- `HOSTNAME`, `PORTS`, `USERNAME` : paramètres d’infrastructure.
- `SITE_URL_COMPLET` : URLs des instances Web.
- `ConstantsInUse` : valeurs effectivement utilisées par le processus courant.
- `ADMIN_SERVER_URL` / `AI_SERVER_URL` : services locaux auxiliaires.
- `ROLES_STRING` / `ROLES_NUMBER` : mapping des rôles.
- `SIMULATION` : identifiants des jeux.
- `AI_CONFIG` : provider, modèles, limites, timeouts et paramètres RAG.
- `SUPPORT_CONFIG` : uploads, limites de messages, événements et comportement IA du support.
- `NOTIFICATION_CONFIG` : rétention Redis et événements de notification.
- `FIREBASE_CONFIG` : paramètres techniques Firebase/FCM.

## ConstantsInUse

`ConstantsInUse` agit comme configuration runtime commune. Elle contient notamment la base ciblée, le host SQL, le port SQL, le serveur courant, l’URL du site, la version WebGL locale et les ports des serveurs auxiliaires.

Lorsqu’un bug apparaît uniquement en dev/demo/live, ce bloc est un des premiers endroits à vérifier avec le fichier `.env` correspondant.

## Frontend

Côté Angular, `uniksimFrontEnd/src/environments/environment.ts` définit notamment les URLs de serveur utilisables et le backend attendu.

## Points d’attention

- Ne pas ajouter une nouvelle constante “temporaire” sans vérifier si elle existe déjà dans une famille logique.
- Une modification de port ou d’URL peut affecter plusieurs processus : NestJS, Admin Server, IA, Angular ou Redis.
- Les rôles numériques doivent rester cohérents avec les données en base.
- Les valeurs sensibles ne doivent jamais être copiées dans la documentation.

## Configuration IA et temps réel actuelle

Au 30 septembre 2026 : `GOOGLE_CLOUD_PROJECT` est requis pour Vertex AI; `GOOGLE_CLOUD_LOCATION` vaut `global` par défaut et cette location est imposée par la politique tarifaire actuelle. L’authentification utilise les credentials Google par défaut de l’environnement. Chroma Cloud utilise les variables `CHROMA_API_KEY`, `CHROMA_TENANT` et `CHROMA_DATABASE`; la collection est `game`. Ne pas recopier leurs valeurs ici.

`AI_MODELS` configure `gemini-3.5-flash-lite` et `gemini-embedding-001`. `AI_PRICE_VERSIONS` référence `vertex-global-standard-2026-09-29`; `THINKING_LEVEL` vaut LOW. Le provider de génération et celui d’embedding restent indépendants. Le serveur IA écoute sur loopback; son token interne protège les opérations query/summary.

`NOTIFICATION_CONFIG` fixe le suffixe `_notifications`, la taille maximale de l’inbox (100), sa rétention (10 519 200 secondes), les types serveur réservés et la taille du payload client (2 048 caractères). Les constantes Angular sont séparées dans `realtime.constants.ts` (transport), `account.constants.ts` (activité du compte) et `support.constants.ts` (support).

# Base de données et persistance

## Vue d’ensemble

Le backend utilise principalement **MySQL via TypeORM** pour les données relationnelles, et **Redis** pour plusieurs données temporaires ou temps réel.

## Architecture de persistance

```mermaid
flowchart TD
    API[NestJS Controllers] --> SERVICES[Services métier]
    SERVICES --> ORM[TypeORM]
    ORM --> MYSQL[(MySQL)]

    SERVICES --> REDIS[RedisService]
    REDIS --> CACHE[(Redis)]

    SERVICES --> BC[BrainCloud]

    MYSQL --> E1[Users / rôles]
    MYSQL --> E2[Produits / codes]
    MYSQL --> E3[Support]
    MYSQL --> E4[FCM installations]

    CACHE --> R1[Présence]
    CACHE --> R2[Sessions]
    CACHE --> R3[Notifications]
    CACHE --> R4[Rankings / données temps réel]

```

## Configuration TypeORM

Le point central est `uniksim-back-end/src/database.providers.ts`.

La connexion est créée avec `TypeOrmModule.forRoot(...)` et utilise :

- `ConstantsInUse.HOSTNAME`
- `ConstantsInUse.PORTS`
- `ConstantsInUse.USERNAME`
- `ConstantsInUse.PASSWORD_DATABASE`
- `ConstantsInUse.PROVIDERS`

Le backend est configuré avec `synchronize: false`. Les changements de schéma ne doivent donc pas être supposés automatiques.

## Entités principales

Les entités TypeORM sont dans `uniksim-back-end/src/entities/`. Parmi les principales :

- `User`, `Role`, `RoleUser`
- `Product`, `ProductsCode`, `ProductsResources`, `Resources`
- `Period`, `Constant`
- `SupportConversation`, `SupportTicket`, `SupportMessage`
- `UserFcmToken`

## Redis

Redis n’est pas seulement un cache. Il est utilisé pour plusieurs fonctions runtime importantes, notamment :

- présence et heartbeats;
- sessions de jeu;
- notifications persistées temporairement;
- rankings et certaines données de simulation;
- communication de certains services historiques.

## Choisir le bon stockage

```mermaid
flowchart LR
    CHANGE[Besoin métier] --> ENTITY{Donnée relationnelle ?}
    ENTITY -- Oui --> MODEL[Entity TypeORM]
    MODEL --> ORM[Repository / Service]
    ORM --> SCHEMA[Vérifier schéma SQL / migration]

    ENTITY -- Non --> RUNTIME{Temporaire ou temps réel ?}
    RUNTIME -- Oui --> REDIS[RedisService]
    RUNTIME -- Non --> OTHER[Vérifier BrainCloud / stockage existant]

```

## Points d’attention

- Ne pas activer `synchronize: true` sur un environnement partagé pour contourner un changement de schéma.
- Vérifier les relations d’entités avant de supprimer ou renommer une colonne.
- Redis contient des données applicatives importantes : un flush peut affecter sessions, présence ou notifications.
- Avant d’ajouter un nouveau stockage, vérifier si le système utilise déjà MySQL, Redis ou BrainCloud pour ce type de donnée.

## Évolution de la persistance des notifications

Au 30 septembre 2026, les entités enregistrées dans `database.providers.ts` comprennent `UserFcmToken`, sans modèle de subscription par produit. Une installation appartient au compte; les push ciblent toutes ses installations. L’inbox Redis `user_<id>_notifications` est bornée à 100 entrées; son TTL de 10 519 200 secondes est renouvelé à chaque insertion. `NotificationService` possède maintenant la logique d’inbox; les anciennes fonctions de notification dans `server.js` ont été retirées. Voir [Notifications et Push](https://wiki.uniksim.com/books/web/page/notifications-et-push).

# Build et déploiement Web

## Vue d’ensemble

Le frontend Angular et le backend NestJS sont déployés ensemble. Le build Angular de production écrit directement dans le backend, puis le backend est compilé et démarré avec l’environnement voulu.

## Pipeline de build

```mermaid
flowchart TD
    A[uniksimFrontEnd] -->|npm run build| B[uniksim-back-end/src/front]
    B -->|npm run build dans le backend| C[uniksim-back-end/dist]
    C -->|npm run start:demo| D[Node + demo.env]
    D --> E[sim.dev.uniksim.com]

```

## Pourquoi le frontend apparaît dans le backend

Dans `uniksimFrontEnd/angular.json`, la configuration de production utilise :

`outputPath: ../uniksim-back-end/src/front`

Le dossier `src/front` contient donc le **résultat compilé d’Angular**. Ce n’est pas un dossier frontend à modifier manuellement.

Lors du build NestJS, ces fichiers sont ensuite disponibles dans le build backend, et `ServeStaticModule` les sert au navigateur.

## Serveur de développement hébergé

L’instance de développement est accessible via `sim.dev.uniksim.com` sur l’infrastructure DigitalOcean.

Le workflow serveur utilisé actuellement est :

1. Se connecter au serveur DigitalOcean.
2. Passer sur l’utilisateur `forge` avec `sudo -u forge` ou la commande équivalente utilisée sur le serveur.
3. Aller dans le dossier du site avec `cd sim.dev.uniksim.com`.
4. Mettre le code à jour.
5. Builder le frontend Angular avec `npm run build` dans `uniksimFrontEnd`.
6. Builder le backend NestJS avec `npm run build` dans `uniksim-back-end`.
7. Démarrer le backend avec `npm run start:demo`.

## Ordre de build

```mermaid
sequenceDiagram
    participant D as Développeur
    participant F as Angular
    participant B as Backend NestJS
    participant N as Node demo
    participant W as sim.dev.uniksim.com

    D->>F: npm run build
    F-->>B: Génère src/front
    D->>B: npm run build
    B-->>N: Génère dist
    D->>N: npm run start:demo
    N->>N: Charge demo.env
    N-->>W: Sert API + frontend compilé

```

## Scripts backend disponibles

- `npm run build` : compile NestJS.
- `npm run start:dev` : démarre `dist/main` avec `dev.env`.
- `npm run start:dev2` : démarre avec `dev2.env`.
- `npm run start:demo` : démarre avec `demo.env`.
- `npm run start:live` : démarre avec `live.env`.

## Points d’attention

- Le frontend doit être buildé **avant** le backend si on veut embarquer la nouvelle version Angular dans le build backend.
- Après une modification uniquement backend, le build Angular n’est pas toujours nécessaire.
- Après une modification frontend, vérifier que les fichiers générés sont présents dans `uniksim-back-end/src/front` avant le build backend.
- Vérifier l’environnement utilisé avant de lancer le serveur : `demo`, `dev`, `dev2` ou `live`.

# Conventions de sécurité Web

## But

Cette page résume les mécanismes de sécurité réellement présents dans le projet. Elle ne remplace pas un audit de sécurité; elle sert de guide pour éviter de contourner les protections existantes lorsqu’on ajoute une feature.

## Authentification et autorisation

Le backend utilise des JWT et plusieurs guards spécialisés :

- `AuthGuardUser` : utilisateur authentifié;
- `AuthGuardAdmin` : rôle admin;
- `AuthGuardAdminUser` : admin ou admin\_user;
- `AuthGuardGame` : accès utilisé par les appels du jeu.

Les tokens peuvent être lus depuis l’en-tête `Authorization: Bearer ...` ou, selon le flux, depuis le cookie `token`. Les guards backend restent la source d’autorité; les guards Angular servent surtout à contrôler la navigation.

## Flux d’autorisation

```mermaid
sequenceDiagram
    participant C as Client
    participant G as Guard NestJS
    participant J as JwtService
    participant E as Endpoint

    C->>G: Requête + token
    G->>J: Vérifie signature / expiration
    J-->>G: Payload
    G->>G: Vérifie rôle si nécessaire
    alt Autorisé
        G->>E: Continue
        E-->>C: Réponse
    else Refusé
        G-->>C: 401 Unauthorized
    end

```

## Configuration HTTP

Dans `src/main.ts` :

- CORS est configuré avec credentials;
- les requêtes JSON et URL-encoded ont une limite de taille;
- l’en-tête HSTS `Strict-Transport-Security` est ajouté;
- le serveur principal écoute sur le port `3000`.

## Uploads du support

`SupportAttachmentService` applique plusieurs contrôles avant de stocker ou servir une image :

- validation du contenu binaire réel plutôt que confiance dans le MIME envoyé par le navigateur;
- types d’image autorisés limités;
- normalisation en WebP;
- limite de dimensions et de taille;
- nom de fichier aléatoire et normalisé;
- protection contre les chemins arbitraires via `path.basename` et validation du format;
- vérification que la pièce jointe appartient à la conversation/utilisateur demandé;
- quotas de stockage utilisateur et global;
- nettoyage des uploads orphelins.

## Sécurité des fichiers

```mermaid
flowchart TD
    U[Upload] --> BIN[Valider signature binaire]
    BIN --> SIZE[Vérifier dimensions / taille]
    SIZE --> NORMAL[Normaliser en WebP]
    NORMAL --> NAME[Générer nom aléatoire]
    NAME --> QUOTA[Vérifier quotas]
    QUOTA --> SAVE[Écrire avec création exclusive]

    READ[Lecture] --> PATH[Vérifier nom / chemin]
    PATH --> OWNER[Vérifier conversation + utilisateur]
    OWNER --> FILE[Servir le fichier]

```

## Secrets et configuration

Le projet contient encore des secrets historiques dans la configuration. Ils ne doivent **jamais** être copiés dans le wiki, le frontend ou les logs. Toute nouvelle intégration devrait préférer les fichiers d’environnement ou une gestion de secrets dédiée plutôt qu’ajouter une nouvelle clé en clair dans le code.

## IA et contrôle d’usage

Le système IA possède des limites de requêtes, budgets, timeouts et plafonds de tokens configurés dans `AI_CONFIG`. Le dossier `src/node.js/server/ai/guard/` contient également la logique de garde liée aux coûts.

## Checklist pour une nouvelle route

- Choisir le guard backend correspondant au niveau d’accès.
- Ne jamais se fier uniquement à l’UI ou au routing Angular.
- Valider les IDs liés à l’utilisateur côté serveur.
- Limiter et valider les entrées volumineuses ou fichiers.
- Ne pas exposer de secret dans une réponse API ou dans Angular.
- Préférer une erreur contrôlée à une exception brute contenant des détails internes.
- Vérifier les permissions avant de lire un fichier ou une ressource appartenant à un autre utilisateur.