From a38ce269cc9283556621b5447eb3a0caf697eae9 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Tue, 20 Jan 2026 21:07:36 -1000 Subject: Add in-app bug reporting feature - New bugs table in SQLite (migration 005) - Store methods for saving and retrieving bugs - Handlers for GET/POST /bugs - Floating bug button with modal UI - Shows recent bug reports in modal Co-Authored-By: Claude Opus 4.5 --- cmd/dashboard/main.go | 4 +++ internal/handlers/handlers.go | 46 ++++++++++++++++++++++++++++++++++ internal/store/sqlite.go | 32 +++++++++++++++++++++++ issues/bug_004_trello_cards_missing.md | 31 +++++++++++++++++++++++ migrations/005_add_bugs.sql | 6 +++++ web/templates/index.html | 42 +++++++++++++++++++++++++++++++ 6 files changed, 161 insertions(+) create mode 100644 issues/bug_004_trello_cards_missing.md create mode 100644 migrations/005_add_bugs.sql diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index de3fb7c..7cacd06 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -137,6 +137,10 @@ func main() { // Unified Quick Add (for Tasks tab) r.Post("/unified-add", h.HandleUnifiedAdd) r.Get("/partials/lists", h.HandleGetListsOptions) + + // Bug reporting + r.Get("/bugs", h.HandleGetBugs) + r.Post("/bugs", h.HandleReportBug) }) // Start server diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index d52e786..8d809ae 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -829,3 +829,49 @@ func (h *Handler) HandleGetListsOptions(w http.ResponseWriter, r *http.Request) fmt.Fprintf(w, ``, list.ID, list.Name) } } + +// HandleGetBugs returns the list of reported bugs +func (h *Handler) HandleGetBugs(w http.ResponseWriter, r *http.Request) { + bugs, err := h.store.GetBugs() + if err != nil { + http.Error(w, "Failed to fetch bugs", http.StatusInternalServerError) + log.Printf("Error fetching bugs: %v", err) + return + } + + w.Header().Set("Content-Type", "text/html") + if len(bugs) == 0 { + fmt.Fprint(w, `

No bugs reported yet.

`) + return + } + + for _, bug := range bugs { + fmt.Fprintf(w, `
+

%s

+

%s

+
`, template.HTMLEscapeString(bug.Description), bug.CreatedAt.Format("Jan 2, 3:04 PM")) + } +} + +// HandleReportBug saves a new bug report +func (h *Handler) HandleReportBug(w http.ResponseWriter, r *http.Request) { + if err := r.ParseForm(); err != nil { + http.Error(w, "Invalid form data", http.StatusBadRequest) + return + } + + description := strings.TrimSpace(r.FormValue("description")) + if description == "" { + http.Error(w, "Description is required", http.StatusBadRequest) + return + } + + if err := h.store.SaveBug(description); err != nil { + http.Error(w, "Failed to save bug", http.StatusInternalServerError) + log.Printf("Error saving bug: %v", err) + return + } + + // Return updated bug list + h.HandleGetBugs(w, r) +} diff --git a/internal/store/sqlite.go b/internal/store/sqlite.go index 7961f35..8640b9b 100644 --- a/internal/store/sqlite.go +++ b/internal/store/sqlite.go @@ -541,3 +541,35 @@ func (s *Store) ClearSyncToken(service string) error { _, err := s.db.Exec(`DELETE FROM sync_tokens WHERE service = ?`, service) return err } + +// Bug represents a user-reported bug +type Bug struct { + ID int64 + Description string + CreatedAt time.Time +} + +// SaveBug saves a new bug report +func (s *Store) SaveBug(description string) error { + _, err := s.db.Exec(`INSERT INTO bugs (description) VALUES (?)`, description) + return err +} + +// GetBugs retrieves all bugs, newest first +func (s *Store) GetBugs() ([]Bug, error) { + rows, err := s.db.Query(`SELECT id, description, created_at FROM bugs ORDER BY created_at DESC`) + if err != nil { + return nil, err + } + defer rows.Close() + + var bugs []Bug + for rows.Next() { + var b Bug + if err := rows.Scan(&b.ID, &b.Description, &b.CreatedAt); err != nil { + return nil, err + } + bugs = append(bugs, b) + } + return bugs, rows.Err() +} diff --git a/issues/bug_004_trello_cards_missing.md b/issues/bug_004_trello_cards_missing.md new file mode 100644 index 0000000..c882424 --- /dev/null +++ b/issues/bug_004_trello_cards_missing.md @@ -0,0 +1,31 @@ +# Bug: Trello cards not showing on all boards + +## Status +Open + +## Symptoms +- Only one board shows cards +- Other boards with cards appear empty +- Refresh works (no 403 error) but doesn't fix the issue +- No errors in server logs + +## Investigation Notes +- CSRF fix applied - refresh now works +- API client code looks correct (fetches all boards, then cards per board) +- Cache logic appears correct (SaveBoards clears and replaces all data) +- Need to investigate: + - Is the Trello API returning all cards? + - Is there a filter issue (`visible` vs `all`)? + - Board permissions issue on Trello side? + - Race condition in concurrent card fetching? + +## Reproduction +1. Login to dashboard +2. Go to Planning tab +3. Observe: only one board has cards, others are empty +4. Compare with actual Trello - should have cards on multiple boards + +## Next Steps +- Add logging to trace Trello API responses +- Check if specific boards are returning empty card arrays +- Verify Trello API credentials have access to all boards diff --git a/migrations/005_add_bugs.sql b/migrations/005_add_bugs.sql new file mode 100644 index 0000000..999b1f2 --- /dev/null +++ b/migrations/005_add_bugs.sql @@ -0,0 +1,6 @@ +-- Bug tracking table +CREATE TABLE IF NOT EXISTS bugs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + description TEXT NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +); diff --git a/web/templates/index.html b/web/templates/index.html index 617ccfe..2cd4c59 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -84,6 +84,48 @@ + + + + + + -- cgit v1.2.3