summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-13 14:04:12 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-13 14:04:12 -1000
commit0fda0e9e4b0c6a73be513987264329e4515170f1 (patch)
tree046f9f903492d0a069c46b351479b652335e6fc2
parent1c79f105c960ddab2265cbfd8dfd728630b1ebfb (diff)
Add Trello Lists support for UI dropdowns
Expose Trello Lists in Board model to enable card creation UI: - Add List model struct (ID, Name) to types.go - Add Lists []List field to Board model - Add GetLists method to TrelloAPI interface - Refactor private getLists to return []models.List - Update GetCards to build list map from slice - Add public GetLists method wrapping private implementation - Update GetBoardsWithCards to populate Lists field concurrently - Update mock Trello client in tests to implement GetLists All tests pass. Boards now include their lists for UI rendering. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
-rw-r--r--SESSION_STATE.md35
-rw-r--r--internal/api/interfaces.go1
-rw-r--r--internal/api/trello.go38
-rw-r--r--internal/handlers/handlers_test.go4
-rw-r--r--internal/models/types.go7
-rw-r--r--issues/phase3_step2_trello_lists.md21
6 files changed, 78 insertions, 28 deletions
diff --git a/SESSION_STATE.md b/SESSION_STATE.md
index 570c987..ce4619e 100644
--- a/SESSION_STATE.md
+++ b/SESSION_STATE.md
@@ -1,24 +1,23 @@
# Session State
-**Current Phase:** Phase 3: Interactivity & Write Operations
-**Current Focus:** Step 1: Trello Write Operations
+## Current Phase
+Phase 3: Interactivity & Write Operations
-## Active Issues
-* `issues/phase3_step1_trello_write.md`: Implementing `CreateCard` and `UpdateCard` in Trello client.
+## Active Task
+Step 2: Trello Lists Support (Backend)
-## Completed Issues
-* `issues/bug_002_tab_state.md`: Fixed tab state persistence.
-* `issues/bug_001_template_rendering.md`: Fixed template error in notes tab.
+## Recent Completed Tasks
+* [x] Phase 2.5: Glassmorphism UI (CSS/HTML)
+* [x] Phase 3 Step 1: Trello Write Ops (Create/Update Card)
-## Roadmap
-1. **Phase 3: Interactivity**
- * **Step 1: Trello Write Ops (Active)**
- * Step 2: Todoist Write Ops
- * Step 3: Unified Quick Add
-2. **Phase 4: Security Hardening**
- * Audit API keys handling.
- * Rate limiting.
+## Next Steps
+1. **Implement Trello Lists Support** (Current)
+ * Update models and API client to fetch and expose lists.
+2. **Trello UI Integration**
+ * Add "Add Card" button and modal.
+ * Add "Done" checkbox.
+3. **Todoist Write Ops**
+ * Implement Create/Complete Task.
-## Immediate Next Steps
-1. Implement `CreateCard` and `UpdateCard` in `internal/api/trello.go`.
-2. Verify with `internal/api/trello_test.go`.
+## Context
+We are adding write capabilities. We just implemented `CreateCard` and `UpdateCard` in the Trello client. Now we need to expose the Lists so the UI can present a dropdown for "Add Card".
diff --git a/internal/api/interfaces.go b/internal/api/interfaces.go
index 95cc0e7..31da0a8 100644
--- a/internal/api/interfaces.go
+++ b/internal/api/interfaces.go
@@ -19,6 +19,7 @@ type TodoistAPI interface {
type TrelloAPI interface {
GetBoards(ctx context.Context) ([]models.Board, error)
GetCards(ctx context.Context, boardID string) ([]models.Card, error)
+ GetLists(ctx context.Context, boardID string) ([]models.List, error)
GetBoardsWithCards(ctx context.Context) ([]models.Board, error)
CreateCard(ctx context.Context, listID, name, description string, dueDate *time.Time) (*models.Card, error)
UpdateCard(ctx context.Context, cardID string, updates map[string]interface{}) error
diff --git a/internal/api/trello.go b/internal/api/trello.go
index 5b87e30..9c18ade 100644
--- a/internal/api/trello.go
+++ b/internal/api/trello.go
@@ -128,9 +128,12 @@ func (c *TrelloClient) GetCards(ctx context.Context, boardID string) ([]models.C
// Fetch lists to get list names
lists, err := c.getLists(ctx, boardID)
- if err != nil {
- // If we can't get lists, continue with empty list names
- lists = make(map[string]string)
+ listMap := make(map[string]string)
+ if err == nil {
+ // Build map of list ID to name
+ for _, list := range lists {
+ listMap[list.ID] = list.Name
+ }
}
// Convert to our model
@@ -140,7 +143,7 @@ func (c *TrelloClient) GetCards(ctx context.Context, boardID string) ([]models.C
ID: apiCard.ID,
Name: apiCard.Name,
ListID: apiCard.IDList,
- ListName: lists[apiCard.IDList],
+ ListName: listMap[apiCard.IDList],
URL: apiCard.URL,
}
@@ -158,8 +161,8 @@ func (c *TrelloClient) GetCards(ctx context.Context, boardID string) ([]models.C
return cards, nil
}
-// getLists fetches lists for a board and returns a map of list ID to name
-func (c *TrelloClient) getLists(ctx context.Context, boardID string) (map[string]string, error) {
+// getLists fetches lists for a board
+func (c *TrelloClient) getLists(ctx context.Context, boardID string) ([]models.List, error) {
url := fmt.Sprintf("%s/boards/%s/lists?key=%s&token=%s", c.baseURL, boardID, c.apiKey, c.token)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
@@ -183,15 +186,23 @@ func (c *TrelloClient) getLists(ctx context.Context, boardID string) (map[string
return nil, fmt.Errorf("failed to decode response: %w", err)
}
- // Convert to map
- lists := make(map[string]string, len(apiLists))
- for _, list := range apiLists {
- lists[list.ID] = list.Name
+ // Convert to model
+ lists := make([]models.List, 0, len(apiLists))
+ for _, apiList := range apiLists {
+ lists = append(lists, models.List{
+ ID: apiList.ID,
+ Name: apiList.Name,
+ })
}
return lists, nil
}
+// GetLists fetches lists for a specific board
+func (c *TrelloClient) GetLists(ctx context.Context, boardID string) ([]models.List, error) {
+ return c.getLists(ctx, boardID)
+}
+
// GetBoardsWithCards fetches all boards and their cards in one call
func (c *TrelloClient) GetBoardsWithCards(ctx context.Context) ([]models.Board, error) {
boards, err := c.GetBoards(ctx)
@@ -211,11 +222,18 @@ func (c *TrelloClient) GetBoardsWithCards(ctx context.Context) ([]models.Board,
sem <- struct{}{}
defer func() { <-sem }()
+ // Fetch cards
cards, err := c.GetCards(ctx, boards[i].ID)
if err == nil {
// It is safe to write to specific indices of the slice concurrently
boards[i].Cards = cards
}
+
+ // Fetch lists
+ lists, err := c.getLists(ctx, boards[i].ID)
+ if err == nil {
+ boards[i].Lists = lists
+ }
}(i)
}
diff --git a/internal/handlers/handlers_test.go b/internal/handlers/handlers_test.go
index 902bebb..13973df 100644
--- a/internal/handlers/handlers_test.go
+++ b/internal/handlers/handlers_test.go
@@ -106,6 +106,10 @@ func (m *mockTrelloClient) GetCards(ctx context.Context, boardID string) ([]mode
return []models.Card{}, nil
}
+func (m *mockTrelloClient) GetLists(ctx context.Context, boardID string) ([]models.List, error) {
+ return []models.List{}, nil
+}
+
func (m *mockTrelloClient) CreateCard(ctx context.Context, listID, name, description string, dueDate *time.Time) (*models.Card, error) {
return nil, nil
}
diff --git a/internal/models/types.go b/internal/models/types.go
index d39a1d6..31308fc 100644
--- a/internal/models/types.go
+++ b/internal/models/types.go
@@ -36,11 +36,18 @@ type Meal struct {
RecipeURL string `json:"recipe_url"`
}
+// List represents a Trello list
+type List struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
+
// Board represents a Trello board
type Board struct {
ID string `json:"id"`
Name string `json:"name"`
Cards []Card `json:"cards"`
+ Lists []List `json:"lists"`
}
// Card represents a Trello card
diff --git a/issues/phase3_step2_trello_lists.md b/issues/phase3_step2_trello_lists.md
new file mode 100644
index 0000000..f16e226
--- /dev/null
+++ b/issues/phase3_step2_trello_lists.md
@@ -0,0 +1,21 @@
+# Phase 3 Step 2: Trello Lists Support
+
+## Description
+To enable "Add Card" functionality, we need to know the available lists for each board. Currently, the `Board` model does not include lists, and the API client only fetches lists internally to map names.
+
+## Requirements
+1. **Update Models**: Add `List` struct and `Lists` field to `Board`.
+2. **Update Interface**: Add `GetLists` to `TrelloAPI`.
+3. **Update Client**:
+ * Refactor `getLists` to return `[]models.List`.
+ * Update `GetBoardsWithCards` to populate `board.Lists`.
+ * Implement public `GetLists`.
+
+## Plan
+1. Modify `internal/models/types.go`.
+2. Modify `internal/api/interfaces.go`.
+3. Modify `internal/api/trello.go`.
+
+## Verification
+* Run `go test ./internal/api/...` to ensure no regressions.
+* (Implicit) The UI will eventually use this data.