# MDT V2 — Documentation Technique
Fichiers sources dans `~/workspace/build/src/`

> **Mobile Data Terminal** pour serveur FiveM Roleplay

---

## Table des matières

1. [Vue d'ensemble](#1-vue-densemble)
2. [Architecture du projet](#2-architecture-du-projet)
3. [Composants clés](#3-composants-clés)
4. [Flux de données & API](#4-flux-de-données--api)
5. [Authentification & Contrôle d'accès](#5-authentification--contrôle-daccès)
6. [Modules par service](#6-modules-par-service)
7. [Frontend](#7-frontend)
8. [Styling](#8-styling)
9. [Base de données](#9-base-de-données)
10. [Prérequis & Installation](#10-prérequis--installation)
11. [Sécurité](#11-sécurité)
12. [Bonnes pratiques & Axes d'amélioration](#12-bonnes-pratiques--axes-damélioration)

---

## 1. Vue d'ensemble

MDT V2 est une application web de type **Mobile Data Terminal (MDT)** conçue pour un serveur FiveM roleplay (Los Santos). Elle fournit aux différents services (police, justice, médical, armée, gouvernement) un tableau de bord unifié permettant de :

- Gérer les fiches civiles et les casiers judiciaires
- Rédiger des rapports (contraventions, plaintes, incidents, tirs, saisies, opérations…)
- Consulter et rechercher des individus recherchés ou hostiles
- Accéder au code pénal, aux procédures et à la documentation interne
- Communiquer via un chat inter-services
- Gérer les plannings, absences et la comptabilité
- Administrer les comptes utilisateurs et les permissions

**Stack technique :**

| Couche | Technologie |
|--------|-------------|
| Frontend | HTML5, CSS3, JavaScript natif (vanilla) |
| Backend | PHP natif (procédural, MySQLi) |
| Base de données | MySQL / MariaDB |
| Icônes | FontAwesome |
| Déploiement | Iframe NUI FiveM (`cfx-nui-*`) |

**Domaine de production :** `v2.mdt.t-life.fr`

---

## 2. Architecture du projet

### 2.1 Structure des dossiers

```
MDT_V2/
├── index.html                  # Page d'accueil / portail
├── login.html                  # Formulaire de connexion
├── register.html               # Formulaire d'inscription
├── chat.html                   # Module de chat autonome
├── document.html               # Hub de documents
├── formulaire_rc_sast.html     # Formulaire de recrutement
├── favicon.ico
│
├── css/                        # Feuilles de style (27 fichiers)
│   ├── ROOT.css                # Variables CSS (design tokens)
│   ├── STYLE.css               # Feuille principale
│   ├── admin.css               # Styles du panneau admin
│   ├── chat.css                # Module chat
│   ├── blocnotes.css           # Bloc-notes
│   └── ...                     # 1 fichier CSS par fonctionnalité
│
├── js/                         # Logique frontend (65+ fichiers)
│   ├── config.js               # Module ES : URLs API, codes patrol
│   ├── login.js                # Gestionnaire de connexion
│   ├── register.js             # Gestionnaire d'inscription
│   ├── mdt_police.js           # Contrôleur dashboard police
│   ├── mdt_doj.js              # Contrôleur module DOJ
│   ├── mdt_gouvernement.js     # Contrôleur module gouvernement
│   ├── civil.js                # CRUD fiches civiles + AppModal
│   ├── casier.js               # CRUD casiers judiciaires + AppModal
│   └── ...                     # 1 fichier JS par fonctionnalité
│
├── php/                        # Backend / API (66+ fichiers)
│   ├── init.php                # Cœur : connexion DB, session, auth
│   ├── login.php               # Endpoint de connexion
│   ├── register.php            # Endpoint d'inscription
│   ├── user.php                # Infos utilisateur courant
│   ├── civil.php               # API fiches civiles
│   ├── casier.php              # API casiers judiciaires
│   ├── agent.php               # API agents de police
│   ├── saisie.php              # API saisies
│   ├── reports.php             # API rapports agrégés
│   └── ...                     # 1 fichier PHP par entité
│
├── police/                     # Module Police (SASP)
│   ├── dashboard.html          # Tableau de bord principal
│   ├── civil.html              # Gestion des civils
│   ├── casier.html             # Casiers judiciaires
│   ├── grade.html              # Grades
│   ├── division.html           # Divisions
│   ├── formations/             # Pages de formation
│   ├── tenues/                 # Tenues par grade
│   └── ...                     # ~70 pages HTML
│
├── doj/                        # Module Department of Justice
│   ├── mdt_doj.html            # Dashboard DOJ
│   ├── casiers.html            # Casiers
│   ├── code_penal.html         # Code pénal
│   ├── da.html                 # Dossiers d'arrestation
│   ├── enquette.html           # Enquêtes
│   ├── ra.html                 # Rapports d'arrestation
│   └── annulaire.html          # Annuaire
│
├── medic/                      # Module Médical (SAMD)
│   ├── dashboard.html          # Tableau de bord médical
│   ├── civil.html              # Fiches civiles médicales
│   ├── medical.html            # Dossiers médicaux
│   ├── bilan.html              # Bilans
│   ├── ppa.html                # PPA
│   ├── css/                    # Styles spécifiques
│   ├── js/                     # Logique spécifique
│   └── php/                    # Endpoints spécifiques
│
├── army/                       # Module Armée
│   ├── mdt_armee.html          # Dashboard armée
│   ├── css/                    # Styles
│   └── js/                     # Logique
│
├── gouv/                       # Module Gouvernement
│   ├── mdt_gouvernement.html   # Dashboard gouvernement
│   ├── admin.html              # Administration
│   ├── code_penal.html         # Code pénal
│   ├── da.html                 # Dossiers d'arrestation
│   ├── enquette.html           # Enquêtes
│   └── ra.html                 # Rapports d'arrestation
│
├── admin/                      # Module Administration
│   ├── admin.html              # Gestion des utilisateurs
│   └── entreprise.html         # Gestion des entreprises
│
├── lv/                         # Module alternatif civil
│   ├── civil.html
│   ├── cree_civil.html
│   ├── js/
│   └── php/
│
├── boilerplates/               # Templates réutilisables
│   └── modal-boilerplate.html
│
├── img/                        # Images statiques
│   └── default_profile_picture.png
│
└── uploads/                    # Fichiers uploadés par les utilisateurs
```

### 2.2 Philosophie architecturale

L'application suit un **pattern MVC simplifié** :

| Couche | Rôle | Exemple |
|--------|------|---------|
| **View** | Pages HTML, une par fonctionnalité | `police/civil.html` |
| **Controller** | Fichiers JS — manipulation DOM + appels `fetch` | `js/civil.js` |
| **Model/API** | Fichiers PHP — requêtes DB CRUD | `php/civil.php` |
| **Core** | `init.php` — connexion DB, session, authentification | `php/init.php` |

**Principe de découplage :** chaque fonctionnalité possède son triplet HTML/JS/PHP dédié. Les pages importent uniquement les CSS/JS dont elles ont besoin.

---

## 3. Composants clés

### 3.1 `php/init.php` — Cœur de l'application

Ce fichier est inclus par **tous les endpoints PHP**. Il centralise :

```php
// Configuration session (compatible iframe FiveM NUI)
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'None'
]);

// Connexion MySQL singleton
function conn() {
    static $conn = null;
    if ($conn === null) {
        $conn = new mysqli(HOST, USER, PASS, DB_NAME);
    }
    return $conn;
}

// Authentification
function login($username, $password) { /* ... */ }
function logout() { /* ... */ }
function logged() { /* ... */ }
function authorized() { /* vérifie status = 'accepted' */ }
function power($min) { /* vérifie le niveau de pouvoir */ }
function group($name) { /* vérifie l'appartenance à un groupe */ }
function access($groupId, $minPower) { /* vérifie groupe + pouvoir */ }

// Gardes
function requireLogin() { /* redirige si non connecté */ }
function requirePower($min) { /* redirige si pouvoir insuffisant */ }
function requireAccess($g, $p) { /* vérifie groupe + pouvoir */ }

// Réponse JSON
function json($data, $code = 200) { /* ... */ }
```

**En-têtes de sécurité :**
- CSP : `frame-ancestors 'self' https://cfx-nui-*` (autorise l'embedding FiveM)
- Cookies : `Secure`, `HttpOnly`, `SameSite=None`

### 3.2 `js/config.js` — Configuration frontend

Module ES exportant les constantes partagées :

```javascript
export const BaseURL = `${location.origin}`;
export const ApiURL = `${location.origin}/php`;
export const PatrolCODES = ["Code 4", "Code 5", "Code 6", /* ... */];
export const PatrolID = ["Lincoln", "Adam", /* ... */];
export const APP_CONFIG = { nav: [/* structure de navigation */] };
```

### 3.3 `AppModal` — Système de modales réutilisable

Implémenté dans `js/civil.js` et `js/casier.js`, exposé via `window.AppModal` :

```javascript
window.AppModal = {
    show({ title, message, onOk }),
    confirm({ title, message, onOk, onCancel }),
    guard({ title, message }, callback),
    bindConfirm(selector, { title, message }, callback)
};
```

Utilise l'élément natif `<dialog>` avec `showModal()`.

### 3.4 Lightbox / Zoom d'images

Fonctions `openLightbox(src, alt)` et `closeLightbox()` dans `js/lightbox_zoom.js`. Déclenchées au clic sur une image ou un bouton zoom. Fermeture via touche Escape ou clic sur le fond.

### 3.5 `police/dashboard.html` — Dashboard principal

Le module le plus complet. Structure en **3 colonnes** :

| Colonne | Contenu |
|---------|---------|
| **Gauche** | Sidebar de navigation avec catégories pliables |
| **Centre** | Widgets : derniers rapports, dernières saisies, individus recherchés/hostiles |
| **Droite** | Chat intégré, cérémonies, notes personnelles |

**Catégories de la sidebar :**

- **Rapports** : Tickets routiers, plaintes, incidents, tirs, arrestations, DA, braquages, rookies, interrogatoires, opérations, enquêtes, rapports labo
- **Police Académie** : Notes, formulaires de recrutement
- **Civil** : Fiches civiles, casiers judiciaires, véhicules civils
- **Information** : Annuaire services, guide rookie, divisions, grades, droits Miranda, procédures, codes radio, code pénal, documents, bodycam
- **Gestion** : Chat, planning, absences, dispatch, armement, saisies, agents, véhicules police, heures de service, comptabilité

---

## 4. Flux de données & API

### 4.1 Convention d'API

Tous les fichiers PHP suivent un pattern **action-based** :

```
GET  /php/{entite}.php?action=list                    → Liste complète
GET  /php/{entite}.php?action=search&searchterm=X     → Recherche
GET  /php/{entite}.php?action=get&id=X                → Enregistrement unique
GET  /php/{entite}.php?action=list_searchedhostiles   → Liste spécialisée
POST /php/{entite}.php                                 → Créer / Mettre à jour / Supprimer
DELETE /php/{entite}.php?id=X                         → Supprimer
```

**Format de réponse JSON :**

```json
{ "success": true, "elements": [...] }
{ "success": true, "element": {...} }
{ "success": false, "error": "Message d'erreur" }
```

### 4.2 Endpoints principaux

| Endpoint | Actions | Table DB |
|----------|---------|----------|
| `php/civil.php` | list, search, get, update, delete, list_searchedhostiles | `civils` |
| `php/casier.php` | list, search, get, update, delete | `casiers` |
| `php/agent.php` | list (GET), delete (DELETE) | `mgt_police_agents` |
| `php/saisie.php` | list (avec limit), CRUD | saisies |
| `php/reports.php` | list (avec limit) | rapports |
| `php/user.php` | GET utilisateur courant | session |
| `php/chat.php` | Messages chat | table chat |
| `php/admin.php` | CRUD utilisateurs | tables users |
| `php/login.php` | POST authentification | `mdt_users` |
| `php/register.php` | GET groupes / POST inscription | `users`, `users_groups` |

### 4.3 Exemple de flux : Recherche d'un civil

```
1. L'utilisateur tape dans le champ de recherche (civil.html)
2. js/civil.js → afficherListe(query)
3. GET /php/civil.php?action=search&searchterm=DOE
4. php/civil.php → requête SQL avec LIKE sur la table civils
5. Retour JSON : { success: true, elements: [{id, nom, prenom}, ...] }
6. Le JS affiche la liste avec boutons de suppression
7. L'utilisateur clique sur un civil
8. afficherDetails(id) → GET /php/civil.php?action=get&id=5
9. Le JS rend : infos personnelles, permis, photos, status recherché/dangereux
10. L'utilisateur modifie et sauvegarde
11. POST /php/civil.php avec action=update + tous les champs
12. php/civil.php → UPDATE avec prepared statement
13. Retour { success: true } → le JS rafraîchit la vue
```

---

## 5. Authentification & Contrôle d'accès

### 5.1 Inscription

1. `register.html` charge la liste des groupes via `GET /php/register.php`
2. L'utilisateur soumet le formulaire (`js/register.js`)
3. `POST /php/register.php` crée le compte avec :
   - Mot de passe hashé (`PASSWORD_DEFAULT` / bcrypt)
   - Grade par défaut = 1, Division = 1
   - Statut = `pending` (nécessite validation admin)

### 5.2 Connexion

1. `login.html` → `js/login.js` soumet le formulaire
2. `POST /php/login.php` appelle `login()` de `init.php`
3. Vérification `authorized()` (statut = `accepted`)
4. Session peuplée : `user`, `group`, `grade`, `division`, `subdivision`, power levels
5. Retour JSON : `{ success: true/false, message, id_group }`
6. Redirection vers le dashboard correspondant au groupe

### 5.3 Contrôle d'accès par grade

Dans `js/mdt_police.js` :

```javascript
// Les grades >= 9 (Commandant+) voient le bouton Admin
if (user.grade_level >= 9) { /* afficher bouton admin */ }

// Les grades < 7 n'ont pas accès aux pages protégées
if (user.grade_level < 7) {
    // Retirer : rookie.html, note.html, formulaire_liste.html,
    // enquette.html, rapport_labo.html, bodycam.html,
    // cree_document_sast_sud.html, comptabilite.html
}
```

**Groupes :**

| ID Groupe | Nom | Description |
|-----------|-----|-------------|
| 1 | LSPD | Los Santos Police Department |
| 2 | BCSO | Blaine County Sheriff's Office |

---

## 6. Modules par service

### 6.1 Police (`police/`)

Module principal, le plus complet. ~70 pages HTML couvrant l'ensemble des opérations policières.

**Fonctionnalités :**
- Gestion complète des rapports (tickets, plaintes, incidents, tirs, arrestations…)
- Registre civil et casiers judiciaires
- Gestion des agents, grades, divisions
- Formation (guide rookie, procédures, ISTC, négociation, légitime défense)
- Tenues par grade (rookie à commandant, versions cérémonie et hiver)
- Dispatch, planning, absences
- Armement, saisies, véhicules de police
- Comptabilité, heures de service

### 6.2 Department of Justice (`doj/`)

Module pour le système judiciaire.

**Fonctionnalités :**
- Casiers judiciaires
- Code pénal
- Dossiers d'arrestation (DA)
- Enquêtes
- Rapports d'arrestation (RA)
- Annuaire

### 6.3 Gouvernement (`gouv/`)

Administration gouvernementale avec des fonctionnalités similaires au DOJ mais orientées gestion.

### 6.4 Médical (`medic/`)

Module pour les services médicaux (SAMD).

**Fonctionnalités :**
- Fiches civiles médicales
- Dossiers médicaux
- Bilans
- PPA (Protocole de Prise en Charge)
- Dashboard dédié

Possède sa propre structure CSS/JS/PHP isolée.

### 6.5 Armée (`army/`)

Module militaire — **en cours de développement**. Structure minimale avec dashboard, CSS et JS dédiés.

### 6.6 Administration (`admin/`)

Panneau de gestion des utilisateurs et des entreprises. Accessible aux grades >= 9 (Commandant+).

---

## 7. Frontend

### 7.1 Patterns communs

- **Aucun framework JS** — JavaScript vanilla avec manipulation DOM directe
- Initialisation via l'événement `DOMContentLoaded`
- **Fetch API** pour tous les appels AJAX
- **`location.origin`** utilisé pour construire les URLs API dynamiquement
- **`window.mdtUser`** — variable globale stockant l'utilisateur courant après `initMDT()`
- **Événement custom `userLoaded`** — dispatché après le chargement des données utilisateur

### 7.2 Initialisation MDT

```javascript
// Pattern récurrent dans les modules
async function initMDT() {
    const response = await fetch(`${ApiURL}/user.php`);
    const data = await response.json();
    window.mdtUser = data;
    document.dispatchEvent(new CustomEvent('userLoaded'));
}

document.addEventListener('DOMContentLoaded', () => {
    initMDT();
});
```

---

## 8. Styling

### 8.1 Design tokens (`css/ROOT.css`)

```css
:root {
    --bg-dark: #121212;
    --surface: #1E1E24;
    --surface-hover: #2A2A35;
    --primary: #3B82F6;
    --warning: #EF9744;
    --danger: #EF4444;
    --success: #10B981;
    --text-main: #F3F4F6;
    --text-muted: #9CA3AF;
    --border: #333340;
    --radius: 8px;
}
```

### 8.2 Feuille principale (`css/STYLE.css`)

- Importe `ROOT.css`
- Styles pour : formulaires login/register, sidebar avec catégories pliables, grille dashboard 3 colonnes, cartes civils (recherchés/hostiles), tableaux modernes, badges de statut
- **Responsive :**
  - ≤ 1200px : 3 colonnes → 2 colonnes
  - ≤ 800px : 2 colonnes → 1 colonne

### 8.3 CSS modulaire

27 fichiers CSS séparés, chacun lié à une fonctionnalité spécifique. Chaque page n'importe que les CSS dont elle a besoin.

---

## 9. Base de données

### 9.1 Schéma inféré

**Base principale :** `srrw6539_mdt_sasp_tlife`
**Base auth :** `srrw6539_mdttlife`

#### Tables utilisateurs

| Table | Colonnes principales |
|-------|---------------------|
| `mdt_users` | id, username, password, status, id_group, id_grade, id_division, id_subdivision, user_power_level |
| `mdt_users_groups` | id_group, group_name, group_power_level |
| `mdt_users_grades` | id_grade, grade_name, grade_power_level |
| `mdt_users_divisions` | id_division, division_name, division_power_level |
| `mdt_users_subdivisions` | id_subdivision, subdivision_name, subdivision_power_level |

#### Tables métier

| Table | Colonnes principales |
|-------|---------------------|
| `civils` | id, nom, prenom, sexe, nationalite, age, date_naissance, lieux_naissance, couleur_yeux, taille, poid, metier, grade_metier, organisation, grade_orga, individu_recherche, individu_dangereux, photo, photos, permis_conduire, permis_arme, permis_chasse, telephone, email, date_enregistrement, date_upd |
| `casiers` | id, nom, prenom, photo, faits (JSON), date_enregistrement, date_upd |
| `mgt_police_agents` | id, grade, … |

### 9.2 Remarques

- Le champ `faits` des casiers est stocké en **JSON**
- Les photos des civils sont stockées dans le dossier `uploads/`
- **Incohérence de nommage :** `mdt_users` vs `users`, `users_groups` vs `mdt_users_groups` entre login.php et register.php

---

## 10. Prérequis & Installation

### 10.1 Prérequis

- **Serveur web** : Apache ou Nginx avec PHP 7.4+
- **Base de données** : MySQL 5.7+ ou MariaDB 10.3+
- **Extensions PHP** : `mysqli`, `session`, `json`
- **Navigateur** : Chrome/Edge moderne (pour le support `<dialog>`, `fetch`, ES modules)

### 10.2 Étapes d'installation

**1. Cloner / déposer les fichiers**

Placez le contenu du projet dans le répertoire racine de votre serveur web ou dans un sous-dossier accessible.

**2. Configurer la base de données**

Créez les tables nécessaires dans votre base MySQL. Modifiez les identifiants dans `php/init.php` :

```php
define('HOST', 'localhost');
define('USER', 'votre_utilisateur');
define('PASS', 'votre_mot_de_passe');
define('DB_NAME', 'srrw6539_mdt_sasp_tlife');
```

> **Note :** Les mêmes identifiants sont dupliqués dans `php/civil.php` et `php/casier.php`. Pensez à les harmoniser.

**3. Configurer les permissions**

Assurez-vous que le dossier `uploads/` est accessible en écriture par le serveur web :

```bash
chmod 755 uploads/
```

**4. Configurer le vhost Apache/Nginx**

Exemple de configuration Apache minimale :

```apache
<VirtualHost *:80>
    ServerName mdt.t-life.local
    DocumentRoot /chemin/vers/MDT_V2

    <Directory /chemin/vers/MDT_V2>
        AllowOverride All
        Require all granted
    </Directory>

    Header set Content-Security-Policy "frame-ancestors 'self' https://cfx-nui-*"
</VirtualHost>
```

**5. Accéder à l'application**

- Page de connexion : `http://votre-domaine/login.html`
- Inscription : `http://votre-domaine/register.html`
- Le premier compte créé aura le statut `pending` et devra être validé via le panneau admin.

### 10.3 Intégration FiveM

Pour une utilisation dans un resource FiveM NUI, configurez le `fxmanifest.lua` :

```lua
fx_version 'cerulean'
game 'gta5'

ui_page 'html/index.html'

files {
    'html/index.html',
    'html/login.html',
    'html/**/*',
}
```

---

## 11. Sécurité

### 11.1 Points forts

| Mesure | Implémentation |
|--------|---------------|
| Hashage des mots de passe | `PASSWORD_DEFAULT` (bcrypt) |
| Protection SQL injection | Prepared statements (`mysqli->prepare`) partout |
| Cookies sécurisés | `HttpOnly`, `Secure`, `SameSite=None` |
| CSP | `frame-ancestors 'self' https://cfx-nui-*` |
| Contrôle d'accès | Vérifications groupe + grade + power level |

### 11.2 Points de vigilance

- **Identifiants DB en dur** dans `init.php`, `civil.php`, `casier.php` — à externaliser dans un fichier `.env` ou `config.php` non versionné
- **Absence de protection CSRF** sur les requêtes POST
- **Pas de rate limiting** sur les tentatives de connexion
- **`console.log()` dans `init.php`** (ligne 54) — peut corrompre les réponses JSON
- **Incohérence de nommage des tables** entre les fichiers d'authentification
- Certains endpoints n'effectuent pas de vérification d'authentification

---

## 12. Bonnes pratiques & Axes d'amélioration

### 12.1 Ce qui fonctionne bien

- Architecture modulaire claire : 1 fonctionnalité = 1 triplet HTML/JS/PHP
- Design tokens CSS cohérents avec `ROOT.css`
- Prepared statements systématiques
- Pattern `AppModal` réutilisable
- Dashboard responsive 3 colonnes

### 12.2 Axes d'amélioration recommandés

| Priorité | Action |
|----------|--------|
| **Haute** | Externaliser les identifiants DB dans un fichier de configuration non versionné |
| **Haute** | Ajouter une protection CSRF sur tous les formulaires POST |
| **Haute** | Corriger l'incohérence de nommage `mdt_users` vs `users` |
| **Haute** | Supprimer le `console.log()` de `init.php` |
| **Moyenne** | Factoriser le code dupliqué (AppModal, lightbox, connexions DB) dans des fichiers partagés |
| **Moyenne** | Ajouter un rate limiting sur `login.php` |
| **Moyenne** | Uniformiser la vérification d'authentification sur tous les endpoints |
| **Basse** | Migrer vers une architecture orientée objet ou un micro-framework |
| **Basse** | Ajouter des tests automatisés (PHPUnit pour le backend) |
| **Basse** | Documenter le schéma de base de données complet |
