import 'admin_ai_trace.dart'; class AdminAiWarning { final String code; final String kind; final String title; final String message; final String severity; final String? location; final int? itemIndex; final String? productName; const AdminAiWarning({ required this.code, required this.kind, required this.title, required this.message, required this.severity, required this.location, required this.itemIndex, required this.productName, }); factory AdminAiWarning.fromJson(Map json) { return AdminAiWarning( code: (json['code'] ?? '').toString(), kind: (json['kind'] ?? '').toString(), title: (json['title'] ?? '').toString(), message: (json['message'] ?? '').toString(), severity: (json['severity'] ?? '').toString(), location: json['location']?.toString(), itemIndex: (json['itemIndex'] as num?)?.toInt(), productName: json['productName']?.toString(), ); } factory AdminAiWarning.fromLegacy(String value) { final trimmed = value.trim(); final parts = trimmed.split(':'); final kind = parts.isNotEmpty ? parts.first : 'parse'; final code = parts.length > 1 ? parts.sublist(1).join(':') : trimmed; return AdminAiWarning( code: code, kind: kind, title: trimmed, message: trimmed, severity: 'warning', location: null, itemIndex: null, productName: null, ); } } 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 warnings; final List legacyWarnings; final String? error; final String? prompt; final String? rawOutput; final Map? normalizedOutput; final Map 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.legacyWarnings, required this.error, required this.prompt, required this.rawOutput, required this.normalizedOutput, required this.summary, }); factory AdminAiTraceDetail.fromJson(Map json) { final warningsRaw = (json['warnings'] as List?) ?? const []; final legacyWarningsRaw = (json['legacyWarnings'] as List?) ?? const []; final normalizedOutputMap = json['normalizedOutput'] is Map ? Map.from(json['normalizedOutput'] as Map) : null; final summaryMap = json['summary'] is Map ? Map.from(json['summary'] as Map) : const {}; 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) { if (entry is Map) { return AdminAiWarning.fromJson(Map.from(entry)); } return AdminAiWarning.fromLegacy(entry.toString()); }) .toList(), legacyWarnings: legacyWarningsRaw.map((entry) => entry.toString()).toList(), error: json['error']?.toString(), prompt: json['prompt']?.toString(), rawOutput: json['rawOutput']?.toString(), normalizedOutput: normalizedOutputMap, summary: summaryMap, ); } }