Initial handling of activity logs

This commit is contained in:
2026-02-22 14:14:16 +08:00
parent b581bdf7be
commit 56504b9e8a
2 changed files with 124 additions and 15 deletions
+42 -9
View File
@@ -16,6 +16,39 @@ import 'tickets_provider.dart';
import 'user_offices_provider.dart';
import '../utils/app_time.dart';
// Helper to insert activity log rows while sanitizing nulls and
// avoiding exceptions from malformed payloads. Accepts either a Map
// or a List<Map>.
Future<void> _insertActivityRows(dynamic client, dynamic rows) async {
try {
if (rows == null) return;
if (rows is List) {
final sanitized = rows
.map((r) {
if (r is Map) {
final m = Map<String, dynamic>.from(r);
m.removeWhere((k, v) => v == null);
return m;
}
return null;
})
.whereType<Map<String, dynamic>>()
.toList();
if (sanitized.isEmpty) return;
await client.from('task_activity_logs').insert(sanitized);
} else if (rows is Map) {
final m = Map<String, dynamic>.from(rows);
m.removeWhere((k, v) => v == null);
await client.from('task_activity_logs').insert(m);
}
} catch (e) {
// Log for debugging but don't rethrow to avoid breaking caller flows
try {
debugPrint('[insertActivityRows] insert failed: $e');
} catch (_) {}
}
}
/// Task query parameters for server-side pagination and filtering.
class TaskQuery {
/// Creates task query parameters.
@@ -337,7 +370,7 @@ class TasksController {
if (taskId == null) return;
try {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': actorId,
'action_type': 'created',
@@ -549,13 +582,13 @@ class TasksController {
try {
final actorId = _client.auth.currentUser?.id;
if (status == 'in_progress') {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': actorId,
'action_type': 'started',
});
} else if (status == 'completed') {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': actorId,
'action_type': 'completed',
@@ -678,7 +711,7 @@ class TasksController {
if (onDuty.isEmpty) {
// record a failed auto-assign attempt for observability
try {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': null,
'action_type': 'auto_assign_failed',
@@ -726,7 +759,7 @@ class TasksController {
if (candidates.isEmpty) {
try {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': null,
'action_type': 'auto_assign_failed',
@@ -752,7 +785,7 @@ class TasksController {
});
try {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': null,
'action_type': 'assigned',
@@ -773,7 +806,7 @@ class TasksController {
// ignore: avoid_print
print('autoAssignTask error for task=$taskId: $e\n$st');
try {
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': null,
'action_type': 'auto_assign_failed',
@@ -859,7 +892,7 @@ class TaskAssignmentsController {
},
)
.toList();
await _client.from('task_activity_logs').insert(logRows);
await _insertActivityRows(_client, logRows);
} catch (_) {
// non-fatal
}
@@ -876,7 +909,7 @@ class TaskAssignmentsController {
// Record a reassignment event (who removed -> who added)
try {
final actorId = _client.auth.currentUser?.id;
await _client.from('task_activity_logs').insert({
await _insertActivityRows(_client, {
'task_id': taskId,
'actor_id': actorId,
'action_type': 'reassigned',