summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PHASE_2_SURGICAL_PLAN.md114
-rw-r--r--PROJECT_SUMMARY.md209
-rw-r--r--QUICKSTART.md121
-rw-r--r--SECURITY_CHECKLIST.md227
-rw-r--r--SETUP_GUIDE.md200
-rw-r--r--TRELLO_AUTH_UPDATE.md78
-rw-r--r--implementation-plan.md397
-rw-r--r--spec.md383
8 files changed, 0 insertions, 1729 deletions
diff --git a/PHASE_2_SURGICAL_PLAN.md b/PHASE_2_SURGICAL_PLAN.md
deleted file mode 100644
index 438f5ee..0000000
--- a/PHASE_2_SURGICAL_PLAN.md
+++ /dev/null
@@ -1,114 +0,0 @@
-# Phase 2: The Productivity OS (Interactive & Refined)
-
-This phase transforms the dashboard into a primary interface with write capabilities, smart sorting, and a refined "Glassmorphism" UI.
-
-## 1. The Unified Atom Model
-**Status:** [x] Complete
-
-```text
-Define `models.Atom` to abstract over Trello, Todoist, Obsidian, and PlanToEat.
-Implement mapper functions.
-
-1. **Model:** Create `internal/models/atom.go` with:
- - AtomSource enum (trello, todoist, obsidian, plantoeat)
- - AtomType enum (task, note, meal)
- - Atom struct with normalized fields (ID, Title, Description, DueDate, Priority, etc.)
- - UI helper fields (SourceIcon, ColorClass)
- - Raw field for preserving original data
-2. **Mappers:** Implement converter functions:
- - TaskToAtom(Task) -> Atom
- - CardToAtom(Card) -> Atom
- - NoteToAtom(Note) -> Atom
- - MealToAtom(Meal) -> Atom
-3. **Priority Mapping:** Normalize priority scales to 1-4 (Low to Urgent)
-4. **Color Mapping:** Assign brand colors (Trello=Blue, Todoist=Red, Obsidian=Purple, PlanToEat=Green)
-```
-
-## 2. Information Architecture: The 4-Tab Split
-**Status:** [x] Complete
-
-```text
-Refactor the frontend and router to support 4 distinct tabs.
-
-1. **Templates:** Update `web/templates/index.html` navigation to:
- - Tasks (Todoist + Due Trello)
- - Planning (Trello Boards)
- - Notes (Obsidian)
- - Meals (PlanToEat)
-2. **Handlers:** Create/Update handlers in `internal/handlers/tabs.go` (new file):
- - `HandleTasksTab`: Aggregates Todoist + Trello cards with due dates.
- - `HandlePlanningTab`: Returns Trello boards (excluding cards shown in Tasks?).
- - `HandleMealsTab`: Returns PlanToEat data.
-3. **Router:** Register new routes `/tabs/tasks`, `/tabs/planning`, `/tabs/meals`.
-```
-
-## 3. Trello: Smart Sorting & Logic
-**Status:** [x] Complete
-
-```text
-Enhance Trello sorting in `internal/api/trello.go` and `internal/store/sqlite.go`.
-
-1. **Backend:** Update `GetBoardsWithCards` to sort by:
- - Primary: Has active cards?
- - Secondary: Newest card modification date (requires parsing Trello ID hex timestamp).
- - Tertiary: Number of cards.
-2. **Store:** Update SQL query in `GetBoards` to reflect this sort order.
-```
-
-## 4. Todoist: "Due First" Sorting
-**Status:** [x] Complete
-
-```text
-Ensure Todoist tasks are sorted by urgency.
-
-1. **Store:** Edit `internal/store/sqlite.go` -> `GetTasks`.
-2. **Query:** Update ORDER BY clause:
- - `CASE WHEN due_date IS NULL THEN 1 ELSE 0 END` (Due dates first)
- - `due_date ASC` (Earliest first)
- - `priority DESC` (High priority next)
-```
-
-## 5. Obsidian: Search & Categorization
-**Status:** [x] Complete
-
-```text
-Enhance Obsidian to support search and categorization.
-
-1. **Backend:** Edit `internal/api/obsidian.go`.
- - Add `SearchNotes(query string)`.
- - Add logic to group notes by tags (e.g., #planning, #task, #meal).
-2. **Frontend:** Add a Search Bar to the Notes tab.
- - HTMX trigger: `hx-get="/tabs/notes/search" hx-trigger="keyup changed delay:500ms"`.
-```
-
-## 6. Visual Overhaul: "Muted Landscape"
-**Status:** [ ] Pending
-
-```text
-Apply the new visual design.
-
-1. **CSS:** Update Tailwind config for "muted" palette.
-2. **Layout:** Add a full-screen background image container.
-3. **Components:** Update cards to use `bg-white/80 backdrop-blur-md` (Glassmorphism).
-```
-
-## 7. Write Operations (The "Primary Interface" Goal)
-**Status:** [ ] Pending
-
-```text
-Implement the interactive features.
-
-1. **Trello:** Implement `UpdateCard` (Archive) and "Mark Complete" button.
-2. **Obsidian:** Implement `CreateNote` (Quick Capture) and "New Note" form.
-```
-
-## 8. Mobile PWA
-**Status:** [ ] Pending
-
-```text
-Make it installable.
-
-1. Create `web/static/manifest.json`.
-2. Add icons.
-3. Link manifest in `index.html`.
-```
diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md
deleted file mode 100644
index daa36eb..0000000
--- a/PROJECT_SUMMARY.md
+++ /dev/null
@@ -1,209 +0,0 @@
-# Project Summary
-
-## What This Is
-
-A **unified personal dashboard** that aggregates your productivity data into one place:
-- 📋 **Trello boards** (your primary task system)
-- ✓ **Todoist tasks**
-- 📝 **Obsidian notes** (optional)
-- 🍽️ **PlanToEat meals** (optional)
-
-## Current Status: ✅ Phase 1 Complete
-
-### What Works
-- ✅ Trello integration (all boards + cards)
-- ✅ Todoist integration (tasks + projects)
-- ✅ Obsidian integration (20 most recent notes)
-- ✅ PlanToEat integration (optional - API not public)
-- ✅ Mobile-responsive web UI
-- ✅ SQLite caching (5-min TTL)
-- ✅ Auto-refresh (5 min)
-- ✅ Full test coverage (9/9 tests passing)
-
-### Statistics
-- **Binary size:** 17MB
-- **Code:** 2,667 lines
-- **Dependencies:** chi router, sqlite3, Go 1.21+
-- **Tests:** 5 unit tests, 4 acceptance tests
-
-## Quick Start
-
-### 1. Get API Keys (5 minutes)
-
-**Todoist:**
-1. Go to https://todoist.com/app/settings/integrations
-2. Copy API token
-
-**Trello:**
-1. Go to https://trello.com/power-ups/admin
-2. Create a Power-Up
-3. Go to **API Key** tab → Generate new API key (NOT Secret!)
-4. Follow "testing/for-yourself" instructions → Click **Token** link
-5. Copy both API Key + Token
-
-### 2. Configure
-
-```bash
-cp .env.example .env
-# Edit .env:
-TODOIST_API_KEY=your_todoist_token
-TRELLO_API_KEY=your_trello_key
-TRELLO_TOKEN=your_trello_token
-```
-
-### 3. Run
-
-```bash
-go run cmd/dashboard/main.go
-```
-
-### 4. Open
-
-http://localhost:8080
-
-**That's it!** 🎉
-
-## Documentation
-
-- **[QUICKSTART.md](QUICKSTART.md)** - Get running in 5 minutes
-- **[SETUP_GUIDE.md](SETUP_GUIDE.md)** - Detailed setup instructions
-- **[README.md](README.md)** - Full project documentation
-
-## Architecture
-
-### Request Flow
-```
-Browser → chi Router → Handler
- ↓
- Check SQLite Cache (5min TTL)
- ↓
- Fresh? → Return cached data
- Stale? → Fetch from APIs in parallel
- ↓
- Trello + Todoist + Obsidian + PlanToEat
- ↓
- Save to cache → Return data
-```
-
-### Key Files
-```
-cmd/dashboard/main.go Entry point
-internal/
- ├── api/ API clients
- │ ├── trello.go Trello (PRIORITY)
- │ ├── todoist.go Todoist tasks
- │ ├── obsidian.go Markdown notes
- │ └── plantoeat.go Meal planning
- ├── handlers/
- │ ├── handlers.go Web handlers
- ├── config/config.go Environment config
- └── store/sqlite.go Database ops
-web/
- ├── templates/index.html Dashboard UI
- └── static/ CSS/JS
-```
-
-## API Endpoints
-
-### Web Dashboard
-- `GET /` - Main dashboard view
-- `POST /api/refresh` - Force refresh all data
-- `GET /api/tasks` - Tasks JSON
-- `GET /api/notes` - Notes JSON
-- `GET /api/meals` - Meals JSON
-- `GET /api/boards` - Trello boards JSON
-
-## What's Optional
-
-### Optional Features
-- **PlanToEat:** API not publicly available - leave blank
-- **Obsidian:** Only if you use Obsidian notes
-
-### Required Features
-- **Todoist:** Yes - tasks integration
-- **Trello:** Yes - your primary task system
-
-## Configuration
-
-All via `.env` file:
-
-```bash
-# Required
-TODOIST_API_KEY=...
-TRELLO_API_KEY=...
-TRELLO_TOKEN=...
-
-# Optional
-OBSIDIAN_VAULT_PATH=/path/to/vault
-
-# Server (with defaults)
-PORT=8080
-CACHE_TTL_MINUTES=5
-DEBUG=false
-```
-
-## Development
-
-### Run Tests
-```bash
-go test ./...
-```
-
-### Build Binary
-```bash
-go build -o dashboard cmd/dashboard/main.go
-```
-
-### Run with Live Reload
-```bash
-go install github.com/cosmtrek/air@latest
-air
-```
-
-## Troubleshooting
-
-### "TODOIST_API_KEY is required"
-Make sure `.env` has all three required keys:
-```bash
-TODOIST_API_KEY=something
-TRELLO_API_KEY=something
-TRELLO_TOKEN=something
-```
-
-### "No boards showing"
-- Check Trello credentials at https://trello.com/power-ups/admin
-- Need **both** API key (from Power-Up's API Key tab) and token (click "Token" link)
-
-### "PlanToEat not working"
-- Expected - API not public
-- Just leave `PLANTOEAT_API_KEY` empty
-- Dashboard works fine without it
-
-## What's Next
-
-### Phase 2 (In Progress)
-- [x] Mark tasks complete
-- [x] Create Trello cards
-- [x] Create Todoist tasks
-- [ ] Quick note capture
-
-### Phase 3 (Future)
-- Unified search
-- Daily digest
-- PWA support
-
-## License
-
-MIT License - personal use project
-
-## Support
-
-- Check logs: Terminal where you ran `go run cmd/dashboard/main.go`
-- Test endpoints: `curl http://localhost:8080/api/tasks`
-- Verify API keys: Try them directly in curl (see SETUP_GUIDE.md)
-
----
-
-**Built with:** Go 1.21+ • SQLite • chi router • Tailwind CSS • HTMX
-
-**Last Updated:** January 2026
diff --git a/QUICKSTART.md b/QUICKSTART.md
deleted file mode 100644
index e8dbf71..0000000
--- a/QUICKSTART.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# Quick Start Guide
-
-## 5-Minute Setup
-
-### 1. Get API Keys
-
-#### Todoist (Required)
-1. Go to https://todoist.com/app/settings/integrations
-2. Scroll to "Developer" section
-3. Copy your **API token**
-
-#### Trello (Required)
-1. Go to https://trello.com/power-ups/admin
-2. Create a Power-Up (any name, e.g., "Personal Dashboard")
-3. Go to **API Key** tab
-4. Click **"Generate a new API Key"** and copy it (NOT the Secret!)
-5. In the API Key description, follow the "testing/for-yourself" instructions
-6. Click the **Token** link to generate a personal token
-7. Click **"Allow"** and copy the token
-
-**Important:** You need the API Key + Token (NOT the Secret). The Secret is for OAuth and not used for personal access.
-
-**That's it!** You now have everything you need.
-
-### 2. Configure
-
-```bash
-# Copy template
-cp .env.example .env
-
-# Edit .env and add:
-TODOIST_API_KEY=your_todoist_token
-TRELLO_API_KEY=your_trello_key
-TRELLO_TOKEN=your_trello_token
-```
-
-### 3. Run
-
-```bash
-go run cmd/dashboard/main.go
-```
-
-### 4. Access
-
-Open http://localhost:8080 in your browser!
-
----
-
-## Optional: Add More Features
-
-### Obsidian Notes
-Add to `.env`:
-```bash
-OBSIDIAN_VAULT_PATH=/path/to/your/vault
-```
-
-### Claude.ai Access
-```bash
-# Generate key
-openssl rand -hex 32
-
-# Add to .env
-AI_AGENT_API_KEY=generated_key_here
-```
-
-Then share with Claude:
-- URL: `http://localhost:8080/api/claude/snapshot`
-- Token: (your AI_AGENT_API_KEY)
-
----
-
-## What You'll See
-
-**Main Dashboard:**
-- 📋 **Trello Boards** at the top (your primary view)
-- ✓ **Todoist Tasks** below
-- 📝 **Recent Notes** (if Obsidian configured)
-- 🍽️ **Meal Plans** (if PlanToEat configured - optional)
-
-**Features:**
-- Auto-refresh every 5 minutes
-- Manual refresh button
-- Mobile-responsive design
-- Fast SQLite caching
-
----
-
-## Troubleshooting
-
-### Can't start - missing API keys
-Make sure your `.env` has:
-```bash
-TODOIST_API_KEY=something
-TRELLO_API_KEY=something
-TRELLO_TOKEN=something
-```
-
-All three are required. Get them from:
-- Todoist: https://todoist.com/app/settings/integrations
-- Trello: https://trello.com/power-ups/admin (create Power-Up, generate both from API Key tab)
-
-### No boards showing
-- Check your Trello API key and token are correct
-- Make sure you have boards in your Trello account
-- Click the refresh button
-
-### No tasks showing
-- Verify Todoist API token is correct
-- Check you have active tasks in Todoist
-
----
-
-## Next Steps
-
-1. ✅ Dashboard is running
-2. Check that data is loading
-3. Test the refresh button
-4. (Optional) Set up Claude.ai access
-5. Start using your unified dashboard!
-
-Need more details? See `SETUP_GUIDE.md` for comprehensive instructions.
diff --git a/SECURITY_CHECKLIST.md b/SECURITY_CHECKLIST.md
deleted file mode 100644
index 46b8cea..0000000
--- a/SECURITY_CHECKLIST.md
+++ /dev/null
@@ -1,227 +0,0 @@
-# Security & Quality Checklist
-
-## Critical Security Issues (Must Fix Before Production)
-
-### Database Security
-- [x] **SQL Injection in GetNotes()** (15 min)
- - File: `internal/store/sqlite.go:208`
- - Change: Use parameterized query for LIMIT clause
- - Impact: Prevents SQL injection attacks
-
-- [ ] **SQLite Concurrency Configuration** (30 min)
- - File: `internal/store/sqlite.go:22-30`
- - Change: Set `MaxOpenConns(1)`, enable WAL mode
- - Impact: Prevents "database is locked" errors under concurrent load
-
-- [ ] **Database File Permissions** (15 min)
- - File: `internal/store/sqlite.go:22-24`
- - Change: Set file to 0600, create dir with 0700
- - Impact: Prevents unauthorized access to cached data
-
-### Input/Output Security
-- [ ] **Path Traversal in Obsidian** (1 hour)
- - File: `internal/api/obsidian.go:49-70`
- - Change: Validate paths stay within vault, skip symlinks
- - Impact: Prevents arbitrary file read attacks
-
-### Network Security
-- [ ] **HTTPS Support** (1 hour)
- - File: `cmd/dashboard/main.go:86-94`
- - Change: Add TLS configuration and ListenAndServeTLS
- - Impact: Prevents credential theft via network sniffing
-
----
-
-## High Priority Issues (Should Fix Soon)
-
-### Concurrency & Performance
-- [ ] **Context Cancellation in Goroutines** (30 min)
- - File: `internal/handlers/handlers.go:151-207`
- - Change: Check `ctx.Done()` before locking mutex in each goroutine
- - Impact: Prevents goroutine leaks and resource exhaustion
-
-- [ ] **Parallelize Trello Card Fetching** (1 hour)
- - File: `internal/api/trello.go:196-204`
- - Change: Use goroutines with bounded concurrency for card fetching
- - Impact: Reduces API call time from N+1 sequential to parallel
-
-- [ ] **Reduce Mutex Contention in aggregateData** (45 min)
- - File: `internal/handlers/handlers.go:154-205`
- - Change: Store results locally, lock only for final assignment
- - Impact: Better parallelism, faster page loads
-
-- [ ] **HTTP Client Connection Pooling** (30 min)
- - File: `internal/api/*.go` (all clients)
- - Change: Configure Transport with MaxIdleConns, MaxIdleConnsPerHost
- - Impact: Prevents port exhaustion and API rate limiting
-
-### Security Hardening
-- [ ] **Rate Limiting on Endpoints** (1 hour)
- - File: `cmd/dashboard/main.go:67, 73`
- - Change: Add rate limiting middleware
- - Impact: Prevents DoS attacks and API quota exhaustion
-
-- [ ] **CSRF Protection** (2 hours)
- - File: `cmd/dashboard/main.go:67`
- - Change: Add CSRF middleware for POST endpoints
- - Impact: Prevents cross-site request forgery (needed for Phase 2)
-
-- [ ] **Sanitize API Keys in Logs** (30 min)
- - File: `internal/api/*.go` (all clients)
- - Change: Redact keys/tokens in error messages
- - Impact: Prevents credential leaks via log files
-
-### Error Handling
-- [ ] **Check JSON Unmarshal Errors** (30 min)
- - File: `internal/store/sqlite.go:155, 234`
- - Change: Log errors, provide defaults
- - Impact: Prevents silent data loss
-
-- [ ] **Sanitize Error Messages** (1 hour)
- - File: `internal/handlers/handlers.go` (multiple locations)
- - Change: Return generic errors to users, log details internally
- - Impact: Prevents information disclosure
-
----
-
-## Medium Priority Issues (Nice to Have)
-
-### Code Quality
-- [ ] **Database Connection Health Check** (15 min)
- - File: `internal/store/sqlite.go:22-30`
- - Change: Add `db.Ping()` after opening connection
- - Impact: Fail fast on database issues
-
-- [ ] **Null Object Pattern for Optional Clients** (1 hour)
- - File: `internal/handlers/handlers.go`, `cmd/dashboard/main.go`
- - Change: Implement null objects instead of nil checks
- - Impact: Eliminates nil pointer risks
-
-- [ ] **Context Timeouts for Database Operations** (2 hours)
- - File: `internal/store/sqlite.go` (all methods)
- - Change: Use `QueryContext`, `ExecContext`, add context parameters
- - Impact: Prevents indefinite blocking
-
-- [ ] **Validate API Response Data** (2 hours)
- - File: `internal/api/*.go` (all clients)
- - Change: Add validation functions for API responses
- - Impact: Protection against malicious API servers
-
-### Testing
-- [ ] **Add Edge Case Tests** (2 hours)
- - Files: Various test files
- - Tests: Empty responses, malformed JSON, network errors
- - Impact: More robust error handling
-
-### Security Headers
-- [ ] **Add Security Headers Middleware** (30 min)
- - File: `cmd/dashboard/main.go`
- - Change: Add X-Frame-Options, CSP, X-Content-Type-Options, etc.
- - Impact: Defense in depth
-
-- [ ] **Content Security Policy** (1 hour)
- - File: `cmd/dashboard/main.go`
- - Change: Add CSP header with appropriate directives
- - Impact: XSS protection
-
-### Configuration
-- [ ] **Validate Config at Startup** (30 min)
- - File: `internal/config/config.go:61-76`
- - Change: Add token strength validation, file path checks
- - Impact: Fail fast on misconfiguration
-
-- [ ] **Make HTTP Timeouts Configurable** (30 min)
- - File: `internal/api/*.go` (all clients)
- - Change: Add `APITimeoutSeconds` to config
- - Impact: Flexibility for different environments
-
----
-
-## Low Priority / Future Enhancements
-
-### Monitoring & Observability
-- [ ] **Structured Logging** (4 hours)
- - Change: Replace log.Printf with structured logger (zap/zerolog)
- - Impact: Better log analysis and debugging
-
-- [ ] **Health Check Endpoint** (30 min)
- - File: `cmd/dashboard/main.go`
- - Change: Add `/health` endpoint checking DB, API connectivity
- - Impact: Better monitoring
-
-- [ ] **Metrics Collection** (4 hours)
- - Change: Add Prometheus metrics for API calls, cache hits, errors
- - Impact: Performance monitoring
-
-### Code Organization
-- [ ] **Extract Constants** (1 hour)
- - Files: Various
- - Change: Move magic numbers to constants
- - Impact: Better maintainability
-
-- [ ] **Standardize Error Messages** (1 hour)
- - Files: Various
- - Change: Consistent capitalization and formatting
- - Impact: Better UX
-
-### Database
-- [ ] **Database Encryption at Rest** (2 hours)
- - File: `internal/store/sqlite.go`
- - Change: Use SQLCipher
- - Impact: Data protection
-
-- [ ] **Migration Versioning Table** (1 hour)
- - File: `internal/store/sqlite.go:41-68`
- - Change: Track which migrations have run
- - Impact: Better migration management
-
----
-
-## Estimated Time Summary
-
-| Priority | Count | Estimated Time |
-|----------|-------|----------------|
-| Critical | 4 items | ~2.5 hours |
-| High | 7 items | ~6.5 hours |
-| Medium | 8 items | ~9.5 hours |
-| Low | 8 items | ~14 hours |
-| **Total** | **27 items** | **~32.5 hours** |
-
-### Recommended Sprint 1 (Critical + High Priority)
-- **Duration**: 1-2 weeks part-time
-- **Items**: 11 items
-- **Time**: ~9 hours
-- **Focus**: Security hardening and performance
-
-### Recommended Sprint 2 (Medium Priority)
-- **Duration**: 1-2 weeks part-time
-- **Items**: 8 items
-- **Time**: ~9.5 hours
-- **Focus**: Code quality and testing
-
----
-
-## Quick Wins (< 30 minutes each)
-
-These can be done in small chunks:
-
-1. ✓ SQL injection fix (15 min)
-2. ✓ Database permissions (15 min)
-3. ✓ Health check endpoint (15 min)
-4. ✓ Security headers middleware (30 min)
-5. ✓ Database ping check (15 min)
-6. ✓ Check JSON unmarshal errors (30 min)
-7. ✓ Extract constants (30 min)
-8. ✓ Config validation (30 min)
-
-**Total Quick Wins**: ~3.5 hours, addresses 8 issues
-
----
-
-## Notes
-
-- Priority order considers both security impact and implementation effort
-- Times are estimates for an experienced Go developer
-- Some items may reveal additional issues during implementation
-- Testing time not included (add ~30% for comprehensive testing)
-- Code review time not included (add ~20% for peer review)
diff --git a/SETUP_GUIDE.md b/SETUP_GUIDE.md
deleted file mode 100644
index 9e208c8..0000000
--- a/SETUP_GUIDE.md
+++ /dev/null
@@ -1,200 +0,0 @@
-# Setup Guide
-
-## Step-by-Step API Key Setup
-
-### 1. Todoist (Required)
-
-1. Log in to [Todoist](https://todoist.com)
-2. Click your profile icon → **Settings**
-3. Go to **Integrations** tab
-4. Scroll down to **Developer** section
-5. Copy your **API token**
-6. Add to `.env`: `TODOIST_API_KEY=your_token_here`
-
-### 2. Trello (Required)
-
-Trello requires **both** an API key and a token:
-
-1. Go to https://trello.com/power-ups/admin
-2. Click **"Create a Power-Up"** (or select an existing one)
- - Name: "Personal Dashboard" (or anything you prefer)
- - Workspace: Select your workspace
- - Click "Create"
-3. In your Power-Up, go to the **"API Key"** tab
-4. Click **"Generate a new API Key"**
-5. **Copy the API Key** shown
- - ⚠️ **Important:** Copy the **API Key**, NOT the **Secret**
- - Add to `.env`: `TRELLO_API_KEY=abc123...`
-6. In the description text below the API Key, look for instructions about "testing" or "for-yourself"
-7. Click the **"Token"** link in those instructions (or "manually generate a Token")
-8. Click **"Allow"** to authorize access to your account
-9. **Copy the Token** shown on the next page
- - Add to `.env`: `TRELLO_TOKEN=xyz789...`
-
-**Example `.env` for Trello:**
-```bash
-TRELLO_API_KEY=a1b2c3d4e5f6... # API Key (not Secret!)
-TRELLO_TOKEN=1234567890abcdef... # Personal token for testing
-```
-
-**Common Confusion:**
-- ❌ Don't use the "Secret" - that's for OAuth apps
-- ✅ Use API Key + Token (from the testing/personal use instructions)
-
-### 3. Obsidian (Optional)
-
-If you use Obsidian for notes:
-
-1. Find your Obsidian vault folder (usually in Documents/Obsidian)
-2. Copy the **full path** to your vault
-3. Add to `.env`: `OBSIDIAN_VAULT_PATH=/path/to/your/vault`
-
-**Examples:**
-- macOS: `/Users/yourname/Documents/Obsidian/MyVault`
-- Linux: `/home/yourname/Documents/Obsidian/MyVault`
-- Windows: `C:\Users\yourname\Documents\Obsidian\MyVault`
-
-### 4. PlanToEat (Optional - Skip if no access)
-
-**Note:** PlanToEat's API is not publicly documented or easily accessible.
-
-If you don't have a PlanToEat API key, simply **leave it blank** in `.env`:
-```bash
-# PLANTOEAT_API_KEY= # Leave commented out or empty
-```
-
-The dashboard will work fine without it - you just won't see meal planning data.
-
-### 5. AI Agent Access (Optional)
-
-For Claude.ai to access your dashboard:
-
-1. Generate a secure API key:
- ```bash
- openssl rand -hex 32
- ```
-
-2. Add to `.env`:
- ```bash
- AI_AGENT_API_KEY=a1b2c3d4e5f6...
- ```
-
-3. Share the URL + token with Claude separately
-
-## Complete .env Example
-
-```bash
-# Required
-TODOIST_API_KEY=abc123def456...
-TRELLO_API_KEY=a1b2c3d4e5f6...
-TRELLO_TOKEN=1234567890abcdef...
-
-# Optional
-OBSIDIAN_VAULT_PATH=/Users/yourname/Documents/Obsidian/MyVault
-# PLANTOEAT_API_KEY= # Not publicly available
-AI_AGENT_API_KEY=xyz789...
-
-# Server settings (optional)
-PORT=8080
-CACHE_TTL_MINUTES=5
-DEBUG=false
-```
-
-## Running the Dashboard
-
-1. **Copy environment template:**
- ```bash
- cp .env.example .env
- ```
-
-2. **Edit `.env`** with your API keys (see above)
-
-3. **Run the application:**
- ```bash
- go run cmd/dashboard/main.go
- ```
-
-4. **Access the dashboard:**
- - Web UI: http://localhost:8080
- - AI endpoint: http://localhost:8080/api/claude/snapshot
-
-## Troubleshooting
-
-### "TODOIST_API_KEY is required"
-- Make sure you've added `TODOIST_API_KEY=...` to `.env`
-- No spaces around the `=` sign
-- No quotes needed
-
-### "TRELLO_API_KEY is required"
-- You need **both** `TRELLO_API_KEY` and `TRELLO_TOKEN`
-- Get both from https://trello.com/power-ups/admin
-- Create a Power-Up, go to "API Key" tab
-- Copy the API Key (NOT the Secret!)
-- Follow the "testing/for-yourself" instructions to generate a token
-
-### "TRELLO_TOKEN is required"
-- In Power-Up Admin Portal (https://trello.com/power-ups/admin)
-- Go to your Power-Up's "API Key" tab
-- Look for "testing/for-yourself" instructions in the description
-- Click the "Token" link in those instructions (NOT the Secret!)
-- Click "Allow" to authorize
-- Copy the long token string
-
-### No Trello boards showing
-- Verify both API key and token are correct
-- Check that you have boards in your Trello account
-- Try the "Refresh" button on the dashboard
-
-### No tasks showing
-- Verify your Todoist API token is correct
-- Check that you have tasks in Todoist
-- Make sure tasks aren't all completed
-
-### Obsidian notes not showing
-- Verify the vault path is correct and exists
-- Make sure the application has read permissions
-- Check that you have `.md` files in the vault
-
-### PlanToEat not working
-- This is expected - PlanToEat's API is not publicly available
-- Simply leave `PLANTOEAT_API_KEY` empty or commented out
-- The dashboard will work without it
-
-## Testing Your Setup
-
-### Test Todoist
-```bash
-curl -H "Authorization: Bearer YOUR_TODOIST_KEY" \
- https://api.todoist.com/rest/v2/tasks
-```
-
-Should return your tasks in JSON format.
-
-### Test Trello
-```bash
-curl "https://api.trello.com/1/members/me/boards?key=YOUR_API_KEY&token=YOUR_TOKEN"
-```
-
-Should return your boards in JSON format. If you get a 401 error, verify both your API key and token are correct.
-
-### Test Dashboard
-```bash
-# Start the server
-go run cmd/dashboard/main.go
-
-# In another terminal, test the endpoint
-curl http://localhost:8080/api/tasks
-```
-
-Should return your tasks from the dashboard.
-
-## Next Steps
-
-Once everything is set up:
-1. Visit http://localhost:8080 to see your dashboard
-2. Check that Trello boards appear at the top
-3. Verify Todoist tasks are listed
-4. Test the manual refresh button
-5. If you set up AI access, test with Claude!
-
-Need help? Check the logs in the terminal where you ran `go run cmd/dashboard/main.go`.
diff --git a/TRELLO_AUTH_UPDATE.md b/TRELLO_AUTH_UPDATE.md
deleted file mode 100644
index eee0533..0000000
--- a/TRELLO_AUTH_UPDATE.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Trello Authentication Update
-
-## What Changed (January 2026)
-
-Trello moved from the simple app-key page to a Power-Up based API key system.
-
-### Old Process (Deprecated)
-- Go to https://trello.com/app-key
-- API key shown at top of page
-- Click "Token" link to generate token
-
-### New Process (Current)
-1. Go to https://trello.com/power-ups/admin
-2. Create a Power-Up (any name, e.g., "Personal Dashboard")
-3. Go to the Power-Up's **"API Key"** tab
-4. Click **"Generate a new API Key"**
-5. Copy the **API Key** (NOT the Secret - you won't use that!)
-6. In the description below the API Key, find the "testing/for-yourself" instructions
-7. Click the **"Token"** link in those instructions
-8. Click **"Allow"** to authorize
-9. Copy the token
-
-**Important Note:**
-- The API Key tab shows both an **API Key** and a **Secret**
-- For personal use, you need: **API Key + Token** (NOT Secret)
-- The Secret is only used for OAuth applications, not personal access
-- Follow the "testing" or "for-yourself" instructions to generate your token
-
-## What Stayed the Same
-
-### Authentication Method
-The actual API authentication hasn't changed:
-- Still uses API Key + Token
-- Still passed as query parameters: `?key=XXX&token=YYY`
-- No code changes needed in `internal/api/trello.go`
-
-### API Endpoints
-All Trello API endpoints remain the same:
-- Base URL: `https://api.trello.com/1`
-- `/members/me/boards` - Get user boards
-- `/boards/{id}/cards` - Get board cards
-- `/boards/{id}/lists` - Get board lists
-
-## Code Impact
-
-✅ **No code changes required**
-
-The application code already uses the correct authentication method. Only documentation needed updates.
-
-## Documentation Updated
-
-All documentation has been updated to reflect the new process:
-- ✅ `.env.example` - Updated instructions
-- ✅ `START_HERE.md` - Updated quick start
-- ✅ `QUICKSTART.md` - Updated 5-min guide
-- ✅ `README.md` - Updated installation steps
-- ✅ `SETUP_GUIDE.md` - Updated detailed setup and troubleshooting
-- ✅ `PROJECT_SUMMARY.md` - Updated quick reference
-- ✅ `CLAUDE.md` - Updated for Claude Code instances
-
-## References
-
-- New Power-Up Admin Portal: https://trello.com/power-ups/admin
-- Trello REST API Docs: https://developer.atlassian.com/cloud/trello/rest/
-- Authorization Guide: https://developer.atlassian.com/cloud/trello/guides/rest-api/authorization/
-
-## Testing
-
-Authentication works the same way. Test with:
-```bash
-curl "https://api.trello.com/1/members/me/boards?key=YOUR_KEY&token=YOUR_TOKEN"
-```
-
-Should return JSON array of your boards. A 401 error means invalid credentials.
-
----
-
-**Last Updated:** January 12, 2026
diff --git a/implementation-plan.md b/implementation-plan.md
deleted file mode 100644
index 502e534..0000000
--- a/implementation-plan.md
+++ /dev/null
@@ -1,397 +0,0 @@
-# Implementation Plan: Personal Consolidation Dashboard
-
-## Project Overview
-Build a unified web dashboard aggregating tasks (Todoist), notes (Obsidian), and meal planning (PlanToEat) using Go backend and responsive frontend.
-
-## Development Phases
-
-### Phase 1: Foundation & Read-Only Aggregation (MVP)
-**Goal:** Display aggregated data from all services in a single dashboard
-
-#### Step 1: Project Setup
-- [x] Initialize Go module (`go mod init`)
-- [ ] Create project directory structure
-- [ ] Set up `.env.example` with all required API keys
-- [ ] Add `.gitignore` for Go projects
-- [ ] Create `README.md` with setup instructions
-
-#### Step 2: Core Backend Infrastructure
-**Priority: High**
-
-1. **Database Layer** (`internal/store/sqlite.go`)
- - Initialize SQLite connection
- - Create tables for cached data:
- - `tasks` (Todoist)
- - `notes` (Obsidian)
- - `meals` (PlanToEat)
- - `cache_metadata` (last fetch times, TTL)
- - Implement CRUD operations
- - Add migration support (manual SQL files in `migrations/`)
-
-2. **Configuration** (`internal/config/config.go`)
- - Load environment variables
- - Validate required API keys
- - Provide configuration struct to handlers
-
-3. **Data Models** (`internal/models/types.go`)
- - Implement Task struct (Todoist)
- - Implement Note struct (Obsidian)
- - Implement Meal struct (PlanToEat)
- - Implement Board/Card structs (Trello - optional)
-
-#### Step 3: API Integrations (Sequential Implementation)
-**Priority: High**
-
-**3.1: Todoist Integration** (`internal/api/todoist.go`)
-- Implement HTTP client with Bearer token auth
-- Create `GetTasks()` - fetch all active tasks
-- Create `GetProjects()` - fetch project list
-- Parse API responses into Task structs
-- Add error handling and rate limiting
-- Test with real API token
-
-**3.2: Obsidian Integration** (`internal/api/obsidian.go`)
-- Read vault directory from env variable
-- Implement file scanner (limit to 20 most recent)
-- Parse markdown files
-- Extract YAML frontmatter for tags/metadata
-- Handle file read errors gracefully
-
-**3.3: PlanToEat Integration** (`internal/api/plantoeat.go`)
-- Implement HTTP client with API key auth
-- Create `GetPlannerItems()` - fetch upcoming meals (7 days)
-- Create `GetRecipeDetails()` - fetch recipe info
-- Parse API responses into Meal structs
-- Add error handling
-
-**3.4: Trello Integration (Optional)** (`internal/api/trello.go`)
-- Implement HTTP client with API Key + Token
-- Create `GetBoards()` - fetch user's boards
-- Create `GetCards()` - fetch cards from specific boards
-- Parse API responses
-
-#### Step 4: Backend HTTP Handlers
-**Priority: High**
-
-1. **Main Server** (`cmd/dashboard/main.go`)
- - Set up HTTP server with chi/gorilla router
- - Configure static file serving (`/static/*`)
- - Configure template rendering
- - Add graceful shutdown
- - Start server on port from env (default 8080)
-
-2. **Dashboard Handler** (`internal/handlers/dashboard.go`)
- - Implement `GET /` - main dashboard view
- - Aggregate data from all sources in parallel (goroutines)
- - Check cache freshness (5min TTL)
- - Refresh stale data from APIs
- - Render dashboard template with aggregated data
-
-3. **API Endpoints** (`internal/handlers/api.go`)
- - `GET /api/tasks` - return tasks as JSON
- - `GET /api/notes` - return notes as JSON
- - `GET /api/meals` - return meals as JSON
- - `POST /api/refresh` - force refresh all data
- - Add CORS headers if needed
-
-#### Step 5: Frontend Development
-**Priority: High**
-
-1. **Base Template** (`web/templates/base.html`)
- - HTML5 boilerplate
- - Include Tailwind CSS (CDN or built)
- - Include HTMX (if chosen) or vanilla JS
- - Mobile viewport meta tag
- - Basic responsive grid layout
-
-2. **Dashboard View** (`web/templates/index.html`)
- - Header with refresh button
- - Quick capture section (placeholder for Phase 2)
- - Tasks section (today + week view)
- - Meals section (upcoming 7 days)
- - Notes section (recent 10 notes)
- - Loading spinners
- - Error message display
-
-3. **Styling** (`web/static/css/styles.css`)
- - Mobile-first responsive design
- - Card-based layout for each section
- - Dark mode support (optional)
- - Loading states
- - Hover effects and transitions
-
-4. **Interactivity** (`web/static/js/app.js`)
- - Auto-refresh every 5 minutes
- - Manual refresh button handler
- - Show/hide loading states
- - Error handling UI
- - Task filtering (all/today/week)
-
-#### Step 6: Testing & Refinement
-**Priority: Medium**
-
-- Test with real API keys for all services
-- Test on mobile browser (Chrome/Safari)
-- Verify responsive design breakpoints
-- Test error scenarios (API down, invalid keys)
-- Verify cache TTL behavior
-- Test concurrent API calls
-
-### Phase 2: Write Operations
-**Goal:** Enable creating and updating data across services
-
-#### Step 1: Todoist Write Operations
-**Priority: High**
-
-1. **API Methods** (`internal/api/todoist.go`)
- - `CreateTask(content, projectID, dueDate, priority)` - POST /tasks
- - `CompleteTask(taskID)` - POST /tasks/{id}/close
- - `UpdateTask(taskID, updates)` - POST /tasks/{id}
-
-2. **HTTP Handlers** (`internal/handlers/tasks.go`)
- - `POST /api/tasks` - create new task
- - `POST /api/tasks/:id/complete` - mark task complete
- - `PUT /api/tasks/:id` - update task
- - Return JSON responses
- - Invalidate cache after mutations
-
-3. **Frontend Updates**
- - Add task creation form in quick capture section
- - Add checkbox click handler for task completion
- - Add inline edit for task content
- - Show success/error notifications
- - Update UI optimistically with rollback on error
-
-#### Step 2: Obsidian Write Operations
-**Priority: Medium**
-
-1. **API Methods** (`internal/api/obsidian.go`)
- - `CreateNote(title, content, tags)` - write to vault directory
- - Generate filename from title (slugify)
- - Add YAML frontmatter with metadata
- - Handle file write errors
-
-2. **HTTP Handlers** (`internal/handlers/notes.go`)
- - `POST /api/notes` - create new note
- - Accept markdown content
- - Return created note details
-
-3. **Frontend Updates**
- - Add note creation form
- - Markdown preview (optional)
- - Tag input field
- - Success notification with link to note
-
-#### Step 3: PlanToEat Write Operations (Optional)
-**Priority: Low**
-
-1. **API Methods** (`internal/api/plantoeat.go`)
- - `AddMealToPlanner(recipeID, date, mealType)` - POST to planner
- - `GetRecipes()` - search recipes for selection
-
-2. **HTTP Handlers** (`internal/handlers/meals.go`)
- - `POST /api/meals` - add meal to planner
- - `GET /api/recipes/search` - search recipes
-
-3. **Frontend Updates**
- - Add meal planning interface
- - Recipe search/selection
- - Date and meal type picker
-
-### Phase 3: Enhancements
-**Goal:** Advanced features and polish
-
-#### Planned Features
-1. **Unified Search**
- - Search across tasks, notes, and meals
- - Full-text search using SQLite FTS5
- - Search results page with highlighting
-
-2. **Quick Capture**
- - Single input that intelligently routes to correct service
- - Parse natural language (e.g., "task: buy milk" vs "note: meeting notes")
- - Keyboard shortcut support
-
-3. **Daily Digest**
- - `/digest` route showing day-at-a-glance
- - Upcoming tasks, today's meals, pinned notes
- - Export as markdown or email
-
-4. **PWA Configuration**
- - Add `manifest.json` for installability
- - Service worker for offline caching
- - App icon and splash screen
-
-5. **Data Visualization**
- - Task completion trends
- - Meal planning calendar view
- - Note creation frequency
-
-## Technical Decisions
-
-### Resolved
-- **Routing:** Use `chi` router (lightweight, stdlib-like)
-- **Database:** SQLite with manual migrations
-- **Frontend:** HTMX + Tailwind CSS (CDN) for rapid development
-- **Obsidian Scanning:** Flat directory scan with mtime sorting (avoid deep recursion)
-
-### To Decide During Implementation
-- [ ] Full Tailwind build vs CDN (start with CDN, optimize later)
-- [ ] Trello integration in Phase 1 or defer to Phase 3
-- [ ] Dark mode toggle persistence (localStorage vs cookie)
-- [ ] Cache invalidation strategy (TTL vs event-based)
-
-## File Structure
-```
-task-dashboard/
-├── cmd/
-│ └── dashboard/
-│ └── main.go
-├── internal/
-│ ├── api/
-│ │ ├── todoist.go
-│ │ ├── plantoeat.go
-│ │ ├── trello.go
-│ │ └── obsidian.go
-│ ├── config/
-│ │ └── config.go
-│ ├── handlers/
-│ │ ├── dashboard.go
-│ │ ├── tasks.go
-│ │ ├── notes.go
-│ │ └── meals.go
-│ ├── models/
-│ │ └── types.go
-│ └── store/
-│ └── sqlite.go
-├── web/
-│ ├── static/
-│ │ ├── css/
-│ │ │ └── styles.css
-│ │ └── js/
-│ │ └── app.js
-│ └── templates/
-│ ├── base.html
-│ ├── index.html
-│ ├── tasks.html
-│ └── notes.html
-├── migrations/
-│ ├── 001_initial_schema.sql
-│ └── 002_add_cache_metadata.sql
-├── .env.example
-├── .gitignore
-├── go.mod
-├── go.sum
-├── README.md
-├── spec.md
-└── implementation-plan.md
-```
-
-## Environment Variables (.env.example)
-```bash
-# API Keys
-TODOIST_API_KEY=your_todoist_token
-PLANTOEAT_API_KEY=your_plantoeat_key
-TRELLO_API_KEY=your_trello_api_key
-TRELLO_TOKEN=your_trello_token
-
-# Paths
-OBSIDIAN_VAULT_PATH=/path/to/your/obsidian/vault
-DATABASE_PATH=./dashboard.db
-
-# Server
-PORT=8080
-CACHE_TTL_MINUTES=5
-```
-
-## Development Workflow
-
-### Day 1-2: Foundation
-1. Set up project structure
-2. Implement SQLite database layer
-3. Create configuration loader
-4. Define all data models
-
-### Day 3-4: API Integrations
-1. Implement Todoist client (highest priority)
-2. Implement Obsidian file reader
-3. Implement PlanToEat client
-4. Test all API clients independently
-
-### Day 5-6: Backend Server
-1. Set up HTTP server with routing
-2. Implement dashboard handler with caching
-3. Create API endpoints
-4. Test with Postman/curl
-
-### Day 7-8: Frontend
-1. Build HTML templates
-2. Add Tailwind styling
-3. Implement JavaScript interactivity
-4. Test responsive design
-
-### Day 9-10: Phase 1 Polish
-1. Error handling improvements
-2. Loading states and UX polish
-3. Mobile testing
-4. Documentation
-
-### Week 2+: Phase 2 & 3
-- Implement write operations
-- Add enhancements based on usage
-- Deploy to Docker/Fly.io
-
-## Testing Strategy
-
-### Unit Tests
-- API client functions
-- Data model parsing
-- Cache logic
-
-### Integration Tests
-- Full API roundtrips (with mocked responses)
-- Database operations
-- Handler responses
-
-### Manual Testing
-- Real API integration with personal accounts
-- Mobile browser testing (Chrome DevTools + real device)
-- Error scenarios (network failures, invalid keys)
-
-## Success Metrics
-
-### Phase 1 Complete When:
-- [ ] Dashboard shows Todoist tasks (today + week)
-- [ ] Dashboard shows 10 most recent Obsidian notes
-- [ ] Dashboard shows 7 days of PlanToEat meals
-- [ ] Responsive on mobile (320px-1920px)
-- [ ] Auto-refresh works (5min)
-- [ ] Manual refresh button works
-- [ ] Runs with `go run cmd/dashboard/main.go`
-- [ ] Can deploy with Docker
-
-### Phase 2 Complete When:
-- [ ] Can create Todoist task from dashboard
-- [ ] Can mark Todoist task complete
-- [ ] Can create quick note to Obsidian
-- [ ] All mutations update cache immediately
-
-## Risk Mitigation
-
-### Potential Issues
-1. **API Rate Limits:** Use aggressive caching, respect rate limits
-2. **Large Obsidian Vaults:** Limit to 20 most recent files
-3. **Slow API Responses:** Implement timeouts, show partial data
-4. **API Authentication Changes:** Version lock API docs, monitor changelogs
-
-### Contingency Plans
-- If PlanToEat API is difficult, defer to Phase 3
-- If Trello adds complexity, make fully optional
-- If HTMX is limiting, switch to vanilla JS incrementally
-
-## Next Steps
-1. Run through "Getting Started Checklist" from spec
-2. Begin with Step 1: Project Setup
-3. Implement features sequentially following phase order
-4. Test continuously with real data
-5. Iterate based on daily usage feedback
diff --git a/spec.md b/spec.md
deleted file mode 100644
index a62909b..0000000
--- a/spec.md
+++ /dev/null
@@ -1,383 +0,0 @@
-# Personal Consolidation Dashboard - Project Spec
-
-## Overview
-Build a unified web dashboard that aggregates tasks, notes, and meal planning from multiple services into a single interface. Go backend + simple frontend with mobile-responsive design.
-
-## Core Requirements
-
-### Phase 1: Read-Only Aggregation (MVP)
-Display data from:
-1. **Todoist** - Tasks and projects
-2. **Obsidian** - Recent notes (file system access)
-3. **PlanToEat** - Upcoming meals/recipes
-4. **Trello** (optional phase 1) - Boards and cards
-
-### Phase 2: Write Operations
-- Create/update/complete tasks in Todoist
-- Quick capture notes (save to Obsidian vault)
-- Add meals to PlanToEat planner
-
-### Phase 3: Enhancements
-- Search across all sources
-- Unified quick capture
-- Daily digest view
-- Mobile PWA configuration
-
-## Technical Stack
-
-### Backend
-- **Language:** Go 1.21+
-- **Framework:** Standard library + chi/gorilla for routing (your choice)
-- **Storage:** SQLite for caching API responses, user preferences
-- **APIs:**
- - Todoist REST API v2: https://developer.todoist.com/rest/v2
- - PlanToEat API: https://www.plantoeat.com/developers
- - Trello REST API: https://developer.atlassian.com/cloud/trello/rest
- - Obsidian: Direct filesystem access to vault directory
-
-### Frontend
-- **Framework:** HTMX + Tailwind CSS (or plain HTML/CSS/vanilla JS - your preference)
-- **Mobile:** Responsive design, PWA manifest later
-
-### Deployment
-- **Local first:** Run on localhost:8080
-- **Future:** Docker container, deploy to Fly.io/Railway
-- **Data:** SQLite file in project directory, environment variables for API keys
-
-## Data Models
-
-### Task (from Todoist)
-```go
-type Task struct {
- ID string
- Content string
- Description string
- ProjectID string
- ProjectName string
- DueDate *time.Time
- Priority int
- Completed bool
- Labels []string
- URL string // Link back to Todoist
-}
-```
-
-### Note (from Obsidian)
-```go
-type Note struct {
- Filename string
- Title string
- Content string // First 200 chars or full content
- Modified time.Time
- Path string
- Tags []string
-}
-```
-
-### Meal (from PlanToEat)
-```go
-type Meal struct {
- ID string
- RecipeName string
- Date time.Time
- MealType string // breakfast, lunch, dinner
- RecipeURL string
-}
-```
-
-### Board/Card (from Trello)
-```go
-type Board struct {
- ID string
- Name string
- Cards []Card
-}
-
-type Card struct {
- ID string
- Name string
- ListID string
- ListName string
- DueDate *time.Time
- URL string
-}
-```
-
-## API Integration Details
-
-### Todoist
-- **Auth:** Bearer token in Authorization header
-- **Endpoint:** https://api.todoist.com/rest/v2/tasks
-- **Rate limit:** Not publicly documented, use reasonable polling (5min intervals)
-- **Key operations:**
- - GET /tasks - Fetch all active tasks
- - GET /projects - Fetch project list
- - POST /tasks - Create new task
- - POST /tasks/{id}/close - Complete task
-
-### PlanToEat
-- **Auth:** API key in query parameter or header (check docs)
-- **Endpoint:** https://www.plantoeat.com/api/v2
-- **Key operations:**
- - GET /planner_items - Fetch upcoming meals
- - GET /recipes - Fetch recipe details
-
-### Trello
-- **Auth:** API Key + Token in query parameters
-- **Endpoint:** https://api.trello.com/1
-- **Key operations:**
- - GET /members/me/boards - Fetch user's boards
- - GET /boards/{id}/cards - Fetch cards on board
-
-### Obsidian
-- **Access:** Direct filesystem reads from vault directory
-- **Location:** Environment variable `OBSIDIAN_VAULT_PATH`
-- **Parse:** Markdown files, extract YAML frontmatter for metadata
-- **Watch:** Optional - use fsnotify for real-time updates
-
-## Architecture
-
-### Backend Structure
-```
-cmd/
- dashboard/
- main.go # Entry point, server setup
-internal/
- api/
- todoist.go # Todoist API client
- plantoeat.go # PlanToEat API client
- trello.go # Trello API client
- obsidian.go # Filesystem reader
- handlers/
- tasks.go # HTTP handlers for task views
- notes.go # HTTP handlers for notes
- meals.go # HTTP handlers for meals
- models/
- types.go # Shared data structures
- store/
- sqlite.go # Database operations
-web/
- static/
- css/
- styles.css # Tailwind or custom styles
- js/
- app.js # Optional vanilla JS
- templates/
- index.html # Main dashboard
- tasks.html # Task list partial
- notes.html # Notes list partial
-```
-
-### Configuration
-Environment variables (.env file):
-```bash
-TODOIST_API_KEY=your_token
-PLANTOEAT_API_KEY=your_key
-TRELLO_API_KEY=your_key
-TRELLO_TOKEN=your_token
-OBSIDIAN_VAULT_PATH=/path/to/vault
-DATABASE_PATH=./dashboard.db
-PORT=8080
-```
-
-## UI Requirements
-
-### Dashboard Layout
-```
-+----------------------------------+
-| [Quick Capture] |
-+----------------------------------+
-| Today's Tasks | Meals |
-| □ Task 1 | 🍳 Breakfast|
-| □ Task 2 | 🍕 Lunch |
-| ☑ Task 3 | 🍝 Dinner |
-+----------------------------------+
-| Recent Notes |
-| • Note 1 (2h ago) |
-| • Note 2 (1d ago) |
-+----------------------------------+
-| Trello Boards (optional) |
-+----------------------------------+
-```
-
-### Features
-- **Mobile-responsive** - Stack vertically on small screens
-- **Dark mode support** (optional but nice)
-- **Refresh button** - Manual data sync
-- **Auto-refresh** - Every 5 minutes
-- **Loading states** - Spinners during API calls
-- **Error handling** - Show API failures gracefully
-
-## Success Criteria
-
-### Phase 1 Complete When:
-- [ ] Dashboard shows Todoist tasks for today/week
-- [ ] Dashboard shows 5-10 most recent Obsidian notes
-- [ ] Dashboard shows upcoming meals from PlanToEat
-- [ ] Responsive design works on mobile browser
-- [ ] Runs locally with `go run cmd/dashboard/main.go`
-
-### Phase 2 Complete When:
-- [ ] Can create new Todoist task from dashboard
-- [ ] Can mark Todoist task complete
-- [ ] Can create quick note (saves to Obsidian vault)
-
-## Non-Requirements (Out of Scope)
-- User authentication (single user only)
-- Real-time sync (polling is fine)
-- Offline support
-- Data analytics/insights
-- Calendar integration
-- Migration tools from Google Keep
-- Bi-directional Trello sync
-
-## Development Notes
-
-### API Key Setup
-User must obtain:
-1. Todoist: Settings → Integrations → API token
-2. PlanToEat: Account settings → API access
-3. Trello: https://trello.com/app-key → Generate token
-4. Obsidian: Just need filesystem path
-
-### Testing Strategy
-- Start with Todoist integration only (simplest API)
-- Mock API responses for initial UI development
-- Use real APIs once structure is solid
-- Test on mobile browser early
-
-### Performance
-- Cache API responses in SQLite (5min TTL)
-- Obsidian: Only scan vault on startup + when requested
-- Parallel API calls using goroutines
-- Limit Obsidian file reads (e.g., last 20 modified files)
-
-## Questions to Resolve During Development
-1. HTMX vs vanilla JS for interactivity?
-2. Full Tailwind build or CDN version?
-3. SQLite migrations approach (golang-migrate vs manual)?
-4. Obsidian vault - recursive scan or flat directory?
-5. Trello - all boards or filter to specific ones?
-
-## Getting Started Checklist
-- [ ] Initialize Go module
-- [ ] Set up project structure
-- [ ] Create .env.example with required variables
-- [ ] Implement Todoist API client first (test with real token)
-- [ ] Build basic HTTP server with single endpoint
-- [ ] Create simple HTML template
-- [ ] Add SQLite caching layer
-- [ ] Iterate on remaining integrations
-
-## Reference Documentation
-- Todoist API: https://developer.todoist.com/rest/v2
-- PlanToEat API: https://www.plantoeat.com/developers
-- Trello API: https://developer.atlassian.com/cloud/trello/rest/api-group-actions
-- HTMX: https://htmx.org/docs/
-
-Endpoint design guidance for Claude Code:
-Security
-
-Token auth in header: Authorization: Bearer <token> (not query param - avoids URL logging)
-Single read-only token - Generate once, store in your env vars and tell me separately
-Rate limiting: 100 req/hour per token (I rarely need more than 1-2 calls per conversation)
-No CORS needed - Server-to-server only
-HTTPS only when deployed (Let's Encrypt via Caddy/Traefik)
-
-Response format
-json{
-"generated_at": "2026-01-09T15:30:00Z",
-"tasks": {
-"today": [
-{
-"id": "task_123",
-"content": "Review PRs",
-"priority": 4,
-"due": "2026-01-09T17:00:00Z",
-"project": "Work",
-"completed": false
-}
-],
-"overdue": [...],
-"next_7_days": [...]
-},
-"meals": {
-"today": {
-"breakfast": "Oatmeal with protein powder",
-"lunch": "Chicken salad",
-"dinner": "Salmon with veggies"
-},
-"next_7_days": [...]
-},
-"notes": {
-"recent": [
-{
-"title": "Sprint planning notes",
-"modified": "2026-01-09T10:15:00Z",
-"preview": "First 150 chars...",
-"path": "work/sprint-planning.md"
-}
-]
-},
-"trello_boards": [...] // optional
-}
-Efficiency
-
-Cache responses: 5min TTL in-memory, return cached JSON if token valid
-Limit data volume:
-
-Tasks: Today + overdue + next 7 days only
-Notes: 10 most recent only
-Meals: Today + next 7 days
-Total response < 100KB
-
-
-Selective fields: Don't include full note content, just previews
-Single endpoint: /api/claude/snapshot (not multiple endpoints)
-
-Error responses
-json{
-"error": "unauthorized",
-"message": "Invalid or missing token"
-}
-```
-
-Standard HTTP codes:
-- 200: Success
-- 401: Invalid/missing token
-- 429: Rate limit exceeded
-- 500: Server error (with safe message, no stack traces)
-
-### Implementation hints for Claude Code:
-```
-Create GET /api/claude/snapshot endpoint:
-- Require Authorization: Bearer <token> header
-- Return cached JSON (5min TTL) with current state
-- Include: today's tasks, overdue tasks, next 7 days tasks, today's meals,
- next 7 days meals, 10 most recent notes
-- Limit each note preview to 150 chars
-- Total response should be < 100KB
-- Use 401 for auth failures, 429 for rate limits
-- Cache API responses to avoid hammering upstream services
-```
-
-### What I'll do:
-When you give me the URL + token:
-```
-My dashboard: https://dashboard.yourdomain.com/api/claude/snapshot
-Token: <you'll share separately>
-```
-
-I'll call:
-```
-web_fetch(
-url="https://dashboard.yourdomain.com/api/claude/snapshot",
-headers={"Authorization": "Bearer <token>"}
-)
-Then parse JSON and use context naturally in our conversations.
-Optional: Webhook for updates
-If you want proactive notifications (e.g., "Pete, you have 3 overdue tasks"), add:
-
-POST endpoint to receive webhook URL from me (not implemented yet on my side)
-Your dashboard posts to that URL when important state changes
-Skip this for now - manual fetch is simpler