import 'dart:convert'; import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart'; import 'package:brick_supabase/brick_supabase.dart'; import '../utils/app_time.dart'; /// Event log for a programmer task. Mirrors [TaskActivityLog] but keyed to /// `programmer_tasks`. `actionType` values: created, started, paused, resumed, /// completed, cancelled, assigned, reassigned. @ConnectOfflineFirstWithSupabase( supabaseConfig: SupabaseSerializable(tableName: 'programmer_task_activity_logs'), ) class ProgrammerTaskActivityLog extends OfflineFirstWithSupabaseModel { final String id; final String taskId; final String? actorId; final String actionType; final Map? meta; final DateTime createdAt; ProgrammerTaskActivityLog({ required this.id, required this.taskId, this.actorId, required this.actionType, this.meta, required this.createdAt, }); factory ProgrammerTaskActivityLog.fromMap(Map map) { final id = map['id'] == null ? '' : map['id'].toString(); final taskId = map['task_id'] == null ? '' : map['task_id'].toString(); final actorId = map['actor_id']?.toString(); final actionType = (map['action_type'] as String?) ?? 'unknown'; Map? meta; final rawMeta = map['meta']; if (rawMeta is Map) { meta = rawMeta; } else if (rawMeta is Map) { meta = rawMeta.map((k, v) => MapEntry(k.toString(), v)); } else if (rawMeta is String && rawMeta.isNotEmpty) { try { final decoded = jsonDecode(rawMeta); if (decoded is Map) { meta = decoded.map((k, v) => MapEntry(k.toString(), v)); } } catch (_) { meta = null; } } final rawCreated = map['created_at']; DateTime createdAt; if (rawCreated is DateTime) { createdAt = AppTime.toAppTime(rawCreated); } else if (rawCreated is String) { try { createdAt = AppTime.parse(rawCreated); } catch (_) { createdAt = AppTime.now(); } } else { createdAt = AppTime.now(); } return ProgrammerTaskActivityLog( id: id, taskId: taskId, actorId: actorId, actionType: actionType, meta: meta, createdAt: createdAt, ); } }