diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-12 13:23:55 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-12 13:23:55 -1000 |
| commit | 80c233287b65927a012ff46a27d4eac9a796fce0 (patch) | |
| tree | ec69f26c116274b69b5d5c200e4a563f2bdc8445 | |
| parent | 325811c369b77b0a6b15bf81463948a10cb1f658 (diff) | |
Parallelize Trello card fetching for improved performance
Replaced sequential card fetching in GetBoardsWithCards with concurrent
goroutines limited by a semaphore (max 5 concurrent requests). This
significantly reduces load times for users with multiple boards.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
| -rw-r--r-- | SESSION_STATE.md | 32 | ||||
| -rw-r--r-- | internal/api/trello.go | 27 |
2 files changed, 52 insertions, 7 deletions
diff --git a/SESSION_STATE.md b/SESSION_STATE.md new file mode 100644 index 0000000..4481900 --- /dev/null +++ b/SESSION_STATE.md @@ -0,0 +1,32 @@ +# Current Session State + +## 🎯 Active Goal +Phase 1 stability and optimization complete. + +## ✅ Completed +- Initial Phase 1 feature set (Trello, Todoist, Obsidian, PlanToEat) +- AI Snapshot endpoint implementation (`/api/claude/snapshot`) +- Basic testing suite (9/9 passing) +- **Security Fix:** Timing attack vulnerability in Bearer token validation (ai_auth.go:33) +- **Security Fix:** JSON injection in error responses (ai_auth.go:47-50) +- **Database Hardening:** Enabled WAL mode for better concurrency (sqlite.go:32-35) +- **Database Hardening:** Set MaxOpenConns(1) to prevent "database is locked" errors (sqlite.go:38) +- **Security Fix:** SQL injection vulnerability in GetNotes LIMIT clause (sqlite.go:215-221) +- **Commit:** 4c03e9c "Harden database security and reliability" +- **Security Fix:** Path traversal mitigation - skip symbolic links in Obsidian scanner (obsidian.go:54-57) +- **Commit:** 325811c "Mitigate path traversal risk in Obsidian scanner" +- **Performance Optimization:** Parallelized Trello card fetching with semaphore-limited concurrency (trello.go:197-220) + +## 🏗️ Architecture & Decisions +- **Decision:** Use SQLite for caching with a 5-minute TTL. +- **Decision:** Trello is the primary task system, requiring Key+Token auth. +- **Decision:** Agent endpoint uses Bearer token auth for security. +- **Decision:** Limit Trello concurrent requests to 5 to prevent API rate limiting. + +## 📋 Next Steps +1. **Code Quality:** Commit parallelization changes. +2. **Testing:** Add unit tests for security fixes (timing attack, SQL injection, path traversal). +3. **Future:** Consider Phase 2 features (write operations, user management). + +## ⚠️ Known Blockers / Debt +- **Test Coverage:** Security fixes lack dedicated unit tests. diff --git a/internal/api/trello.go b/internal/api/trello.go index 899f6df..cecf0dc 100644 --- a/internal/api/trello.go +++ b/internal/api/trello.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net/http" + "sync" "time" "task-dashboard/internal/models" @@ -193,16 +194,28 @@ func (c *TrelloClient) GetBoardsWithCards(ctx context.Context) ([]models.Board, return nil, err } - // Fetch cards for each board + var wg sync.WaitGroup + sem := make(chan struct{}, 5) // Limit to 5 concurrent requests + for i := range boards { - cards, err := c.GetCards(ctx, boards[i].ID) - if err != nil { - // Log error but continue with other boards - continue - } - boards[i].Cards = cards + wg.Add(1) + go func(i int) { + defer wg.Done() + + // Acquire semaphore + sem <- struct{}{} + defer func() { <-sem }() + + 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 + } + }(i) } + wg.Wait() + return boards, nil } |
