feat: Version 3.6.2 - Correctifs tâches #17-20

- #17: Amélioration gestion des secteurs et statistiques
- #18: Optimisation services API et logs
- #19: Corrections Flutter widgets et repositories
- #20: Fix création passage - détection automatique ope_users.id vs users.id

Suppression dossier web/ (migration vers app Flutter)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-16 14:11:15 +01:00
parent 7b78037175
commit 232940b1eb
196 changed files with 8483 additions and 7966 deletions

View File

@@ -2,6 +2,9 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:path_provider/path_provider.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:geosector_app/core/data/models/user_model.dart';
@@ -65,16 +68,44 @@ class ApiService {
headers['X-App-Identifier'] = _appIdentifier;
_dio.options.headers.addAll(headers);
// Gestionnaire de cookies pour les sessions PHP
// Utilise CookieJar en mémoire (cookies maintenus pendant la durée de vie de l'app)
final cookieJar = CookieJar();
_dio.interceptors.add(CookieManager(cookieJar));
debugPrint('🍪 [API] Gestionnaire de cookies activé');
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
debugPrint('🌐 [API] Requête: ${options.method} ${options.path}');
debugPrint('🔑 [API] _sessionId présent: ${_sessionId != null}');
debugPrint('🔑 [API] Headers: ${options.headers}');
if (_sessionId != null) {
debugPrint('🔑 [API] Token: Bearer ${_sessionId!.substring(0, 20)}...');
options.headers[AppKeys.sessionHeader] = 'Bearer $_sessionId';
} else {
debugPrint('⚠️ [API] PAS DE TOKEN - Requête non authentifiée');
}
handler.next(options);
},
onError: (DioException error, handler) {
if (error.response?.statusCode == 401) {
_sessionId = null;
final path = error.requestOptions.path;
debugPrint('❌ [API] Erreur 401 sur: $path');
// Ne pas reset le token pour les requêtes non critiques
final nonCriticalPaths = [
'/users/device-info',
'/chat/rooms',
];
final isNonCritical = nonCriticalPaths.any((p) => path.contains(p));
if (isNonCritical) {
debugPrint('⚠️ [API] Requête non critique - Token conservé');
} else {
debugPrint('❌ [API] Requête critique - Token invalidé');
_sessionId = null;
}
}
handler.next(error);
},
@@ -1066,15 +1097,21 @@ class ApiService {
if (data.containsKey('session_id')) {
final sessionId = data['session_id'];
if (sessionId != null) {
debugPrint('🔐 [LOGIN] Token reçu du serveur: $sessionId');
debugPrint('🔐 [LOGIN] Longueur token: ${sessionId.toString().length}');
setSessionId(sessionId);
debugPrint('🔐 [LOGIN] Token stocké dans _sessionId');
// Collecter et envoyer les informations du device après login réussi
debugPrint('📱 Collecte des informations device après login...');
DeviceInfoService.instance.collectAndSendDeviceInfo().then((_) {
debugPrint('✅ Informations device collectées et envoyées');
}).catchError((error) {
debugPrint('⚠️ Erreur lors de l\'envoi des infos device: $error');
// Ne pas bloquer le login si l'envoi des infos device échoue
// Délai de 1 seconde pour laisser la session PHP se stabiliser
debugPrint('📱 Collecte des informations device après login (délai 1s)...');
Future.delayed(const Duration(seconds: 1), () {
DeviceInfoService.instance.collectAndSendDeviceInfo().then((_) {
debugPrint('✅ Informations device collectées et envoyées');
}).catchError((error) {
debugPrint('⚠️ Erreur lors de l\'envoi des infos device: $error');
// Ne pas bloquer le login si l'envoi des infos device échoue
});
});
}
}