From d799d4d04cc18654de5864a458668ff073e26284 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Tue, 20 Jan 2026 15:25:00 -1000 Subject: Add task tracking issues Document completed and planned tasks: - Obsidian removal (completed) - Authentication implementation (completed) - VPS deployment preparation (planned) - API sync optimization research Co-Authored-By: Claude Opus 4.5 --- issues/phase4_step2_research_sync.md | 124 ++++++++++++++++++++++++++++++++++ issues/task_001_remove_obsidian.md | 37 ++++++++++ issues/task_002_add_authentication.md | 36 ++++++++++ issues/task_003_deployment_prep.md | 58 ++++++++++++++++ 4 files changed, 255 insertions(+) create mode 100644 issues/phase4_step2_research_sync.md create mode 100644 issues/task_001_remove_obsidian.md create mode 100644 issues/task_002_add_authentication.md create mode 100644 issues/task_003_deployment_prep.md (limited to 'issues') 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. -- cgit v1.2.3