summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/api/google_calendar.go3
-rw-r--r--internal/api/http.go4
-rw-r--r--internal/api/plantoeat.go25
-rw-r--r--internal/api/research_test.go18
-rw-r--r--internal/api/todoist_test.go12
-rw-r--r--internal/api/trello_test.go10
-rw-r--r--internal/auth/auth_test.go8
-rw-r--r--internal/auth/handlers_test.go4
-rw-r--r--internal/handlers/handlers.go29
-rw-r--r--internal/handlers/handlers_test.go12
-rw-r--r--internal/handlers/response.go4
-rw-r--r--internal/handlers/tab_state_test.go4
-rw-r--r--internal/handlers/timeline_logic_test.go8
-rw-r--r--internal/store/sqlite.go36
-rw-r--r--internal/store/sqlite_test.go22
15 files changed, 90 insertions, 109 deletions
diff --git a/internal/api/google_calendar.go b/internal/api/google_calendar.go
index dc61f3d..e4f9c2f 100644
--- a/internal/api/google_calendar.go
+++ b/internal/api/google_calendar.go
@@ -55,7 +55,8 @@ func deduplicateEvents(events []models.CalendarEvent) []models.CalendarEvent {
// NewGoogleCalendarClient creates a client that fetches from multiple calendars.
// calendarIDs can be comma-separated (e.g., "cal1@group.calendar.google.com,cal2@group.calendar.google.com")
func NewGoogleCalendarClient(ctx context.Context, credentialsFile, calendarIDs string) (*GoogleCalendarClient, error) {
- srv, err := calendar.NewService(ctx, option.WithCredentialsFile(credentialsFile))
+ // Use type-safe credential loading (replaces deprecated WithCredentialsFile)
+ srv, err := calendar.NewService(ctx, option.WithAuthCredentialsFile(option.ServiceAccount, credentialsFile))
if err != nil {
return nil, fmt.Errorf("unable to retrieve Calendar client: %v", err)
}
diff --git a/internal/api/http.go b/internal/api/http.go
index 8854625..df28c65 100644
--- a/internal/api/http.go
+++ b/internal/api/http.go
@@ -95,7 +95,7 @@ func (c *BaseClient) PostEmpty(ctx context.Context, path string, headers map[str
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
body, _ := io.ReadAll(resp.Body)
@@ -126,7 +126,7 @@ func (c *BaseClient) doJSON(req *http.Request, result interface{}) error {
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
body, _ := io.ReadAll(resp.Body)
diff --git a/internal/api/plantoeat.go b/internal/api/plantoeat.go
index a7fdf58..5c24cc1 100644
--- a/internal/api/plantoeat.go
+++ b/internal/api/plantoeat.go
@@ -39,27 +39,6 @@ func (c *PlanToEatClient) SetSessionCookie(cookie string) {
c.sessionCookie = cookie
}
-func (c *PlanToEatClient) authHeaders() map[string]string {
- return map[string]string{"Authorization": "Bearer " + c.apiKey}
-}
-
-// planToEatPlannerItem represents a planner item from the API
-type planToEatPlannerItem struct {
- ID int `json:"id"`
- Date string `json:"date"`
- MealType string `json:"meal_type"`
- Recipe struct {
- ID int `json:"id"`
- Title string `json:"title"`
- URL string `json:"url"`
- } `json:"recipe"`
-}
-
-// planToEatResponse wraps the API response
-type planToEatResponse struct {
- Items []planToEatPlannerItem `json:"items"`
-}
-
// GetUpcomingMeals fetches meals by scraping the planner web interface
// Requires a valid session cookie set via SetSessionCookie
func (c *PlanToEatClient) GetUpcomingMeals(ctx context.Context, days int) ([]models.Meal, error) {
@@ -84,7 +63,7 @@ func (c *PlanToEatClient) GetUpcomingMeals(ctx context.Context, days int) ([]mod
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
log.Printf("DEBUG [PlanToEat/Meals]: Response status %d", resp.StatusCode)
@@ -238,7 +217,7 @@ func (c *PlanToEatClient) GetShoppingList(ctx context.Context) ([]models.Shoppin
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
log.Printf("DEBUG [PlanToEat/Shopping]: Response status %d", resp.StatusCode)
diff --git a/internal/api/research_test.go b/internal/api/research_test.go
index 83a52b4..f2519e2 100644
--- a/internal/api/research_test.go
+++ b/internal/api/research_test.go
@@ -45,7 +45,7 @@ func TestTodoistSyncResearch(t *testing.T) {
if err != nil {
t.Fatalf("Failed to call Sync API: %v", err)
}
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
body, err := io.ReadAll(resp.Body)
if err != nil {
@@ -102,13 +102,13 @@ func TestTodoistSyncResearch(t *testing.T) {
if err != nil {
t.Fatalf("Incremental sync failed: %v", err)
}
- defer resp2.Body.Close()
+ defer func() { _ = resp2.Body.Close() }()
body2, _ := io.ReadAll(resp2.Body)
t.Logf("Incremental response size: %d bytes (vs full: %d bytes)", len(body2), len(body))
var syncResp2 map[string]interface{}
- json.Unmarshal(body2, &syncResp2)
+ _ = json.Unmarshal(body2, &syncResp2)
if items2, ok := syncResp2["items"].([]interface{}); ok {
t.Logf("Incremental items count: %d", len(items2))
}
@@ -142,7 +142,7 @@ func TestTrelloOptimizationResearch(t *testing.T) {
t.Fatalf("Failed to fetch boards: %v", err)
}
body, _ := io.ReadAll(resp.Body)
- resp.Body.Close()
+ _ = resp.Body.Close()
fullDuration := time.Since(start)
t.Logf("Test 1 - Full boards response:")
@@ -150,7 +150,7 @@ func TestTrelloOptimizationResearch(t *testing.T) {
t.Logf(" Duration: %v", fullDuration)
var boards []map[string]interface{}
- json.Unmarshal(body, &boards)
+ _ = json.Unmarshal(body, &boards)
t.Logf(" Board count: %d", len(boards))
if len(boards) > 0 {
t.Logf(" Fields in first board: %v", getKeys(boards[0]))
@@ -170,7 +170,7 @@ func TestTrelloOptimizationResearch(t *testing.T) {
t.Fatalf("Failed to fetch limited boards: %v", err)
}
body2, _ := io.ReadAll(resp2.Body)
- resp2.Body.Close()
+ _ = resp2.Body.Close()
limitedDuration := time.Since(start)
t.Logf("\nTest 2 - Limited fields (id,name):")
@@ -196,7 +196,7 @@ func TestTrelloOptimizationResearch(t *testing.T) {
t.Fatalf("Failed to fetch board with cards: %v", err)
}
body3, _ := io.ReadAll(resp3.Body)
- resp3.Body.Close()
+ _ = resp3.Body.Close()
batchDuration := time.Since(start)
t.Logf("\nTest 3 - Single board with cards/lists embedded:")
@@ -204,7 +204,7 @@ func TestTrelloOptimizationResearch(t *testing.T) {
t.Logf(" Duration: %v", batchDuration)
var boardWithCards map[string]interface{}
- json.Unmarshal(body3, &boardWithCards)
+ _ = json.Unmarshal(body3, &boardWithCards)
if cards, ok := boardWithCards["cards"].([]interface{}); ok {
t.Logf(" Cards count: %d", len(cards))
}
@@ -227,7 +227,7 @@ func TestTrelloOptimizationResearch(t *testing.T) {
t.Logf(" 'since' parameter: Error - %v", err)
} else {
body4, _ := io.ReadAll(resp4.Body)
- resp4.Body.Close()
+ _ = resp4.Body.Close()
t.Logf(" 'since' parameter: Status %d, Size %d bytes", resp4.StatusCode, len(body4))
}
}
diff --git a/internal/api/todoist_test.go b/internal/api/todoist_test.go
index 2fa6e28..7bbcc1e 100644
--- a/internal/api/todoist_test.go
+++ b/internal/api/todoist_test.go
@@ -13,7 +13,7 @@ import (
// newTestTodoistClient creates a TodoistClient for testing with custom base URL
func newTestTodoistClient(baseURL, apiKey string) *TodoistClient {
client := NewTodoistClient(apiKey)
- client.BaseClient.BaseURL = baseURL
+ client.BaseURL = baseURL
client.syncClient.BaseURL = baseURL
return client
}
@@ -62,7 +62,7 @@ func TestTodoistClient_CreateTask(t *testing.T) {
}
w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(response)
+ _ = json.NewEncoder(w).Encode(response)
}))
defer server.Close()
@@ -96,7 +96,7 @@ func TestTodoistClient_CreateTask_WithDueDate(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Parse JSON body
var payload map[string]interface{}
- json.NewDecoder(r.Body).Decode(&payload)
+ _ = json.NewDecoder(r.Body).Decode(&payload)
// Verify due_date
if payload["due_date"] != "2026-01-15" {
@@ -117,7 +117,7 @@ func TestTodoistClient_CreateTask_WithDueDate(t *testing.T) {
}
w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(response)
+ _ = json.NewEncoder(w).Encode(response)
}))
defer server.Close()
@@ -181,7 +181,7 @@ func TestTodoistClient_CompleteTask_Error(t *testing.T) {
// Mock server that returns error
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
- w.Write([]byte(`{"error":"Task not found"}`))
+ _, _ = w.Write([]byte(`{"error":"Task not found"}`))
}))
defer server.Close()
@@ -218,7 +218,7 @@ func TestTodoistClient_GetProjects(t *testing.T) {
}
w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(response)
+ _ = json.NewEncoder(w).Encode(response)
}))
defer server.Close()
diff --git a/internal/api/trello_test.go b/internal/api/trello_test.go
index 7433ff0..d677363 100644
--- a/internal/api/trello_test.go
+++ b/internal/api/trello_test.go
@@ -15,7 +15,7 @@ import (
// newTestTrelloClient creates a TrelloClient for testing with custom base URL
func newTestTrelloClient(baseURL, apiKey, token string) *TrelloClient {
client := NewTrelloClient(apiKey, token)
- client.BaseClient.BaseURL = baseURL
+ client.BaseURL = baseURL
return client
}
@@ -67,7 +67,7 @@ func TestTrelloClient_CreateCard(t *testing.T) {
}
w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(response)
+ _ = json.NewEncoder(w).Encode(response)
}))
defer server.Close()
@@ -122,7 +122,7 @@ func TestTrelloClient_CreateCard_WithDueDate(t *testing.T) {
}
w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(response)
+ _ = json.NewEncoder(w).Encode(response)
}))
defer server.Close()
@@ -176,7 +176,7 @@ func TestTrelloClient_UpdateCard(t *testing.T) {
// Return 200 OK
w.WriteHeader(http.StatusOK)
- w.Write([]byte(`{"id":"card-123","name":"Updated Name"}`))
+ _, _ = w.Write([]byte(`{"id":"card-123","name":"Updated Name"}`))
}))
defer server.Close()
@@ -201,7 +201,7 @@ func TestTrelloClient_UpdateCard_Error(t *testing.T) {
// Mock server that returns error
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
- w.Write([]byte(`{"error":"Invalid card ID"}`))
+ _, _ = w.Write([]byte(`{"error":"Invalid card ID"}`))
}))
defer server.Close()
diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go
index 505efe3..013a4aa 100644
--- a/internal/auth/auth_test.go
+++ b/internal/auth/auth_test.go
@@ -15,7 +15,7 @@ func TestAuthenticate(t *testing.T) {
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
- defer db.Close()
+ defer func() { _ = db.Close() }()
service := NewService(db)
@@ -34,7 +34,7 @@ func TestAuthenticate(t *testing.T) {
t.Errorf("expected no error, got %v", err)
}
if user == nil {
- t.Errorf("expected user, got nil")
+ t.Fatal("expected user, got nil")
}
if user.Username != "testuser" {
t.Errorf("expected username testuser, got %s", user.Username)
@@ -50,7 +50,7 @@ func TestAuthenticate_InvalidCredentials(t *testing.T) {
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
- defer db.Close()
+ defer func() { _ = db.Close() }()
service := NewService(db)
@@ -73,7 +73,7 @@ func TestCreateUser(t *testing.T) {
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
- defer db.Close()
+ defer func() { _ = db.Close() }()
service := NewService(db)
diff --git a/internal/auth/handlers_test.go b/internal/auth/handlers_test.go
index 3e154ce..128ae80 100644
--- a/internal/auth/handlers_test.go
+++ b/internal/auth/handlers_test.go
@@ -20,7 +20,7 @@ func TestHandleLogin(t *testing.T) {
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
- defer db.Close()
+ defer func() { _ = db.Close() }()
service := NewService(db)
sessionManager := scs.New()
@@ -68,7 +68,7 @@ func TestHandleLogin_InvalidCredentials(t *testing.T) {
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
- defer db.Close()
+ defer func() { _ = db.Close() }()
service := NewService(db)
sessionManager := scs.New()
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go
index e0e185d..a169478 100644
--- a/internal/handlers/handlers.go
+++ b/internal/handlers/handlers.go
@@ -659,9 +659,9 @@ func (h *Handler) handleAtomToggle(w http.ResponseWriter, r *http.Request, compl
// Remove from local cache
switch source {
case "todoist":
- h.store.DeleteTask(id)
+ _ = h.store.DeleteTask(id)
case "trello":
- h.store.DeleteCard(id)
+ _ = h.store.DeleteCard(id)
}
// Return completed task HTML with uncomplete option
@@ -675,9 +675,9 @@ func (h *Handler) handleAtomToggle(w http.ResponseWriter, r *http.Request, compl
// Invalidate cache to force refresh
switch source {
case "todoist":
- h.store.InvalidateCache(store.CacheKeyTodoistTasks)
+ _ = h.store.InvalidateCache(store.CacheKeyTodoistTasks)
case "trello":
- h.store.InvalidateCache(store.CacheKeyTrelloBoards)
+ _ = h.store.InvalidateCache(store.CacheKeyTrelloBoards)
}
// Don't swap empty response - just trigger refresh
w.Header().Set("HX-Reswap", "none")
@@ -710,10 +710,11 @@ func (h *Handler) getAtomTitle(id, source string) string {
case "bug":
if bugs, err := h.store.GetBugs(); err == nil {
var bugID int64
- fmt.Sscanf(id, "bug-%d", &bugID)
- for _, b := range bugs {
- if b.ID == bugID {
- return b.Description
+ if _, err := fmt.Sscanf(id, "bug-%d", &bugID); err == nil {
+ for _, b := range bugs {
+ if b.ID == bugID {
+ return b.Description
+ }
}
}
}
@@ -752,7 +753,7 @@ func (h *Handler) HandleUnifiedAdd(w http.ResponseWriter, r *http.Request) {
JSONError(w, http.StatusInternalServerError, "Failed to create Todoist task", err)
return
}
- h.store.InvalidateCache(store.CacheKeyTodoistTasks)
+ _ = h.store.InvalidateCache(store.CacheKeyTodoistTasks)
case "trello":
listID := r.FormValue("list_id")
@@ -764,7 +765,7 @@ func (h *Handler) HandleUnifiedAdd(w http.ResponseWriter, r *http.Request) {
JSONError(w, http.StatusInternalServerError, "Failed to create Trello card", err)
return
}
- h.store.InvalidateCache(store.CacheKeyTrelloBoards)
+ _ = h.store.InvalidateCache(store.CacheKeyTrelloBoards)
default:
JSONError(w, http.StatusBadRequest, "Invalid source", nil)
@@ -791,7 +792,7 @@ func (h *Handler) HandleGetListsOptions(w http.ResponseWriter, r *http.Request)
w.Header().Set("Content-Type", "text/html")
for _, list := range lists {
- fmt.Fprintf(w, `<option value="%s">%s</option>`, list.ID, list.Name)
+ _, _ = fmt.Fprintf(w, `<option value="%s">%s</option>`, list.ID, list.Name)
}
}
@@ -805,12 +806,12 @@ func (h *Handler) HandleGetBugs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
if len(bugs) == 0 {
- fmt.Fprint(w, `<p class="text-gray-500 text-sm">No bugs reported yet.</p>`)
+ _, _ = fmt.Fprint(w, `<p class="text-gray-500 text-sm">No bugs reported yet.</p>`)
return
}
for _, bug := range bugs {
- fmt.Fprintf(w, `<div class="text-sm border-b border-gray-100 py-2">
+ _, _ = fmt.Fprintf(w, `<div class="text-sm border-b border-gray-100 py-2">
<p class="text-gray-900">%s</p>
<p class="text-gray-400 text-xs">%s</p>
</div>`, template.HTMLEscapeString(bug.Description), bug.CreatedAt.Format("Jan 2, 3:04 PM"))
@@ -916,7 +917,7 @@ func (h *Handler) HandleGetShoppingLists(w http.ResponseWriter, r *http.Request)
w.Header().Set("Content-Type", "text/html")
for _, list := range lists {
- fmt.Fprintf(w, `<option value="%s">%s</option>`, list.ID, list.Name)
+ _, _ = fmt.Fprintf(w, `<option value="%s">%s</option>`, list.ID, list.Name)
}
}
diff --git a/internal/handlers/handlers_test.go b/internal/handlers/handlers_test.go
index 3658e0e..d863546 100644
--- a/internal/handlers/handlers_test.go
+++ b/internal/handlers/handlers_test.go
@@ -26,7 +26,7 @@ func setupTestDB(t *testing.T) (*store.Store, func()) {
if err != nil {
t.Fatalf("Failed to create temp db: %v", err)
}
- tmpFile.Close()
+ _ = tmpFile.Close()
// Save current directory and change to project root
// This ensures migrations can be found
@@ -43,18 +43,18 @@ func setupTestDB(t *testing.T) (*store.Store, func()) {
// Initialize store (this runs migrations)
db, err := store.New(tmpFile.Name(), "migrations")
if err != nil {
- os.Chdir(originalDir)
- os.Remove(tmpFile.Name())
+ _ = os.Chdir(originalDir)
+ _ = os.Remove(tmpFile.Name())
t.Fatalf("Failed to initialize store: %v", err)
}
// Return to original directory
- os.Chdir(originalDir)
+ _ = os.Chdir(originalDir)
// Return cleanup function
cleanup := func() {
- db.Close()
- os.Remove(tmpFile.Name())
+ _ = db.Close()
+ _ = os.Remove(tmpFile.Name())
}
return db, cleanup
diff --git a/internal/handlers/response.go b/internal/handlers/response.go
index 3976f02..9a7ab45 100644
--- a/internal/handlers/response.go
+++ b/internal/handlers/response.go
@@ -10,7 +10,7 @@ import (
// JSONResponse writes data as JSON with appropriate headers
func JSONResponse(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(data)
+ _ = json.NewEncoder(w).Encode(data)
}
// JSONError writes an error response as JSON
@@ -32,5 +32,5 @@ func HTMLResponse(w http.ResponseWriter, tmpl *template.Template, name string, d
// HTMLString writes an HTML string directly
func HTMLString(w http.ResponseWriter, html string) {
w.Header().Set("Content-Type", "text/html")
- w.Write([]byte(html))
+ _, _ = w.Write([]byte(html))
}
diff --git a/internal/handlers/tab_state_test.go b/internal/handlers/tab_state_test.go
index 60f1340..71c6ed8 100644
--- a/internal/handlers/tab_state_test.go
+++ b/internal/handlers/tab_state_test.go
@@ -17,7 +17,7 @@ func TestHandleDashboard_TabState(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create test database: %v", err)
}
- defer db.Close()
+ defer func() { _ = db.Close() }()
// Create mock API clients
todoistClient := api.NewTodoistClient("test-key")
@@ -75,7 +75,7 @@ func TestHandleDashboard_TabState(t *testing.T) {
h.HandleDashboard(w, req)
resp := w.Result()
- defer resp.Body.Close()
+ defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
t.Errorf("Expected status 200, got %d", resp.StatusCode)
diff --git a/internal/handlers/timeline_logic_test.go b/internal/handlers/timeline_logic_test.go
index a0576d6..038f836 100644
--- a/internal/handlers/timeline_logic_test.go
+++ b/internal/handlers/timeline_logic_test.go
@@ -96,21 +96,21 @@ func TestBuildTimeline(t *testing.T) {
// Task: 10:00
taskDate := baseTime.Add(2 * time.Hour)
- s.SaveTasks([]models.Task{
+ _ = s.SaveTasks([]models.Task{
{ID: "t1", Content: "Task 1", DueDate: &taskDate},
})
// Meal: Lunch (defaults to 12:00)
mealDate := baseTime // Date part matters
- s.SaveMeals([]models.Meal{
+ _ = s.SaveMeals([]models.Meal{
{ID: "m1", RecipeName: "Lunch", Date: mealDate, MealType: "lunch"},
})
// Card: 14:00
cardDate := baseTime.Add(6 * time.Hour)
- s.SaveBoards([]models.Board{
+ _ = s.SaveBoards([]models.Board{
{
- ID: "b1",
+ ID: "b1",
Name: "Board 1",
Cards: []models.Card{
{ID: "c1", Name: "Card 1", DueDate: &cardDate, ListID: "l1"},
diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go
index c5c52a4..a9a0597 100644
--- a/internal/store/sqlite.go
+++ b/internal/store/sqlite.go
@@ -151,7 +151,7 @@ func (s *Store) SaveTasks(tasks []models.Task) error {
if err != nil {
return err
}
- defer tx.Rollback()
+ defer func() { _ = tx.Rollback() }()
// Clear existing tasks first to remove stale data
if _, err := tx.Exec(`DELETE FROM tasks`); err != nil {
@@ -166,7 +166,7 @@ func (s *Store) SaveTasks(tasks []models.Task) error {
if err != nil {
return err
}
- defer stmt.Close()
+ defer func() { _ = stmt.Close() }()
for _, task := range tasks {
labelsJSON, _ := json.Marshal(task.Labels)
@@ -201,7 +201,7 @@ func (s *Store) GetTasks() ([]models.Task, error) {
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
return scanTasks(rows)
}
@@ -243,13 +243,13 @@ func (s *Store) DeleteTasksByIDs(ids []string) error {
if err != nil {
return err
}
- defer tx.Rollback()
+ defer func() { _ = tx.Rollback() }()
stmt, err := tx.Prepare(`DELETE FROM tasks WHERE id = ?`)
if err != nil {
return err
}
- defer stmt.Close()
+ defer func() { _ = stmt.Close() }()
for _, id := range ids {
if _, err := stmt.Exec(id); err != nil {
@@ -267,7 +267,7 @@ func (s *Store) SaveMeals(meals []models.Meal) error {
if err != nil {
return err
}
- defer tx.Rollback()
+ defer func() { _ = tx.Rollback() }()
stmt, err := tx.Prepare(`
INSERT OR REPLACE INTO meals
@@ -277,7 +277,7 @@ func (s *Store) SaveMeals(meals []models.Meal) error {
if err != nil {
return err
}
- defer stmt.Close()
+ defer func() { _ = stmt.Close() }()
for _, meal := range meals {
_, err := stmt.Exec(
@@ -312,7 +312,7 @@ func (s *Store) GetMeals(startDate, endDate time.Time) ([]models.Meal, error) {
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
var meals []models.Meal
for rows.Next() {
@@ -391,7 +391,7 @@ func (s *Store) SaveBoards(boards []models.Board) error {
if err != nil {
return err
}
- defer tx.Rollback()
+ defer func() { _ = tx.Rollback() }()
// Clear existing data first (cards must be deleted before boards due to foreign key)
if _, err := tx.Exec(`DELETE FROM cards`); err != nil {
@@ -409,7 +409,7 @@ func (s *Store) SaveBoards(boards []models.Board) error {
if err != nil {
return err
}
- defer boardStmt.Close()
+ defer func() { _ = boardStmt.Close() }()
// Save cards
cardStmt, err := tx.Prepare(`
@@ -420,7 +420,7 @@ func (s *Store) SaveBoards(boards []models.Board) error {
if err != nil {
return err
}
- defer cardStmt.Close()
+ defer func() { _ = cardStmt.Close() }()
savedBoards := 0
savedCards := 0
@@ -472,7 +472,7 @@ func (s *Store) GetBoards() ([]models.Board, error) {
if err != nil {
return nil, err
}
- defer boardRows.Close()
+ defer func() { _ = boardRows.Close() }()
var boards []models.Board
boardMap := make(map[string]int) // Store index, not pointer
@@ -501,7 +501,7 @@ func (s *Store) GetBoards() ([]models.Board, error) {
if err != nil {
return nil, err
}
- defer cardRows.Close()
+ defer func() { _ = cardRows.Close() }()
for cardRows.Next() {
var card models.Card
@@ -596,7 +596,7 @@ func (s *Store) GetBugs() ([]Bug, error) {
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
var bugs []Bug
for rows.Next() {
@@ -619,7 +619,7 @@ func (s *Store) GetUnresolvedBugs() ([]Bug, error) {
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
var bugs []Bug
for rows.Next() {
@@ -665,7 +665,7 @@ func (s *Store) GetUserShoppingItems() ([]UserShoppingItem, error) {
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
var items []UserShoppingItem
for rows.Next() {
@@ -701,7 +701,7 @@ func (s *Store) GetTasksByDateRange(start, end time.Time) ([]models.Task, error)
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
return scanTasks(rows)
}
@@ -722,7 +722,7 @@ func (s *Store) GetCardsByDateRange(start, end time.Time) ([]models.Card, error)
if err != nil {
return nil, err
}
- defer rows.Close()
+ defer func() { _ = rows.Close() }()
var cards []models.Card
for rows.Next() {
diff --git a/internal/store/sqlite_test.go b/internal/store/sqlite_test.go
index fc8a3b7..9aef09d 100644
--- a/internal/store/sqlite_test.go
+++ b/internal/store/sqlite_test.go
@@ -125,7 +125,7 @@ func setupTestStoreWithMeals(t *testing.T) *Store {
// TestDeleteTask verifies that DeleteTask removes a task from the cache
func TestDeleteTask(t *testing.T) {
store := setupTestStoreWithTasks(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Save some tasks
tasks := []models.Task{
@@ -213,7 +213,7 @@ func TestDeleteTask(t *testing.T) {
// TestDeleteTask_NonExistent verifies that deleting a non-existent task doesn't error
func TestDeleteTask_NonExistent(t *testing.T) {
store := setupTestStoreWithTasks(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Delete a task that doesn't exist - should not error
err := store.DeleteTask("nonexistent")
@@ -225,7 +225,7 @@ func TestDeleteTask_NonExistent(t *testing.T) {
// TestDeleteCard verifies that DeleteCard removes a card from the cache
func TestDeleteCard(t *testing.T) {
store := setupTestStoreWithCards(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// First create a board
_, err := store.db.Exec(`INSERT INTO boards (id, name) VALUES (?, ?)`, "board1", "Test Board")
@@ -292,7 +292,7 @@ func TestDeleteCard(t *testing.T) {
// TestDeleteCard_NonExistent verifies that deleting a non-existent card doesn't error
func TestDeleteCard_NonExistent(t *testing.T) {
store := setupTestStoreWithCards(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Delete a card that doesn't exist - should not error
err := store.DeleteCard("nonexistent")
@@ -306,7 +306,7 @@ func TestDeleteCard_NonExistent(t *testing.T) {
// where pointers in boardMap became stale when the boards slice grew.
func TestSaveAndGetBoards_MultipleBoards(t *testing.T) {
store := setupTestStoreWithCards(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Create multiple boards with varying numbers of cards
// Use enough boards to trigger slice reallocation
@@ -411,7 +411,7 @@ func TestSaveAndGetBoards_MultipleBoards(t *testing.T) {
// to ensure slice reallocation is thoroughly tested
func TestSaveAndGetBoards_ManyBoards(t *testing.T) {
store := setupTestStoreWithCards(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Create 20 boards with 5 cards each = 100 cards total
numBoards := 20
@@ -466,7 +466,7 @@ func TestSaveAndGetBoards_ManyBoards(t *testing.T) {
func TestGetTasksByDateRange(t *testing.T) {
store := setupTestStoreWithTasks(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
@@ -498,7 +498,7 @@ func TestGetTasksByDateRange(t *testing.T) {
func TestGetMealsByDateRange(t *testing.T) {
store := setupTestStoreWithMeals(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
@@ -530,7 +530,7 @@ func TestGetMealsByDateRange(t *testing.T) {
func TestGetCardsByDateRange(t *testing.T) {
store := setupTestStoreWithCards(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
@@ -603,7 +603,7 @@ func setupTestStoreWithBugs(t *testing.T) *Store {
func TestBugResolution(t *testing.T) {
store := setupTestStoreWithBugs(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Save some bugs
if err := store.SaveBug("Bug 1"); err != nil {
@@ -681,7 +681,7 @@ func TestBugResolution(t *testing.T) {
func TestResolveBug_NonExistent(t *testing.T) {
store := setupTestStoreWithBugs(t)
- defer store.Close()
+ defer func() { _ = store.Close() }()
// Resolving a non-existent bug should not error (no rows affected is fine)
err := store.ResolveBug(999)