# Phase 3 Step 1: Trello Write Operations **Status:** Active **Priority:** High **Feature:** Interactive Dashboard (Write Ops) ## Description Currently, the Trello client is read-only. We need to implement `CreateCard` and `UpdateCard` to enable interactivity (adding tasks, moving cards, completing items). ## Requirements 1. **CreateCard:** * Method: `POST /1/cards` * Parameters: `name`, `idList`, `desc` (optional), `due` (optional). * Returns: Created `models.Card`. 2. **UpdateCard:** * Method: `PUT /1/cards/{id}` * Parameters: Flexible map of updates (e.g., `idList` to move, `closed=true` to archive). * Returns: Updated `models.Card` (or just error). ## Reproduction / Test Plan Since we cannot hit the real Trello API in tests, we will use `httptest.Server` to mock the API responses. ### `internal/api/trello_test.go` ```go package api import ( "encoding/json" "net/http" "net/http/httptest" "testing" "time" "task-dashboard/internal/models" ) func TestTrelloClient_CreateCard(t *testing.T) { // Mock Server server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { t.Errorf("Expected POST, got %s", r.Method) } if r.URL.Path != "/1/cards" { t.Errorf("Expected /1/cards, got %s", r.URL.Path) } // Verify params r.ParseForm() if r.Form.Get("name") != "New Task" { t.Errorf("Expected name='New Task', got %s", r.Form.Get("name")) } // Return mock response card := models.Card{ ID: "new-card-id", Name: "New Task", } json.NewEncoder(w).Encode(card) })) defer server.Close() client := &TrelloClient{ BaseURL: server.URL, Key: "test-key", Token: "test-token", Client: server.Client(), } card, err := client.CreateCard("list-id", "New Task", "Description", nil) if err != nil { t.Fatalf("CreateCard failed: %v", err) } if card.ID != "new-card-id" { t.Errorf("Expected ID 'new-card-id', got %s", card.ID) } } ```