Files
recipe-app/flutter/lib/features/admin/domain/admin_ai_trace_detail.dart
T
Nils-Johan Gynther 67a7590525
Test Suite / backend-pr-quick (push) Has been skipped
Test Suite / quick-import-pr-quick (push) Has been skipped
Test Suite / backend-full (push) Successful in 12m45s
Test Suite / flutter-quality (push) Failing after 7m24s
feat(ai): add AI trace tracking and admin panel
- Add AiTrace model to Prisma schema with relations to User
- Implement AiTraceService with CRUD operations for AI traces
- Add new admin panel for AI traces with filtering and detail views
- Integrate trace persistence in receipt import flow
- Add API endpoints for listing and retrieving AI traces
- Update Flutter admin UI with new AI tab and navigation
- Add new domain models for AI traces and details
- Add migration for AiTrace table creation

BREAKING CHANGE: None
2026-05-21 17:33:21 +02:00

76 lines
2.5 KiB
Dart

import 'admin_ai_trace.dart';
class AdminAiTraceDetail {
final String id;
final AdminAiTraceSource source;
final AdminAiTraceStatus status;
final DateTime createdAt;
final int userId;
final String userLabel;
final int? sessionId;
final String? fileName;
final String? model;
final int? durationMs;
final int? retryCount;
final int? chunkCount;
final List<String> warnings;
final String? error;
final String? prompt;
final String? rawOutput;
final Map<String, dynamic>? normalizedOutput;
final Map<String, dynamic> summary;
const AdminAiTraceDetail({
required this.id,
required this.source,
required this.status,
required this.createdAt,
required this.userId,
required this.userLabel,
required this.sessionId,
required this.fileName,
required this.model,
required this.durationMs,
required this.retryCount,
required this.chunkCount,
required this.warnings,
required this.error,
required this.prompt,
required this.rawOutput,
required this.normalizedOutput,
required this.summary,
});
factory AdminAiTraceDetail.fromJson(Map<String, dynamic> json) {
final warningsRaw = (json['warnings'] as List<dynamic>?) ?? const [];
final normalizedOutputMap = json['normalizedOutput'] is Map
? Map<String, dynamic>.from(json['normalizedOutput'] as Map)
: null;
final summaryMap = json['summary'] is Map
? Map<String, dynamic>.from(json['summary'] as Map)
: const <String, dynamic>{};
return AdminAiTraceDetail(
id: (json['id'] ?? '').toString(),
source: AdminAiTraceSourceX.fromApi(json['source']?.toString()),
status: AdminAiTraceStatusX.fromApi(json['status']?.toString()),
createdAt: DateTime.tryParse((json['createdAt'] ?? '').toString()) ??
DateTime.fromMillisecondsSinceEpoch(0),
userId: (json['userId'] as num?)?.toInt() ?? 0,
userLabel: (json['userLabel'] ?? '').toString(),
sessionId: (json['sessionId'] as num?)?.toInt(),
fileName: json['fileName']?.toString(),
model: json['model']?.toString(),
durationMs: (json['durationMs'] as num?)?.toInt(),
retryCount: (json['retryCount'] as num?)?.toInt(),
chunkCount: (json['chunkCount'] as num?)?.toInt(),
warnings: warningsRaw.map((entry) => entry.toString()).toList(),
error: json['error']?.toString(),
prompt: json['prompt']?.toString(),
rawOutput: json['rawOutput']?.toString(),
normalizedOutput: normalizedOutputMap,
summary: summaryMap,
);
}
}