diff --git a/backend/internal/web/handlers_tablos.go b/backend/internal/web/handlers_tablos.go
index 9518dcf..86799b0 100644
--- a/backend/internal/web/handlers_tablos.go
+++ b/backend/internal/web/handlers_tablos.go
@@ -184,14 +184,25 @@ func loadOwnedTablo(w http.ResponseWriter, r *http.Request, deps TablosDeps) (sq
// TabloDetailHandler handles GET /tablos/{id}.
// Renders the tablo detail page for the authenticated owner; 404 for non-owner
// and invalid UUIDs (TABLO-03, T-03-03-01, T-03-03-03).
+// Also fetches the tablo's tasks for the kanban board (Plan 02).
func TabloDetailHandler(deps TablosDeps) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tablo, user, ok := loadOwnedTablo(w, r, deps)
if !ok {
return
}
+ // Fetch tasks for the kanban board. On error, log and use empty slice —
+ // the tablo itself is valid so we still render the page (Plan 02, T-04-07).
+ tasks, err := deps.Queries.ListTasksByTablo(r.Context(), tablo.ID)
+ if err != nil {
+ slog.Default().Error("tablos detail: ListTasksByTablo failed", "tablo_id", tablo.ID, "err", err)
+ tasks = []sqlc.Task{}
+ }
+ if tasks == nil {
+ tasks = []sqlc.Task{}
+ }
w.Header().Set("Content-Type", "text/html; charset=utf-8")
- _ = templates.TabloDetailPage(user, csrf.Token(r), tablo).Render(r.Context(), w)
+ _ = templates.TabloDetailPage(user, csrf.Token(r), tablo, tasks).Render(r.Context(), w)
}
}
@@ -288,7 +299,16 @@ func TabloUpdateHandler(deps TablosDeps) http.HandlerFunc {
}
// Non-HTMX: render full detail page with errors surfaced using the
// authenticated user (not nil) to avoid broken layout (CR-02).
- _ = templates.TabloDetailPage(user, csrf.Token(r), tablo).Render(ctx, w)
+ // Fetch tasks for the kanban board; use empty slice on error.
+ tasks, tasksErr := deps.Queries.ListTasksByTablo(ctx, tablo.ID)
+ if tasksErr != nil {
+ slog.Default().Error("tablos update: ListTasksByTablo failed", "tablo_id", tablo.ID, "err", tasksErr)
+ tasks = []sqlc.Task{}
+ }
+ if tasks == nil {
+ tasks = []sqlc.Task{}
+ }
+ _ = templates.TabloDetailPage(user, csrf.Token(r), tablo, tasks).Render(ctx, w)
return
}
diff --git a/backend/templates/layout.templ b/backend/templates/layout.templ
index 7fb9941..2b5f1c9 100644
--- a/backend/templates/layout.templ
+++ b/backend/templates/layout.templ
@@ -49,9 +49,10 @@ templ Layout(title string, user *auth.User, csrfToken string) {
{ children... }
+