fix: bulkCreateTasks force-refreshes _allTasks instead of merging task-by-task

Server is the authoritative kanban categorizer. After a bulk insert,
re-fetch /api/tasks/ so the kanban view reflects exactly what the
server sees, including any column re-categorizations the client's
in-memory upsert wouldn't compute. One extra round-trip per onboarding
submission, called once per session typically.

Eliminates the entire bug class where DataManager.updateTask had to
correctly compute kanban column placement from the response's
kanbanColumn field. With force-refresh, the server is the source of
truth — fewer ways for the client cache to drift.

Refs gitea#2
This commit is contained in:
Trey t
2026-04-25 10:39:53 -05:00
parent dc6d3525fa
commit 60ae14c79e
@@ -640,9 +640,15 @@ object APILayer {
/** /**
* Atomically creates 1-50 tasks via POST /api/tasks/bulk/. The whole * Atomically creates 1-50 tasks via POST /api/tasks/bulk/. The whole
* batch succeeds or fails together on the server. On success, every * batch succeeds or fails together on the server. On success, force-
* returned task is merged into DataManager.allTasks so observing views * refreshes _allTasks from the server — the server is the
* render the new batch immediately. * authoritative kanban categorizer, and a single round-trip
* eliminates any drift between the per-task `kanbanColumn` hint and
* the global kanban view.
*
* This is the bug-class fix for gitea#2: the previous per-task
* updateTask loop was a no-op when _allTasks was null (fresh launch
* after onboarding), silently dropping the new tasks from cache.
*/ */
suspend fun bulkCreateTasks(request: BulkCreateTasksRequest): ApiResult<BulkCreateTasksResponse> { suspend fun bulkCreateTasks(request: BulkCreateTasksRequest): ApiResult<BulkCreateTasksResponse> {
val token = getToken() ?: return ApiResult.Error("Not authenticated", 401) val token = getToken() ?: return ApiResult.Error("Not authenticated", 401)
@@ -650,7 +656,9 @@ object APILayer {
if (result is ApiResult.Success) { if (result is ApiResult.Success) {
DataManager.setTotalSummary(result.data.summary) DataManager.setTotalSummary(result.data.summary)
result.data.tasks.forEach { DataManager.updateTask(it) } // Authoritative refresh — replaces any placeholder kanban
// shell from updateTask with proper server data.
getTasks(forceRefresh = true)
} }
return result return result
} }