leafittome/lib/features/plants/data/plant_diagnosis_service.dart
cschlaefke b665bae95f Diagnose-Feinschliff: Art-Abgleich, nur Fließtext, konsequentes Du
Die angegebene Art ist jetzt eine unbestätigte Angabe: Claude prüft
selbst, welche Pflanze zu sehen ist, beurteilt bei Abweichung die
Pflanze im Bild und meldet matchesSpecies=false — die App zeigt dann
einen Warnhinweis im Ergebnis-Sheet. Prompt verbietet HTML/Markdown
(kein <br>) und schreibt durchgängiges Duzen vor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 22:39:45 +02:00

65 lines
2.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:convert';
import 'dart:typed_data';
import 'package:cloud_functions/cloud_functions.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
/// Ergebnis der KI-Krankheits-Diagnose (Cloud Function diagnosePlant).
class DiagnosisResult {
const DiagnosisResult({
required this.healthy,
required this.matchesSpecies,
required this.summary,
required this.details,
required this.treatment,
required this.prevention,
});
final bool healthy;
/// false, wenn das Foto laut KI eindeutig eine andere Pflanzenart zeigt
/// als die im Profil hinterlegte (z. B. versehentlich falsches Foto).
final bool matchesSpecies;
final String summary;
final String details;
final String treatment;
final String prevention;
}
class PlantDiagnosisService {
PlantDiagnosisService(this._functionsGetter);
// Lazy, damit Widget-Tests ohne initialisiertes Firebase auskommen —
// FirebaseFunctions.instanceFor wirft sonst schon beim Erzeugen.
final FirebaseFunctions Function() _functionsGetter;
/// Schickt das Foto an die Cloud Function (Claude) dauert einige Sekunden.
/// [speciesHint] ist die bekannte Art der Pflanze und hilft der Diagnose.
Future<DiagnosisResult> diagnose(
Uint8List imageBytes, {
String? speciesHint,
}) async {
final callable = _functionsGetter().httpsCallable('diagnosePlant');
final response = await callable.call<Map<String, dynamic>>({
'imageBase64': base64Encode(imageBytes),
if (speciesHint != null && speciesHint.trim().isNotEmpty)
'speciesHint': speciesHint.trim(),
});
final data = response.data;
return DiagnosisResult(
healthy: data['healthy'] as bool? ?? false,
matchesSpecies: data['matchesSpecies'] as bool? ?? true,
summary: data['summary'] as String? ?? '',
details: data['details'] as String? ?? '',
treatment: data['treatment'] as String? ?? '',
prevention: data['prevention'] as String? ?? '',
);
}
}
final plantDiagnosisServiceProvider = Provider<PlantDiagnosisService>((ref) {
return PlantDiagnosisService(
() => FirebaseFunctions.instanceFor(region: 'europe-west3'),
);
});