summaryrefslogtreecommitdiff
path: root/issues
diff options
context:
space:
mode:
Diffstat (limited to 'issues')
-rw-r--r--issues/phase4_step2_research_sync.md124
-rw-r--r--issues/task_001_remove_obsidian.md37
-rw-r--r--issues/task_002_add_authentication.md36
-rw-r--r--issues/task_003_deployment_prep.md58
4 files changed, 255 insertions, 0 deletions
diff --git a/issues/phase4_step2_research_sync.md b/issues/phase4_step2_research_sync.md
new file mode 100644
index 0000000..d690e6f
--- /dev/null
+++ b/issues/phase4_step2_research_sync.md
@@ -0,0 +1,124 @@
+# Phase 4 Step 2: Research Efficient Sync
+
+## Research Findings
+
+### Todoist Sync API
+
+**Test Results (from `research_test.go`):**
+- Full sync response: **17,502 bytes**
+- Incremental sync response: **179 bytes** (99% reduction!)
+- `sync_token` successfully enables incremental updates
+
+**Response Structure:**
+```json
+{
+ "sync_token": "...",
+ "full_sync": true/false,
+ "items": [...] // tasks
+}
+```
+
+**Item (Task) Fields Available:**
+- `id`, `content`, `description`, `project_id`
+- `checked` (completion status)
+- `is_deleted` (for handling deletions)
+- `updated_at` (for tracking changes)
+- `due` (with `date`, `is_recurring`, `string`)
+
+**Implementation Approach:**
+1. Store `sync_token` in database (new table or cache_metadata)
+2. On refresh, call Sync API with stored token
+3. Apply incremental changes to local database:
+ - Update modified tasks
+ - Delete tasks where `is_deleted=true`
+ - Mark tasks where `checked=true` as completed
+4. If `full_sync=true` in response, clear and rebuild local state
+
+### Trello API Optimization
+
+**Test Results:**
+- Full boards response: **48,228 bytes** (all fields)
+- Limited fields (id,name): **462 bytes** (99% reduction!)
+- Single board with embedded cards/lists: **10,452 bytes**
+
+**Optimization Strategies:**
+
+1. **Field Filtering** (immediate win):
+ ```
+ /boards?fields=id,name,dateLastActivity
+ /boards/{id}/cards?fields=id,name,idList,due,url
+ ```
+
+2. **Batch Requests** (reduce API calls):
+ ```
+ /boards/{id}?cards=visible&card_fields=id,name,idList,due,url&lists=open&list_fields=id,name
+ ```
+ - Fetches board + cards + lists in single request
+
+3. **`dateLastActivity` Caching**:
+ - Store `dateLastActivity` for each board
+ - On refresh, fetch boards with minimal fields
+ - Only fetch cards for boards where `dateLastActivity` changed
+ - Note: `since` parameter exists but returns full data (not truly incremental)
+
+### Architecture Implications
+
+**Current Architecture:**
+- Cache-aside pattern: Check cache -> Miss -> Fetch API -> Store in cache
+- Problem: Full data fetch on every cache miss
+
+**Proposed Architecture:**
+- **Sync Engine Pattern**:
+ - SQLite is the source of truth
+ - Sync process updates SQLite incrementally
+ - Read operations always hit SQLite (fast)
+
+**Migration Path:**
+1. Phase A: Add field filtering to Trello (immediate benefit, no architecture change)
+2. Phase B: Implement Todoist Sync API with sync_token storage
+3. Phase C: Add dateLastActivity tracking for Trello boards
+
+## Implementation Plan
+
+### Phase A: Trello Field Optimization (Low effort, High impact)
+
+1. Update `GetBoards` to use `fields=id,name,dateLastActivity`
+2. Update `GetCards` to use `fields=id,name,idList,due,url,desc`
+3. Consider batch endpoint for single-board-with-cards
+
+### Phase B: Todoist Incremental Sync (Medium effort, High impact)
+
+1. Add `sync_tokens` table:
+ ```sql
+ CREATE TABLE sync_tokens (
+ service TEXT PRIMARY KEY,
+ token TEXT NOT NULL,
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
+ );
+ ```
+
+2. Create `SyncTasks` method in `TodoistClient`:
+ - Accept previous sync_token
+ - Return new sync_token + changed items
+
+3. Create `ApplyTaskChanges` method in `Store`:
+ - Handle updates, deletions, completions
+ - Update sync_token after successful apply
+
+4. Update `fetchTasks` to use sync when token exists
+
+### Phase C: Trello Smart Refresh (Medium effort, Medium impact)
+
+1. Store `dateLastActivity` per board in database
+2. On refresh:
+ - Fetch boards with minimal fields
+ - Compare `dateLastActivity` with stored values
+ - Only fetch cards for changed boards
+
+## Recommendation
+
+**Start with Phase A** - simple field filtering provides immediate 99% reduction in Trello response size with minimal code changes.
+
+**Then Phase B** - Todoist Sync API provides the best efficiency gains (99% reduction) and is well-documented.
+
+**Phase C is optional** - Trello doesn't have true incremental sync, so the benefit is limited to skipping unchanged boards.
diff --git a/issues/task_001_remove_obsidian.md b/issues/task_001_remove_obsidian.md
new file mode 100644
index 0000000..c02a785
--- /dev/null
+++ b/issues/task_001_remove_obsidian.md
@@ -0,0 +1,37 @@
+# Remove Obsidian Functionality (COMPLETED)
+
+**Description:**
+Remove all code related to Obsidian integration to prepare for public server deployment. Obsidian relies on local filesystem access, which is not suitable for a public web server environment.
+
+**Status:**
+✅ COMPLETED
+
+**Changes Made:**
+1. **Core Logic:**
+ * Deleted `internal/api/obsidian.go` and `internal/api/obsidian_test.go`.
+ * Removed `ObsidianAPI` interface from `internal/api/interfaces.go`.
+ * Removed `Note` struct from `internal/models/types.go`.
+ * Removed `SourceObsidian` and `NoteToAtom` from `internal/models/atom.go`.
+
+2. **Configuration:**
+ * Removed `ObsidianVaultPath` and `HasObsidian()` from `internal/config/config.go`.
+ * Removed `OBSIDIAN_VAULT_PATH` from `.env.example`.
+
+3. **Handlers:**
+ * Removed `obsidianClient` field from `Handler` struct in `internal/handlers/handlers.go`.
+ * Updated `New` function signature.
+ * Removed `HandleNotesTab` and `fetchNotes` methods.
+ * Removed `HandleNotes` from `internal/handlers/tabs.go`.
+ * Removed `obsidian` logic from `aggregateData`.
+
+4. **UI:**
+ * Removed `web/templates/partials/obsidian-notes.html`.
+ * Removed `web/templates/partials/notes-tab.html`.
+ * Removed "Notes" tab button from `web/templates/index.html`.
+ * Removed `obsidian` color from `tailwind.config.js`.
+
+5. **Main Entry Point:**
+ * Updated `cmd/dashboard/main.go` (Handled by Implementor).
+
+6. **Tests:**
+ * Updated `test/acceptance_test.go` and `internal/handlers/handlers_test.go`.
diff --git a/issues/task_002_add_authentication.md b/issues/task_002_add_authentication.md
new file mode 100644
index 0000000..018fff0
--- /dev/null
+++ b/issues/task_002_add_authentication.md
@@ -0,0 +1,36 @@
+# Task: Add Authentication
+
+## Goal
+Implement session-based authentication to secure the application for public deployment.
+
+## Plan
+
+1. **Dependencies:**
+ * Add `github.com/alexedwards/scs/v2` (Session management).
+ * Add `github.com/alexedwards/scs/sqlite3store` (SQLite store for sessions).
+ * Add `golang.org/x/crypto/bcrypt` (Password hashing).
+
+2. **Database Schema:**
+ * Create migration `migrations/003_add_auth.sql`.
+ * Create `users` table (`id`, `username`, `password_hash`).
+ * Create `sessions` table (required by `scs` SQLite store).
+
+3. **Core Logic (`internal/auth`):**
+ * Create `AuthService` to handle login, logout, and password verification.
+ * Implement `User` model.
+
+4. **Configuration:**
+ * Update `Config` to include `SessionSecret` (for cookie encryption, if needed, though `scs` handles this well).
+
+5. **Handlers & Middleware:**
+ * Initialize `SessionManager` in `main.go`.
+ * Create `LoginHandler` (GET/POST).
+ * Create `LogoutHandler` (POST).
+ * Create `AuthMiddleware` to protect routes.
+
+6. **UI:**
+ * Create `web/templates/login.html`.
+ * Update `web/templates/base.html` (or similar) to show Logout button when logged in.
+
+7. **Seed Data:**
+ * Create a CLI command or startup check to ensure a default admin user exists (or provide instructions to create one).
diff --git a/issues/task_003_deployment_prep.md b/issues/task_003_deployment_prep.md
new file mode 100644
index 0000000..a05c2eb
--- /dev/null
+++ b/issues/task_003_deployment_prep.md
@@ -0,0 +1,58 @@
+# Task 003: VPS Deployment Preparation (Apache + Systemd)
+
+Prepare the application for deployment on a VPS using Apache2 as a reverse proxy and Systemd for process management.
+
+## Target Environment
+- **OS:** Linux (VPS)
+- **Web Server:** Apache2
+- **Process Manager:** Systemd
+- **Directory Structure:**
+ - Root: `/site/{fqdn}/`
+ - Binary: `/site/{fqdn}/app`
+ - Data: `/site/{fqdn}/data/` (Database location)
+ - Webroot: `/site/{fqdn}/public/` (Static assets)
+
+## Plan
+
+### 1. Configuration Updates
+- Ensure the application can accept configuration via Environment Variables for:
+ - `PORT` (Default: 8080)
+ - `DB_PATH` (Default: `./task.db`, Target: `/site/{fqdn}/data/dashboard.db`)
+ - `SESSION_KEY` (Secret)
+ - `STATIC_DIR` (Optional: if we want to point to `public` explicitly)
+
+### 2. Create Deployment Artifacts
+Create a `deployment/` directory containing:
+
+#### A. Systemd Unit File (`deployment/task-dashboard.service`)
+- **Description:** Manages the Go application process.
+- **Key Settings:**
+ - `ExecStart=/site/{fqdn}/app`
+ - `WorkingDirectory=/site/{fqdn}/`
+ - `User=www-data` (or specific user)
+ - `Restart=always`
+ - `EnvironmentFile=/site/{fqdn}/.env` (or inline env vars)
+
+#### B. Apache VHost Configuration (`deployment/apache.conf`)
+- **Description:** Reverse proxy configuration.
+- **Key Settings:**
+ - Based on provided template.
+ - `DocumentRoot /site/{fqdn}/public`
+ - `ProxyPass / http://localhost:8080/`
+ - `ProxyPassReverse / http://localhost:8080/`
+ - Serve static assets directly via Apache for performance (optional but recommended).
+
+### 3. Documentation
+- Create `docs/deployment.md` with instructions:
+ 1. **Build:** `go build -o app cmd/dashboard/main.go`
+ 2. **Setup:**
+ - `mkdir -p /site/{fqdn}/{data,public}`
+ - Copy `app` to `/site/{fqdn}/`
+ - Copy `web/static` content to `/site/{fqdn}/public/`
+ - Copy `web/templates` to `/site/{fqdn}/templates` (or ensure app can find them)
+ 3. **Service:** Install and enable systemd service.
+ 4. **Apache:** Enable site and modules (`proxy`, `proxy_http`).
+
+## Considerations
+- **Static Files:** We should decide if Apache serves `/static` directly from `/site/{fqdn}/public` or if the Go app handles it. Serving via Apache is preferred for performance.
+- **Templates:** The Go app needs access to HTML templates. We need to ensure the `WorkingDirectory` allows relative path resolution to `web/templates` or configure an absolute path.