Add honeycomb completion heatmap and data migration framework

- Add completion_summary endpoint data to residence detail response
- Track completed_from_column on task completions (overdue/due_soon/upcoming)
- Add GetCompletionSummary repo method with monthly aggregation
- Add one-time data migration framework (data_migrations table + registry)
- Add backfill migration to classify historical completions
- Add standalone backfill script for manual/dry-run usage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-12 00:05:10 -05:00
parent 739b245ee6
commit 6803f6ec18
12 changed files with 958 additions and 21 deletions

View File

@@ -102,7 +102,7 @@ func TestResidenceService_GetResidence(t *testing.T) {
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
residence := testutil.CreateTestResidence(t, db, user.ID, "Test House")
resp, err := service.GetResidence(residence.ID, user.ID)
resp, err := service.GetResidence(residence.ID, user.ID, time.Now())
require.NoError(t, err)
assert.Equal(t, residence.ID, resp.ID)
assert.Equal(t, "Test House", resp.Name)
@@ -119,7 +119,7 @@ func TestResidenceService_GetResidence_AccessDenied(t *testing.T) {
otherUser := testutil.CreateTestUser(t, db, "other", "other@test.com", "password")
residence := testutil.CreateTestResidence(t, db, owner.ID, "Test House")
_, err := service.GetResidence(residence.ID, otherUser.ID)
_, err := service.GetResidence(residence.ID, otherUser.ID, time.Now())
testutil.AssertAppError(t, err, http.StatusForbidden, "error.residence_access_denied")
}
@@ -132,7 +132,7 @@ func TestResidenceService_GetResidence_NotFound(t *testing.T) {
user := testutil.CreateTestUser(t, db, "user", "user@test.com", "password")
_, err := service.GetResidence(9999, user.ID)
_, err := service.GetResidence(9999, user.ID, time.Now())
assert.Error(t, err)
}
@@ -210,7 +210,7 @@ func TestResidenceService_DeleteResidence(t *testing.T) {
require.NoError(t, err)
// Should not be found
_, err = service.GetResidence(residence.ID, user.ID)
_, err = service.GetResidence(residence.ID, user.ID, time.Now())
assert.Error(t, err)
}