Migrate TaskService + ResidenceService to ctx-aware repos
Backend CI / Test (push) Has been cancelled
Backend CI / Contract Tests (push) Has been cancelled
Backend CI / Build (push) Has been cancelled
Backend CI / Lint (push) Has been cancelled
Backend CI / Secret Scanning (push) Has been cancelled

Every public method on TaskService and ResidenceService now takes
ctx context.Context as the first arg and routes its repo calls through
.WithContext(ctx). With otelgorm registered, this means every API
endpoint backed by these two services produces a flame graph in Jaeger
where the SQL spans nest under the parent HTTP request span — instead
of appearing as orphaned queries.

Endpoints now fully traced (HTTP → service → SQL):
- GET    /api/tasks/                       (already shipped)
- GET    /api/tasks/by-residence/:id/      (already shipped)
- GET    /api/tasks/:id/
- POST   /api/tasks/
- POST   /api/tasks/bulk/
- PUT    /api/tasks/:id/
- DELETE /api/tasks/:id/
- POST   /api/tasks/:id/in-progress/
- POST   /api/tasks/:id/cancel/
- POST   /api/tasks/:id/uncancel/
- POST   /api/tasks/:id/archive/
- POST   /api/tasks/:id/unarchive/
- POST   /api/tasks/:id/complete/
- POST   /api/tasks/:id/quick-complete/
- GET    /api/tasks/completions/* (CRUD)
- GET    /api/static_data/ (categories, priorities, frequencies)
- GET    /api/residences/
- GET    /api/residences/my/
- GET    /api/residences/summary/
- GET    /api/residences/:id/
- POST   /api/residences/
- PUT    /api/residences/:id/
- DELETE /api/residences/:id/
- Share-code + member management endpoints
- GET    /api/residences/:id/report/

Mechanical work: ~50 method signatures, ~80 handler call sites,
~25 test call sites updated. Internal sendTaskCompletedNotification
helper also takes ctx so background notification SQL nests correctly.

The remaining services (ContractorService, DocumentService,
AuthService, NotificationService, SubscriptionService) follow the same
pattern; they continue to emit untraced SQL until migrated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-25 16:04:01 -05:00
parent 3f5bf21e09
commit 65a9aae4e5
9 changed files with 382 additions and 378 deletions
+110 -110
View File
@@ -43,7 +43,7 @@ func TestTaskService_CreateTask(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotZero(t, resp.Data.ID)
assert.Equal(t, "Fix leaky faucet", resp.Data.Title)
@@ -79,7 +79,7 @@ func TestTaskService_CreateTask_WithOptionalFields(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
// Note: Category and Priority are no longer preloaded for performance
// Client resolves from cache using CategoryID and PriorityID
@@ -120,7 +120,7 @@ func TestTaskService_CreateTask_WithTemplateID(t *testing.T) {
Title: "From template: " + tc.name,
TemplateID: tc.templateID,
}
resp, err := service.CreateTask(req, user.ID, time.Now().UTC())
resp, err := service.CreateTask(context.Background(), req, user.ID, time.Now().UTC())
require.NoError(t, err)
if tc.wantID == nil {
@@ -165,7 +165,7 @@ func TestTaskService_BulkCreateTasks(t *testing.T) {
{ResidenceID: residence.ID, Title: "Task C"},
},
}
resp, err := service.BulkCreateTasks(req, user.ID, time.Now().UTC())
resp, err := service.BulkCreateTasks(context.Background(), req, user.ID, time.Now().UTC())
require.NoError(t, err)
assert.Equal(t, 3, resp.CreatedCount)
assert.Len(t, resp.Tasks, 3)
@@ -198,7 +198,7 @@ func TestTaskService_BulkCreateTasks(t *testing.T) {
ResidenceID: residence.ID,
Tasks: []requests.CreateTaskRequest{}, // empty triggers the guard
}
_, err := service.BulkCreateTasks(req, user.ID, time.Now().UTC())
_, err := service.BulkCreateTasks(context.Background(), req, user.ID, time.Now().UTC())
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.task_list_empty")
var after int64
@@ -214,7 +214,7 @@ func TestTaskService_BulkCreateTasks(t *testing.T) {
{ResidenceID: residence.ID, Title: "Sneaky"},
},
}
_, err := service.BulkCreateTasks(req, other.ID, time.Now().UTC())
_, err := service.BulkCreateTasks(context.Background(), req, other.ID, time.Now().UTC())
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
})
@@ -227,7 +227,7 @@ func TestTaskService_BulkCreateTasks(t *testing.T) {
{ResidenceID: second.ID, Title: "Should land on batch residence"},
},
}
resp, err := service.BulkCreateTasks(req, user.ID, time.Now().UTC())
resp, err := service.BulkCreateTasks(context.Background(), req, user.ID, time.Now().UTC())
require.NoError(t, err)
require.Len(t, resp.Tasks, 1)
assert.Equal(t, residence.ID, resp.Tasks[0].ResidenceID)
@@ -251,7 +251,7 @@ func TestTaskService_CreateTask_AccessDenied(t *testing.T) {
}
now := time.Now().UTC()
_, err := service.CreateTask(req, otherUser.ID, now)
_, err := service.CreateTask(context.Background(), req, otherUser.ID, now)
// When creating a task, residence access is checked first
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
}
@@ -267,7 +267,7 @@ func TestTaskService_GetTask(t *testing.T) {
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
resp, err := service.GetTask(task.ID, user.ID)
resp, err := service.GetTask(context.Background(), task.ID, user.ID)
require.NoError(t, err)
assert.Equal(t, task.ID, resp.ID)
assert.Equal(t, "Test Task", resp.Title)
@@ -285,7 +285,7 @@ func TestTaskService_GetTask_AccessDenied(t *testing.T) {
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, owner.ID, "Test Task")
_, err := service.GetTask(task.ID, otherUser.ID)
_, err := service.GetTask(context.Background(), task.ID, otherUser.ID)
testutil.AssertAppError(t, err, http.StatusForbidden, "error.task_access_denied")
}
@@ -332,7 +332,7 @@ func TestTaskService_UpdateTask(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.UpdateTask(task.ID, user.ID, req, now)
resp, err := service.UpdateTask(context.Background(), task.ID, user.ID, req, now)
require.NoError(t, err)
assert.Equal(t, "Updated Title", resp.Data.Title)
assert.Equal(t, "Updated description", resp.Data.Description)
@@ -349,10 +349,10 @@ func TestTaskService_DeleteTask(t *testing.T) {
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
_, err := service.DeleteTask(task.ID, user.ID)
_, err := service.DeleteTask(context.Background(), task.ID, user.ID)
require.NoError(t, err)
_, err = service.GetTask(task.ID, user.ID)
_, err = service.GetTask(context.Background(), task.ID, user.ID)
assert.Error(t, err)
}
@@ -368,7 +368,7 @@ func TestTaskService_CancelTask(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
now := time.Now().UTC()
resp, err := service.CancelTask(task.ID, user.ID, now)
resp, err := service.CancelTask(context.Background(), task.ID, user.ID, now)
require.NoError(t, err)
assert.True(t, resp.Data.IsCancelled)
}
@@ -385,8 +385,8 @@ func TestTaskService_CancelTask_AlreadyCancelled(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
now := time.Now().UTC()
service.CancelTask(task.ID, user.ID, now)
_, err := service.CancelTask(task.ID, user.ID, now)
service.CancelTask(context.Background(), task.ID, user.ID, now)
_, err := service.CancelTask(context.Background(), task.ID, user.ID, now)
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.task_already_cancelled")
}
@@ -402,8 +402,8 @@ func TestTaskService_UncancelTask(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
now := time.Now().UTC()
service.CancelTask(task.ID, user.ID, now)
resp, err := service.UncancelTask(task.ID, user.ID, now)
service.CancelTask(context.Background(), task.ID, user.ID, now)
resp, err := service.UncancelTask(context.Background(), task.ID, user.ID, now)
require.NoError(t, err)
assert.False(t, resp.Data.IsCancelled)
}
@@ -420,7 +420,7 @@ func TestTaskService_ArchiveTask(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
now := time.Now().UTC()
resp, err := service.ArchiveTask(task.ID, user.ID, now)
resp, err := service.ArchiveTask(context.Background(), task.ID, user.ID, now)
require.NoError(t, err)
assert.True(t, resp.Data.IsArchived)
}
@@ -437,8 +437,8 @@ func TestTaskService_UnarchiveTask(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
now := time.Now().UTC()
service.ArchiveTask(task.ID, user.ID, now)
resp, err := service.UnarchiveTask(task.ID, user.ID, now)
service.ArchiveTask(context.Background(), task.ID, user.ID, now)
resp, err := service.UnarchiveTask(context.Background(), task.ID, user.ID, now)
require.NoError(t, err)
assert.False(t, resp.Data.IsArchived)
}
@@ -455,7 +455,7 @@ func TestTaskService_MarkInProgress(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Test Task")
now := time.Now().UTC()
resp, err := service.MarkInProgress(task.ID, user.ID, now)
resp, err := service.MarkInProgress(context.Background(), task.ID, user.ID, now)
require.NoError(t, err)
assert.True(t, resp.Data.InProgress)
}
@@ -477,7 +477,7 @@ func TestTaskService_CreateCompletion(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateCompletion(req, user.ID, now)
resp, err := service.CreateCompletion(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotZero(t, resp.Data.ID)
assert.Equal(t, task.ID, resp.Data.TaskID)
@@ -520,7 +520,7 @@ func TestTaskService_CreateCompletion_RecurringTask_ResetsInProgress(t *testing.
}
now := time.Now().UTC()
resp, err := service.CreateCompletion(req, user.ID, now)
resp, err := service.CreateCompletion(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotZero(t, resp.Data.ID)
@@ -558,7 +558,7 @@ func TestTaskService_GetCompletion(t *testing.T) {
}
db.Create(completion)
resp, err := service.GetCompletion(completion.ID, user.ID)
resp, err := service.GetCompletion(context.Background(), completion.ID, user.ID)
require.NoError(t, err)
assert.Equal(t, completion.ID, resp.ID)
assert.Equal(t, "Test notes", resp.Notes)
@@ -582,10 +582,10 @@ func TestTaskService_DeleteCompletion(t *testing.T) {
}
db.Create(completion)
_, err := service.DeleteCompletion(completion.ID, user.ID)
_, err := service.DeleteCompletion(context.Background(), completion.ID, user.ID)
require.NoError(t, err)
_, err = service.GetCompletion(completion.ID, user.ID)
_, err = service.GetCompletion(context.Background(), completion.ID, user.ID)
assert.Error(t, err)
}
@@ -623,7 +623,7 @@ func TestTaskService_CreateCompletion_TransactionIntegrity(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateCompletion(req, user.ID, now)
resp, err := service.CreateCompletion(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotZero(t, resp.Data.ID)
@@ -721,7 +721,7 @@ func TestTaskService_CreateCompletion_UpdateError_ReturnedNotSwallowed(t *testin
now := time.Now().UTC()
// This call will succeed because FindByID loads version=1, UpdateTx uses version=1, DB has version=1.
// To verify error propagation, we use the direct transaction test above.
resp, err := service.CreateCompletion(req, user.ID, now)
resp, err := service.CreateCompletion(context.Background(), req, user.ID, now)
require.NoError(t, err, "CreateCompletion should succeed with matching versions")
assert.NotZero(t, resp.Data.ID)
}
@@ -760,7 +760,7 @@ func TestTaskService_DeleteCompletion_OneTime_RestoresOriginalDueDate(t *testing
Notes: "Completed",
}
now := time.Now().UTC()
completionResp, err := service.CreateCompletion(req, user.ID, now)
completionResp, err := service.CreateCompletion(context.Background(), req, user.ID, now)
require.NoError(t, err)
// Confirm NextDueDate is nil after completion
@@ -769,7 +769,7 @@ func TestTaskService_DeleteCompletion_OneTime_RestoresOriginalDueDate(t *testing
assert.Nil(t, taskAfterComplete.NextDueDate, "NextDueDate should be nil after one-time completion")
// Delete the completion
_, err = service.DeleteCompletion(completionResp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), completionResp.Data.ID, user.ID)
require.NoError(t, err)
// Verify NextDueDate is restored to the original DueDate
@@ -820,7 +820,7 @@ func TestTaskService_DeleteCompletion_Recurring_RecalculatesFromLastCompletion(t
CompletedAt: &firstCompletedAt,
}
now := time.Now().UTC()
_, err = service.CreateCompletion(firstReq, user.ID, now)
_, err = service.CreateCompletion(context.Background(), firstReq, user.ID, now)
require.NoError(t, err)
// Second completion on Feb 15
@@ -830,7 +830,7 @@ func TestTaskService_DeleteCompletion_Recurring_RecalculatesFromLastCompletion(t
Notes: "Second completion",
CompletedAt: &secondCompletedAt,
}
resp, err := service.CreateCompletion(secondReq, user.ID, now)
resp, err := service.CreateCompletion(context.Background(), secondReq, user.ID, now)
require.NoError(t, err)
// NextDueDate should be Feb 15 + 30 days = Mar 17
@@ -843,7 +843,7 @@ func TestTaskService_DeleteCompletion_Recurring_RecalculatesFromLastCompletion(t
assert.Equal(t, expectedAfterSecond.Day(), taskAfterSecond.NextDueDate.Day())
// Delete the second (latest) completion
_, err = service.DeleteCompletion(resp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), resp.Data.ID, user.ID)
require.NoError(t, err)
// NextDueDate should be recalculated from the first completion: Jan 15 + 30 = Feb 14
@@ -895,7 +895,7 @@ func TestTaskService_DeleteCompletion_LastCompletion_RestoresDueDate(t *testing.
CompletedAt: &completedAt,
}
now := time.Now().UTC()
completionResp, err := service.CreateCompletion(req, user.ID, now)
completionResp, err := service.CreateCompletion(context.Background(), req, user.ID, now)
require.NoError(t, err)
// Verify NextDueDate was set to completedAt + 7 days
@@ -904,7 +904,7 @@ func TestTaskService_DeleteCompletion_LastCompletion_RestoresDueDate(t *testing.
require.NotNil(t, taskAfterComplete.NextDueDate)
// Delete the only completion
_, err = service.DeleteCompletion(completionResp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), completionResp.Data.ID, user.ID)
require.NoError(t, err)
// NextDueDate should be restored to original DueDate since no completions remain
@@ -923,7 +923,7 @@ func TestTaskService_GetCategories(t *testing.T) {
residenceRepo := repositories.NewResidenceRepository(db)
service := NewTaskService(taskRepo, residenceRepo)
categories, err := service.GetCategories()
categories, err := service.GetCategories(context.Background())
require.NoError(t, err)
assert.Greater(t, len(categories), 0)
@@ -941,7 +941,7 @@ func TestTaskService_GetPriorities(t *testing.T) {
residenceRepo := repositories.NewResidenceRepository(db)
service := NewTaskService(taskRepo, residenceRepo)
priorities, err := service.GetPriorities()
priorities, err := service.GetPriorities(context.Background())
require.NoError(t, err)
assert.Greater(t, len(priorities), 0)
@@ -958,7 +958,7 @@ func TestTaskService_GetFrequencies(t *testing.T) {
residenceRepo := repositories.NewResidenceRepository(db)
service := NewTaskService(taskRepo, residenceRepo)
frequencies, err := service.GetFrequencies()
frequencies, err := service.GetFrequencies(context.Background())
require.NoError(t, err)
assert.Greater(t, len(frequencies), 0)
}
@@ -981,7 +981,7 @@ func TestTaskService_SharedUserAccess(t *testing.T) {
task := testutil.CreateTestTask(t, db, residence.ID, owner.ID, "Test Task")
// Shared user should be able to see the task
resp, err := service.GetTask(task.ID, sharedUser.ID)
resp, err := service.GetTask(context.Background(), task.ID, sharedUser.ID)
require.NoError(t, err)
assert.Equal(t, task.ID, resp.ID)
@@ -991,7 +991,7 @@ func TestTaskService_SharedUserAccess(t *testing.T) {
Title: "Shared User Task",
}
now := time.Now().UTC()
_, err = service.CreateTask(req, sharedUser.ID, now)
_, err = service.CreateTask(context.Background(), req, sharedUser.ID, now)
require.NoError(t, err)
}
@@ -1017,7 +1017,7 @@ func TestTaskService_CreateTask_NextDueDateEqualsDueDate(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
require.NotNil(t, resp.Data.DueDate, "DueDate should be set")
require.NotNil(t, resp.Data.NextDueDate, "NextDueDate should be initialized")
@@ -1041,7 +1041,7 @@ func TestTaskService_CreateTask_NoDueDate_NextDueDateNil(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.Nil(t, resp.Data.DueDate, "DueDate should be nil")
assert.Nil(t, resp.Data.NextDueDate, "NextDueDate should be nil when no DueDate")
@@ -1073,7 +1073,7 @@ func TestTaskService_CreateTask_WithWeeklyFrequency(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotNil(t, resp.Data.FrequencyID, "FrequencyID should be saved")
assert.Equal(t, weeklyFreq.ID, *resp.Data.FrequencyID, "FrequencyID should match Weekly")
@@ -1105,7 +1105,7 @@ func TestTaskService_CreateTask_WithCustomFrequencyAndInterval(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotNil(t, resp.Data.FrequencyID, "FrequencyID should be saved")
assert.NotNil(t, resp.Data.CustomIntervalDays, "CustomIntervalDays should be saved")
@@ -1132,7 +1132,7 @@ func TestTaskService_CreateTask_FrequencyWithoutDueDate(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.NotNil(t, resp.Data.FrequencyID, "FrequencyID should be saved")
assert.Nil(t, resp.Data.NextDueDate, "NextDueDate should be nil when no DueDate")
@@ -1160,7 +1160,7 @@ func TestTaskService_CreateTask_WithPastDueDate(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err, "Creating task with past due date should not error")
require.NotNil(t, resp.Data.DueDate, "DueDate should be set")
assert.True(t, resp.Data.DueDate.Before(time.Now()), "DueDate should be in the past")
@@ -1183,7 +1183,7 @@ func TestTaskService_CreateTask_WithInProgressTrue(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.True(t, resp.Data.InProgress, "InProgress should be true in response")
@@ -1234,7 +1234,7 @@ func TestTaskService_CreateTask_AllOptionalFields(t *testing.T) {
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err)
assert.Equal(t, "Full task with all fields", resp.Data.Title)
@@ -1272,7 +1272,7 @@ func TestTaskService_CreateTask_CustomIntervalDaysWithoutFrequency(t *testing.T)
}
now := time.Now().UTC()
resp, err := service.CreateTask(req, user.ID, now)
resp, err := service.CreateTask(context.Background(), req, user.ID, now)
require.NoError(t, err, "Should save even without FrequencyID")
assert.NotNil(t, resp.Data.CustomIntervalDays, "CustomIntervalDays should be saved")
assert.Equal(t, 10, *resp.Data.CustomIntervalDays)
@@ -1300,7 +1300,7 @@ func TestTaskService_CreateTask_InvalidResidenceAccess(t *testing.T) {
}
now := time.Now().UTC()
_, err := service.CreateTask(req, stranger.ID, now)
_, err := service.CreateTask(context.Background(), req, stranger.ID, now)
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
}
@@ -1319,7 +1319,7 @@ func TestTaskService_CreateTask_NonExistentResidence(t *testing.T) {
}
now := time.Now().UTC()
_, err := service.CreateTask(req, user.ID, now)
_, err := service.CreateTask(context.Background(), req, user.ID, now)
require.Error(t, err, "Should error for non-existent residence")
// Should return forbidden since user has no access to non-existent residence
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
@@ -1357,7 +1357,7 @@ func TestTaskService_DeleteCompletion_OneTime_RestoresAndExitsKanbanCompleted(t
// Complete the task (sets NextDueDate to nil)
now := time.Now().UTC()
completionResp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
completionResp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID,
Notes: "Done",
}, user.ID, now)
@@ -1373,7 +1373,7 @@ func TestTaskService_DeleteCompletion_OneTime_RestoresAndExitsKanbanCompleted(t
"Task should be in completed state")
// Delete the completion
_, err = service.DeleteCompletion(completionResp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), completionResp.Data.ID, user.ID)
require.NoError(t, err)
// Verify NextDueDate restored to original DueDate
@@ -1425,7 +1425,7 @@ func TestTaskService_DeleteCompletion_Recurring_RestoresToOriginalDueDate(t *tes
// Complete on Apr 3
completedAt := time.Date(2026, 4, 3, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
completionResp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
completionResp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Weekly done", CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -1437,7 +1437,7 @@ func TestTaskService_DeleteCompletion_Recurring_RestoresToOriginalDueDate(t *tes
assert.Equal(t, 10, taskAfterComplete.NextDueDate.Day())
// Delete the completion
_, err = service.DeleteCompletion(completionResp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), completionResp.Data.ID, user.ID)
require.NoError(t, err)
// Verify NextDueDate restored to original DueDate (Apr 1)
@@ -1483,21 +1483,21 @@ func TestTaskService_DeleteCompletion_MultipleCompletions_SequentialDeletion(t *
// Completion 1: Jan 5
c1At := time.Date(2026, 1, 5, 10, 0, 0, 0, time.UTC)
c1Resp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
c1Resp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Completion 1", CompletedAt: &c1At,
}, user.ID, now)
require.NoError(t, err)
// Completion 2: Jan 12
c2At := time.Date(2026, 1, 12, 10, 0, 0, 0, time.UTC)
c2Resp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
c2Resp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Completion 2", CompletedAt: &c2At,
}, user.ID, now)
require.NoError(t, err)
// Completion 3: Jan 19
c3At := time.Date(2026, 1, 19, 10, 0, 0, 0, time.UTC)
c3Resp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
c3Resp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Completion 3", CompletedAt: &c3At,
}, user.ID, now)
require.NoError(t, err)
@@ -1509,7 +1509,7 @@ func TestTaskService_DeleteCompletion_MultipleCompletions_SequentialDeletion(t *
assert.Equal(t, 26, taskAfter3.NextDueDate.Day())
// Delete completion 3 (latest) -> recalc from completion 2: Jan 12 + 7 = Jan 19
_, err = service.DeleteCompletion(c3Resp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), c3Resp.Data.ID, user.ID)
require.NoError(t, err)
var taskAfterDel3 models.Task
db.First(&taskAfterDel3, task.ID)
@@ -1518,7 +1518,7 @@ func TestTaskService_DeleteCompletion_MultipleCompletions_SequentialDeletion(t *
"NextDueDate should be Jan 19 (completion 2: Jan 12 + 7)")
// Delete completion 2 (now latest) -> recalc from completion 1: Jan 5 + 7 = Jan 12
_, err = service.DeleteCompletion(c2Resp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), c2Resp.Data.ID, user.ID)
require.NoError(t, err)
var taskAfterDel2 models.Task
db.First(&taskAfterDel2, task.ID)
@@ -1527,7 +1527,7 @@ func TestTaskService_DeleteCompletion_MultipleCompletions_SequentialDeletion(t *
"NextDueDate should be Jan 12 (completion 1: Jan 5 + 7)")
// Delete completion 1 (last remaining) -> restore to original DueDate: Jan 1
_, err = service.DeleteCompletion(c1Resp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), c1Resp.Data.ID, user.ID)
require.NoError(t, err)
var taskAfterDel1 models.Task
db.First(&taskAfterDel1, task.ID)
@@ -1570,19 +1570,19 @@ func TestTaskService_DeleteCompletion_MiddleCompletion_KeepsLatest(t *testing.T)
// Create 3 completions
c1At := time.Date(2026, 2, 3, 10, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "First", CompletedAt: &c1At,
}, user.ID, now)
require.NoError(t, err)
c2At := time.Date(2026, 2, 10, 10, 0, 0, 0, time.UTC)
c2Resp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
c2Resp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Second", CompletedAt: &c2At,
}, user.ID, now)
require.NoError(t, err)
c3At := time.Date(2026, 2, 17, 10, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Third", CompletedAt: &c3At,
}, user.ID, now)
require.NoError(t, err)
@@ -1594,7 +1594,7 @@ func TestTaskService_DeleteCompletion_MiddleCompletion_KeepsLatest(t *testing.T)
assert.Equal(t, 24, taskBefore.NextDueDate.Day())
// Delete the MIDDLE completion (2nd)
_, err = service.DeleteCompletion(c2Resp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), c2Resp.Data.ID, user.ID)
require.NoError(t, err)
// NextDueDate should still be based on the latest (3rd): Feb 17 + 7 = Feb 24
@@ -1634,7 +1634,7 @@ func TestTaskService_DeleteCompletion_DoesNotRestoreInProgress(t *testing.T) {
// Complete it (sets InProgress = false)
now := time.Now().UTC()
completionResp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
completionResp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Completed",
}, user.ID, now)
require.NoError(t, err)
@@ -1644,7 +1644,7 @@ func TestTaskService_DeleteCompletion_DoesNotRestoreInProgress(t *testing.T) {
assert.False(t, taskAfterComplete.InProgress, "InProgress should be false after completion")
// Delete the completion
_, err = service.DeleteCompletion(completionResp.Data.ID, user.ID)
_, err = service.DeleteCompletion(context.Background(), completionResp.Data.ID, user.ID)
require.NoError(t, err)
// InProgress is NOT restored by DeleteCompletion
@@ -1674,7 +1674,7 @@ func TestTaskService_TaskWithNoDates(t *testing.T) {
Title: "No Date Task",
}
now := time.Now().UTC()
createResp, err := service.CreateTask(createReq, user.ID, now)
createResp, err := service.CreateTask(context.Background(), createReq, user.ID, now)
require.NoError(t, err)
// Verify dates are nil
@@ -1686,7 +1686,7 @@ func TestTaskService_TaskWithNoDates(t *testing.T) {
"Task with no due date should be in upcoming column")
// Complete it
completionResp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
completionResp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: createResp.Data.ID, Notes: "Done",
}, user.ID, now)
require.NoError(t, err)
@@ -1732,7 +1732,7 @@ func TestTaskService_TaskDueExactlyToday_Boundary(t *testing.T) {
assert.False(t, task.IsOverdueAt(today), "Task due today should NOT be overdue")
// Complete it
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Done today",
}, user.ID, today)
require.NoError(t, err)
@@ -1771,7 +1771,7 @@ func TestTaskService_TaskDueYesterday_IsOverdue(t *testing.T) {
assert.True(t, task.IsOverdueAt(today), "Task due yesterday should be overdue")
// Complete it
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Done late",
}, user.ID, today)
require.NoError(t, err)
@@ -1802,7 +1802,7 @@ func TestTaskService_TaskVeryFarFuture(t *testing.T) {
DueDate: &requests.FlexibleDate{Time: farFuture},
}
now := time.Now().UTC()
resp, err := service.CreateTask(createReq, user.ID, now)
resp, err := service.CreateTask(context.Background(), createReq, user.ID, now)
require.NoError(t, err)
assert.Equal(t, "upcoming_tasks", resp.Data.KanbanColumn,
@@ -1840,7 +1840,7 @@ func TestTaskService_RecurringTask_CompletedLate(t *testing.T) {
completedAt := time.Date(2026, 12, 15, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Late", CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -1884,7 +1884,7 @@ func TestTaskService_RecurringTask_CompletedEarly(t *testing.T) {
completedAt := time.Date(2026, 12, 14, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Early", CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -1937,7 +1937,7 @@ func TestTaskService_CustomIntervalEdgeCases(t *testing.T) {
completedAt := time.Date(2026, 6, 1, 12, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -1968,7 +1968,7 @@ func TestTaskService_CustomIntervalEdgeCases(t *testing.T) {
completedAt := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2014,7 +2014,7 @@ func TestTaskService_FrequencyWithNilOrZeroDays(t *testing.T) {
require.NoError(t, err)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Done once",
}, user.ID, now)
require.NoError(t, err)
@@ -2049,7 +2049,7 @@ func TestTaskService_FrequencyWithNilOrZeroDays(t *testing.T) {
require.NoError(t, err)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Done zero",
}, user.ID, now)
require.NoError(t, err)
@@ -2076,7 +2076,7 @@ func TestTaskService_VersionConflict(t *testing.T) {
// First update succeeds
newTitle := "Updated Once"
now := time.Now().UTC()
resp, err := service.UpdateTask(task.ID, user.ID, &requests.UpdateTaskRequest{
resp, err := service.UpdateTask(context.Background(), task.ID, user.ID, &requests.UpdateTaskRequest{
Title: &newTitle,
}, now)
require.NoError(t, err)
@@ -2154,7 +2154,7 @@ func TestTaskService_CreateCompletion_OneTime_NextDueDateBecomesNil(t *testing.T
require.NoError(t, err)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Done",
}, user.ID, now)
require.NoError(t, err)
@@ -2190,7 +2190,7 @@ func TestTaskService_CreateCompletion_OneTime_InProgressBecomesFalse(t *testing.
require.NoError(t, err)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID,
}, user.ID, now)
require.NoError(t, err)
@@ -2212,7 +2212,7 @@ func TestTaskService_CreateCompletion_OneTime_CompletionRecordFields(t *testing.
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Record Fields Task")
now := time.Now().UTC()
resp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
resp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Check all fields",
}, user.ID, now)
require.NoError(t, err)
@@ -2241,7 +2241,7 @@ func TestTaskService_CreateCompletion_OneTime_WithNotesActualCostRating(t *testi
cost := decimal.NewFromFloat(75.50)
rating := 4
now := time.Now().UTC()
resp, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
resp, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID,
Notes: "Detailed notes",
ActualCost: &cost,
@@ -2292,7 +2292,7 @@ func TestTaskService_CreateCompletion_AlreadyCompleted_SecondCompletionCreated(t
now := time.Now().UTC()
// First completion
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "First",
}, user.ID, now)
require.NoError(t, err)
@@ -2302,7 +2302,7 @@ func TestTaskService_CreateCompletion_AlreadyCompleted_SecondCompletionCreated(t
assert.Nil(t, afterFirst.NextDueDate, "NextDueDate should be nil after first completion")
// Second completion on already-completed task
resp2, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
resp2, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Second",
}, user.ID, now)
require.NoError(t, err)
@@ -2332,7 +2332,7 @@ func TestTaskService_CreateCompletion_WithBackdatedCompletedAt(t *testing.T) {
backdated := time.Date(2026, 1, 15, 14, 30, 0, 0, time.UTC)
now := time.Now().UTC()
_, err := service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err := service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Backdated", CompletedAt: &backdated,
}, user.ID, now)
require.NoError(t, err)
@@ -2375,7 +2375,7 @@ func TestTaskService_CreateCompletion_Recurring_BackdatedCompletedAt_NextDueFrom
backdated := time.Date(2026, 1, 10, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, Notes: "Backdated recurring", CompletedAt: &backdated,
}, user.ID, now)
require.NoError(t, err)
@@ -2425,7 +2425,7 @@ func TestTaskService_CreateCompletion_Recurring_Daily(t *testing.T) {
now := time.Now().UTC()
completedAt1 := time.Date(2026, 3, 26, 9, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt1,
}, user.ID, now)
require.NoError(t, err)
@@ -2441,7 +2441,7 @@ func TestTaskService_CreateCompletion_Recurring_Daily(t *testing.T) {
// Complete again
completedAt2 := time.Date(2026, 3, 27, 10, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt2,
}, user.ID, now)
require.NoError(t, err)
@@ -2483,7 +2483,7 @@ func TestTaskService_CreateCompletion_Recurring_Weekly_OnTime(t *testing.T) {
completedAt := time.Date(2026, 3, 20, 15, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2527,7 +2527,7 @@ func TestTaskService_CreateCompletion_Recurring_Weekly_CompletedLate_NextDueFrom
// Complete 3 days late
completedAt := time.Date(2026, 3, 23, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2572,7 +2572,7 @@ func TestTaskService_CreateCompletion_Recurring_BiWeekly(t *testing.T) {
completedAt := time.Date(2026, 3, 1, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2616,7 +2616,7 @@ func TestTaskService_CreateCompletion_Recurring_Monthly_Dedicated(t *testing.T)
completedAt := time.Date(2026, 2, 5, 12, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2662,7 +2662,7 @@ func TestTaskService_CreateCompletion_Recurring_Quarterly(t *testing.T) {
completedAt := time.Date(2026, 1, 5, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2708,7 +2708,7 @@ func TestTaskService_CreateCompletion_Recurring_Yearly(t *testing.T) {
completedAt := time.Date(2026, 1, 10, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2766,7 +2766,7 @@ func TestTaskService_CreateCompletion_Recurring_Custom_Intervals(t *testing.T) {
completedAt := time.Date(2026, 3, 5, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2812,7 +2812,7 @@ func TestTaskService_CreateCompletion_Recurring_NoDueDate_NextDueFromCompletion(
completedAt := time.Date(2026, 3, 26, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -2859,7 +2859,7 @@ func TestTaskService_CreateCompletion_Recurring_ThreeSequentialCompletions(t *te
// Completion 1: Mar 1 -> NextDueDate = Mar 8
c1 := time.Date(2026, 3, 1, 10, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &c1,
}, user.ID, now)
require.NoError(t, err)
@@ -2869,7 +2869,7 @@ func TestTaskService_CreateCompletion_Recurring_ThreeSequentialCompletions(t *te
// Completion 2: Mar 8 -> NextDueDate = Mar 15
c2 := time.Date(2026, 3, 8, 10, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &c2,
}, user.ID, now)
require.NoError(t, err)
@@ -2879,7 +2879,7 @@ func TestTaskService_CreateCompletion_Recurring_ThreeSequentialCompletions(t *te
// Completion 3: Mar 15 -> NextDueDate = Mar 22
c3 := time.Date(2026, 3, 15, 10, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &c3,
}, user.ID, now)
require.NoError(t, err)
@@ -2922,7 +2922,7 @@ func TestTaskService_CreateCompletion_Recurring_InProgressResetForNextCycle(t *t
require.NoError(t, err)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID,
}, user.ID, now)
require.NoError(t, err)
@@ -2960,7 +2960,7 @@ func TestTaskService_CreateCompletion_CompletedFromColumn_Capture(t *testing.T)
require.NoError(t, err)
now := time.Date(2026, 3, 26, 0, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID,
}, user.ID, now)
require.NoError(t, err)
@@ -2988,7 +2988,7 @@ func TestTaskService_CreateCompletion_CompletedFromColumn_Capture(t *testing.T)
require.NoError(t, err)
now := time.Date(2026, 3, 26, 0, 0, 0, 0, time.UTC)
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID,
}, user.ID, now)
require.NoError(t, err)
@@ -3047,7 +3047,7 @@ func TestTaskService_CreateCompletion_AllFrequencyTypes_TableDriven(t *testing.T
completedAt := time.Date(2026, 3, 5, 10, 0, 0, 0, time.UTC)
now := time.Now().UTC()
_, err = service.CreateCompletion(&requests.CreateTaskCompletionRequest{
_, err = service.CreateCompletion(context.Background(), &requests.CreateTaskCompletionRequest{
TaskID: task.ID, CompletedAt: &completedAt,
}, user.ID, now)
require.NoError(t, err)
@@ -3091,7 +3091,7 @@ func TestTaskService_QuickComplete_OneTime_ClearsNextDueDate(t *testing.T) {
err := db.Create(task).Error
require.NoError(t, err)
err = service.QuickComplete(task.ID, user.ID)
err = service.QuickComplete(context.Background(), task.ID, user.ID)
require.NoError(t, err)
var reloaded models.Task
@@ -3132,7 +3132,7 @@ func TestTaskService_QuickComplete_Recurring_RecalculatesNextDueDate(t *testing.
err := db.Create(task).Error
require.NoError(t, err)
err = service.QuickComplete(task.ID, user.ID)
err = service.QuickComplete(context.Background(), task.ID, user.ID)
require.NoError(t, err)
var reloaded models.Task
@@ -3154,7 +3154,7 @@ func TestTaskService_QuickComplete_SetsWidgetNotes(t *testing.T) {
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, user.ID, "Widget Task")
err := service.QuickComplete(task.ID, user.ID)
err := service.QuickComplete(context.Background(), task.ID, user.ID)
require.NoError(t, err)
var completion models.TaskCompletion
@@ -3173,7 +3173,7 @@ func TestTaskService_QuickComplete_NonExistentTask_ReturnsNotFound(t *testing.T)
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
err := service.QuickComplete(99999, user.ID)
err := service.QuickComplete(context.Background(), 99999, user.ID)
testutil.AssertAppErrorCode(t, err, http.StatusNotFound)
}
@@ -3189,6 +3189,6 @@ func TestTaskService_QuickComplete_AccessDenied_ReturnsForbidden(t *testing.T) {
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
task := testutil.CreateTestTask(t, db, residence.ID, owner.ID, "Private Task")
err := service.QuickComplete(task.ID, otherUser.ID)
err := service.QuickComplete(context.Background(), task.ID, otherUser.ID)
testutil.AssertAppError(t, err, http.StatusForbidden, "error.task_access_denied")
}