feat(ai-training): ajout validation OpenCV, gestion des logs et modération des contributions

- Backend IA :
  - Intégration d'OpenCV (WebAssembly) pour la détection et certification des cibles (anneaux concentriques, confiance).
  - Ajout du système de journalisation complet des uploads (SQLite, IP, appareil, statut, métadonnées).
  - Implémentation du système de modération (bannissement/débannissement de wallets, rejet 403 avec motifs).
  - Harmonisation des codes d'erreur et messages JSON (UPLOAD_SUCCESS, WALLET_BANNED, etc.).
  - Dashboard Next.js : page dédiée aux logs avec filtres, export CSV et actions de modération en un clic.
- Application Mobile (Flutter) :
  - Encapsulation des réponses d'export dans AiExportResult avec gestion fine des erreurs et statuts.
  - Mise à jour du disclaimer de participation à l'entraînement IA avec avertissements stricts de bannissement.
  - Révocation de l'envoi de photos et affichage d'un bandeau explicatif en cas de suspension.
  - Ajout d'un bouton manuel « Actualiser mon statut » dans les paramètres pour synchroniser l'état du compte.
  - Possibilité de configurer l'URL/IP du serveur IA directement depuis les paramètres.
This commit is contained in:
streaper2
2026-08-25 12:16:29 +02:00
parent 0374a7611e
commit 44ac4462a6
14 changed files with 2869 additions and 141 deletions
+10 -7
View File
@@ -241,15 +241,18 @@ class AnalysisProvider extends ChangeNotifier {
/// Exporte l'image et le json vers le backend IA.
/// [sessionId], [distance] et [weapon] proviennent du SessionProvider de
/// l'écran appelant, pour que le dataset contienne les vraies métadonnées.
Future<bool> exportToAiBackend({
Future<AiExportResult> exportToAiBackend({
String? sessionId,
int? distance,
String? weapon,
}) async {
if (_imagePath == null || _targetType == null) {
_errorMessage = "Impossible d'export : image ou type de cible manquant.";
_errorMessage = "Impossible d'exporter : image ou type de cible manquant.";
notifyListeners();
return false;
return AiExportResult.error(
code: 'MISSING_DATA',
message: "Impossible d'exporter : image ou type de cible manquant.",
);
}
final service = AiExportService();
@@ -257,7 +260,7 @@ class AnalysisProvider extends ChangeNotifier {
_state = AnalysisState.loading;
notifyListeners();
final success = await service.exportData(
final result = await service.exportData(
imagePath: _imagePath!,
sessionId: sessionId ?? 'export',
targetType: _targetType!,
@@ -270,11 +273,11 @@ class AnalysisProvider extends ChangeNotifier {
);
_state = AnalysisState.success;
if (!success) {
_errorMessage = "Échec de l'export vers le serveur IA.";
if (!result.isSuccess) {
_errorMessage = result.message;
}
notifyListeners();
return success;
return result;
}
/// Save the session