From 47ba2f1797d23a2214b6032f1884daa0e24f797f Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sun, 17 May 2026 16:28:15 +0200 Subject: [PATCH] feat(19-01): enrich TabloCardView with Progress field and wire batch progress query - Add Progress int field to TabloCardView (D-05) - Map row.Status into Tablo struct in TabloCardsFromUnreadRows - Wire ListTabloProgressByIDs batch query in TablosListHandler (no N+1) - Non-fatal error handling: progress defaults to 0 on query failure --- backend/internal/web/handlers_tablos.go | 22 ++++++++++++++++++++++ backend/templates/discussion_forms.go | 2 ++ 2 files changed, 24 insertions(+) diff --git a/backend/internal/web/handlers_tablos.go b/backend/internal/web/handlers_tablos.go index 0e32b20..d2d29d6 100644 --- a/backend/internal/web/handlers_tablos.go +++ b/backend/internal/web/handlers_tablos.go @@ -51,6 +51,28 @@ func TablosListHandler(deps TablosDeps) http.HandlerFunc { } cardViews := templates.TabloCardsFromUnreadRows(tabloRows) + + // Batch progress query: one query for all tablos (D-06, no N+1). + tabloIDs := make([]uuid.UUID, len(cardViews)) + for i, cv := range cardViews { + tabloIDs[i] = cv.Tablo.ID + } + progressRows, progressErr := deps.Queries.ListTabloProgressByIDs(r.Context(), tabloIDs) + if progressErr != nil { + slog.Default().Error("tablos list: progress query failed", "user_id", user.ID, "err", progressErr) + // Non-fatal: proceed with Progress = 0 for all cards. + progressRows = nil + } + progressMap := make(map[uuid.UUID]int, len(progressRows)) + for _, p := range progressRows { + if p.TotalTasks > 0 { + progressMap[p.TabloID] = int(p.DoneTasks * 100 / p.TotalTasks) + } + } + for i := range cardViews { + cardViews[i].Progress = progressMap[cardViews[i].Tablo.ID] + } + sidebarTablos := make([]sqlc.Tablo, 0, len(cardViews)) for _, cv := range cardViews { sidebarTablos = append(sidebarTablos, cv.Tablo) diff --git a/backend/templates/discussion_forms.go b/backend/templates/discussion_forms.go index 2ae02d0..247bd2c 100644 --- a/backend/templates/discussion_forms.go +++ b/backend/templates/discussion_forms.go @@ -36,6 +36,7 @@ type DiscussionTabData struct { type TabloCardView struct { Tablo sqlc.Tablo DiscussionUnreadCount int64 + Progress int // 0–100; 0 when no tasks (D-05) } func DiscussionPostURL(tabloID uuid.UUID) string { @@ -90,6 +91,7 @@ func TabloCardsFromUnreadRows(rows []sqlc.ListTablosByUserWithDiscussionUnreadRo Color: row.Color, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, + Status: row.Status, }, DiscussionUnreadCount: row.DiscussionUnreadCount, })