docs/60-administration/99-technique.md —
ce document se lit aussi dans le dépôt, sans serveur.
Administration — le côté technique
Les fichiers
| Rôle | Fichier |
|---|---|
| Écran utilisateurs | public/erp/utilisateurs.php + public/erp/assets/js/pages/utilisateurs-2.js |
| API | src/Http/Controllers/AdminController.php, AuthController.php |
| Données | src/Repository/UserRepository.php |
| Jetons | src/Auth/JwtService.php |
| Second facteur | src/Auth/ + pragmarx/google2fa |
| Verrouillage | src/Auth/LoginThrottle.php |
| Garde de route | src/Http/Middleware/ModuleAccessMiddleware.php |
| Garde dans un contrôleur | src/Http/ModuleAccess.php |
| Écran sécurité | public/erp/securite.php |
| API sécurité | src/Http/Controllers/SecurityController.php |
| Le caviardage | src/Retention/KeyRedactor.php |
| Les candidats | src/Retention/RedactionCandidateRepository.php |
| Les documents Pro | src/Repository/ProDocumentRepository.php |
| InnerPerf | public/erp/innerperf.php, src/Http/Controllers/InnerPerfController.php |
| Le barème | src/InnerPerf/ScoreRules.php |
| Données InnerPerf | src/Repository/InnerPerfRepository.php |
| Le temps | src/Support/Clock.php |
Les tables
users, user_modules, refresh_tokens, auth_challenges, audit_logs.
InnerPerf n'a pas de table. Tout se recalcule depuis audit_logs à chaque lecture : un score stocké serait faux le jour où le barème change.
Les jetons
Ils vivent dans des cookies HttpOnly, invisibles au JavaScript. Le navigateur ne garde en clair que le profil d'affichage.
Un jeton rejoué ferme toutes les sessions de l'utilisateur — voir auth.refresh_reuse dans le journal d'audit.
Les routes de la page Sécurité
| Route | Qui |
|---|---|
GET /v1/securite/orders, POST /v1/securite/preview | Module orders, lecture |
POST /v1/securite/redact | Administrateur |
POST /v1/securite/reveal, /restore | Administrateur + 10 par minute |
Les constantes qui décident
RedactionCandidateRepository::REDACT_AFTER_DAYS = 30
ProDocumentRepository::listExpired($retentionDays = 60)
KeyRedactor::MARKER = '*redacted*'
KeyRedactor::F_IDENTIFIER = [ … ] // les champs qui portent un identifiant
ScoreRules::WEIGHTS // le barème, action par action
ScoreRules::PLAFONDS // les gestes répétables, et leur plafond/jour
InnerPerfController::DEFAULT_GAP_MINUTES = 15
InnerPerfController::LONE_SESSION_SECONDS = 120
F_IDENTIFIER est la liste de référence des champs sensibles. Elle est publique et empruntée par Woo\ChampsCle, que la recherche et le stock utilisent — de sorte qu'un champ connu de l'un est connu de l'autre par construction, jamais par recopie.
REDACT_AFTER_DAYS est aussi un plancher : l'API refuse un délai plus court que la constante.
Les modules appliqués
const MODULES_APPLIQUES = ['orders', 'support', 'finance', 'hr', 'suppliers', 'analytics'];
Cette liste, côté écran, doit rester alignée sur AdminController. Elle ne donne aucun droit — elle décide seulement de ce que l'écran propose de cocher.
Les tests
tests/Unit/JwtServiceTest.php, tests/Unit/LoginThrottleTest.php, tests/Unit/DroitsDeModuleTest.php, tests/Unit/CoutDeHachageTest.php, tests/Unit/VocabulaireAuditTest.php, tests/Unit/ChampsCleTest.php, tests/Unit/SurfacesPubliquesTest.php, tests/Unit/EtatDeStockTest.php (le marqueur n'est pas un numéro), tests/Unit/InnerPerfScoreTest.php.