diff --git a/.planning/MILESTONES.md b/.planning/MILESTONES.md new file mode 100644 index 0000000..aa083af --- /dev/null +++ b/.planning/MILESTONES.md @@ -0,0 +1,31 @@ +# Project Milestones: TaskPlanner + +## v1.0 MVP (Shipped: 2026-02-01) + +**Delivered:** Personal task and notes management with image attachments, accessible from any device via Docker deployment. + +**Phases completed:** 1-6 (18 plans total) + +**Key accomplishments:** + +- Complete entry management with tasks/thoughts, quick capture, and auto-save +- Image attachments with mobile camera support and thumbnail gallery +- Tag-based organization with autocomplete and case-insensitive matching +- Full-text search with highlighting and date/type filtering +- Docker deployment with persistent volumes and health monitoring +- Mobile-friendly UI with swipe gestures and touch targets + +**Stats:** + +- 131 files created/modified +- 3,057 lines of TypeScript/Svelte +- 6 phases, 18 plans, 41 tasks +- 3 days from project start to ship (2026-01-29 → 2026-02-01) + +**Git range:** `1681a6a` → `8793e15` + +**What's next:** Deploy to production, gather real-world usage feedback + +--- + +*Milestone history maintained in reverse chronological order* diff --git a/.planning/PROJECT.md b/.planning/PROJECT.md index c3aba7d..b7f8fbf 100644 --- a/.planning/PROJECT.md +++ b/.planning/PROJECT.md @@ -10,19 +10,19 @@ Capture and find anything from any device — especially laptop. If cross-device ## Requirements -### Validated +### Validated (v1.0 - Shipped 2026-02-01) -(None yet — ship to validate) +- [x] Capture tasks and thoughts from any device via web browser +- [x] Distinguish between tasks (actionable) and thoughts (reference) +- [x] Attach images to entries (from file upload or camera) +- [x] Organize entries with tags (emergent, not predefined categories) +- [x] Find entries by tag, time, or search +- [x] Add notes to existing entries +- [x] Digitize paper notes by photographing and tagging them ### Active -- [ ] Capture tasks and thoughts from any device via web browser -- [ ] Distinguish between tasks (actionable) and thoughts (reference) -- [ ] Attach images to entries (from file upload or camera) -- [ ] Organize entries with tags (emergent, not predefined categories) -- [ ] Find entries by tag, time, or search -- [ ] Add notes to existing entries -- [ ] Digitize paper notes by photographing and tagging them +(None — see v2 candidates in `.planning/milestones/v1.0-REQUIREMENTS.md`) ### Out of Scope @@ -59,9 +59,13 @@ This project solves a real problem while serving as a vehicle for learning new a | Decision | Rationale | Outcome | |----------|-----------|---------| -| Web app over native | Works on all devices including laptop without app stores | — Pending | -| Tags over folders | Flexible organization, items can have multiple tags | — Pending | -| Images from day one | Core need is digitizing paper notes | — Pending | +| Web app over native | Works on all devices including laptop without app stores | ✓ Validated | +| Tags over folders | Flexible organization, items can have multiple tags | ✓ Validated | +| Images from day one | Core need is digitizing paper notes | ✓ Validated | +| Tailwind CSS v4 | Modern utility-first CSS with Vite plugin | ✓ Validated | +| SQLite with WAL mode | Simple, fast, concurrent reads for single-user | ✓ Validated | +| Repository pattern | Clean data access, testable, singleton instances | ✓ Validated | +| adapter-node for Docker | Server-side rendering with env prefix support | ✓ Validated | --- -*Last updated: 2026-01-29 after initialization* +*Last updated: 2026-02-01 after v1.0 milestone completion* diff --git a/.planning/STATE.md b/.planning/STATE.md index 58c14a8..feef14b 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,28 +2,30 @@ ## Project Reference -See: .planning/PROJECT.md (updated 2026-01-29) +See: .planning/PROJECT.md (updated 2026-02-01) **Core value:** Capture and find anything from any device — especially laptop. If cross-device capture with images doesn't work, nothing else matters. -**Current focus:** Phase 6 - Deployment (COMPLETE) +**Current focus:** Post-v1.0 — awaiting next milestone ## Current Position -Phase: 6 of 6 (Deployment) -Plan: 2 of 2 in current phase -Status: PROJECT COMPLETE -Last activity: 2026-02-01 — Completed 06-02-PLAN.md +Phase: N/A (between milestones) +Plan: N/A +Status: MILESTONE v1.0 COMPLETE +Last activity: 2026-02-01 — Completed milestone v1.0 -Progress: [██████████] 100% +Progress: Awaiting `/gsd:new-milestone` for v2 planning ## Performance Metrics -**Velocity:** +**v1.0 Summary:** - Total plans completed: 18 - Average duration: 3.3 min - Total execution time: 60 min +- Phases: 6 +- Requirements satisfied: 31/31 -**By Phase:** +**By Phase (v1.0):** | Phase | Plans | Total | Avg/Plan | |-------|-------|-------|----------| @@ -34,85 +36,28 @@ Progress: [██████████] 100% | 05-search | 3 | 7 min | 2.3 min | | 06-deployment | 2 | 4 min | 2 min | -**Recent Trend:** -- Last 5 plans: 05-01 (2 min), 05-02 (1 min), 05-03 (4 min), 06-01 (2 min), 06-02 (2 min) -- Trend: Stable - -*Updated after each plan completion* - ## Accumulated Context ### Decisions -Decisions are logged in PROJECT.md Key Decisions table. -Recent decisions affecting current work: +Key decisions from v1.0 are preserved in PROJECT.md. -- Tailwind CSS v4 with @tailwindcss/vite plugin (01-01) -- Unified entries table with type discriminator (01-01) -- SQLite database at ./data/taskplaner.db (01-01) -- WAL mode for concurrent reads (01-01) -- Repository pattern with singleton instance for data access (01-02) -- Server hooks verify database on first request (01-02) -- getOrdered method with showCompleted filter and type/createdAt ordering (02-01) -- Form action validation with fail() pattern for error handling (02-01) -- svelte-persisted-store for localStorage persistence (02-02) -- Type indicator: checkbox for tasks, purple T badge for thoughts (02-02) -- Debounced auto-save via fetch to form actions (02-03) -- URL params synced with localStorage for showCompleted filter (02-03) -- Native touch handlers for swipe-to-delete gesture (02-04) -- invalidateAll() for seamless list updates after mutations (02-04) -- Thumbnails always JPEG regardless of original format (03-01) -- EXIF rotation via sharp.rotate() before resize (03-01) -- Immutable cache headers for images (03-01) -- Fetch to form action for programmatic upload control (03-02) -- Optimistic preview using URL.createObjectURL (03-02) -- Create entry first, then upload image with entryId (03-02) -- JPEG at 0.9 quality for camera captures (03-03) -- Default back camera for mobile paper note photos (03-03) -- Stop camera stream after capture to save battery (03-03) -- Horizontal scroll gallery with 80x80 thumbnails (03-04) -- File input with capture="environment" for mobile camera (03-04) -- Edit mode toggle to reveal delete buttons (03-04) -- Fetch/invalidateAll pattern for pin toggle actions (04-02) -- Due date stored as ISO string from HTML5 date input (04-02) -- Pinned section uses uppercase label for visual distinction (04-02) -- Tags stored with original case but matched case-insensitively (04-01) -- Entry tags replaced atomically via delete-then-insert (04-01) -- lower() helper for case-insensitive SQL queries (04-01) -- Svelecte onChange prop for Svelte 5 event handling (04-03) -- Tags saved immediately on change without debounce (04-03) -- Max 3 tags shown on collapsed cards with +N indicator (04-03) -- $bindable value prop for SearchBar (parent owns debounced value) (05-01) -- Native event listener for "/" shortcut to avoid Svelte 5 bug (05-01) -- $effect with setTimeout/clearTimeout for debounce pattern (05-01) -- Case-insensitive matching for text search and tag filtering (05-02) -- AND logic for multiple tag filters (05-02) -- XSS-safe HTML generation: escape first, then modify (05-02) -- Recent searches saved on blur with >= 2 char minimum (05-03) -- Generic filterEntries to preserve full entry type (05-03) -- Flat list during filtering (no pinned/unpinned separation) (05-03) -- TASKPLANER_ prefix for environment variables via adapter-node envPrefix (06-01) -- Multi-stage Docker build for smaller production image (06-01) -- Non-root 'nodejs' user (UID 1001) for container security (06-01) -- Named volume taskplaner_data for persistent data (06-01) -- Health check queries database to verify full stack connectivity (06-02) -- Backup script uses temporary Alpine container to access volume (06-02) -- Environment variables documented with comments explaining each option (06-02) +For v2, new decisions will be logged here as work progresses. ### Pending Todos -None - project complete. +None — ready for next milestone. ### Blockers/Concerns -None - all phases completed successfully. +None. ## Session Continuity Last session: 2026-02-01 -Stopped at: Completed 06-02-PLAN.md (PROJECT COMPLETE) +Stopped at: Completed milestone v1.0 Resume file: None --- *State initialized: 2026-01-29* -*Last updated: 2026-02-01 after 06-02 completion - PROJECT COMPLETE* +*Last updated: 2026-02-01 — Milestone v1.0 archived* diff --git a/.planning/v1-MILESTONE-AUDIT.md b/.planning/milestones/v1.0-AUDIT.md similarity index 100% rename from .planning/v1-MILESTONE-AUDIT.md rename to .planning/milestones/v1.0-AUDIT.md diff --git a/.planning/REQUIREMENTS.md b/.planning/milestones/v1.0-REQUIREMENTS.md similarity index 89% rename from .planning/REQUIREMENTS.md rename to .planning/milestones/v1.0-REQUIREMENTS.md index 5d98747..32a611b 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/milestones/v1.0-REQUIREMENTS.md @@ -1,13 +1,12 @@ -# Requirements: TaskPlanner +# Requirements: TaskPlanner v1.0 **Defined:** 2026-01-29 +**Shipped:** 2026-02-01 **Core Value:** Capture and find anything from any device — especially laptop. If cross-device capture with images doesn't work, nothing else matters. -## v1 Requirements +## v1 Requirements (All Complete) -Requirements for initial release. Each maps to roadmap phases. - -### Core +### Core (6/6) - [x] **CORE-01**: User can create a new entry (task or thought) - [x] **CORE-02**: User can edit an existing entry @@ -16,55 +15,53 @@ Requirements for initial release. Each maps to roadmap phases. - [x] **CORE-05**: User can mark a task as complete - [x] **CORE-06**: User can add notes to an existing entry -### Images +### Images (4/4) - [x] **IMG-01**: User can attach images to an entry via file upload - [x] **IMG-02**: User can attach images via camera capture (mobile) - [x] **IMG-03**: User can view attached images on an entry - [x] **IMG-04**: User can remove an image attachment -### Tags +### Tags (4/4) - [x] **TAG-01**: User can add tags to an entry - [x] **TAG-02**: User can remove tags from an entry - [x] **TAG-03**: User sees autocomplete suggestions from existing tags - [x] **TAG-04**: Tags are case-insensitive ("work" = "Work" = "WORK") -### Organization +### Organization (3/3) - [x] **ORG-01**: User can pin/favorite an entry for quick access - [x] **ORG-02**: User can set a due date on a task - [x] **ORG-03**: Pinned entries appear in a dedicated section -### Search +### Search (4/4) - [x] **SRCH-01**: User can search entries by text (title and content) - [x] **SRCH-02**: User can filter entries by tag - [x] **SRCH-03**: User can filter entries by date range - [x] **SRCH-04**: User can filter to show only tasks or only thoughts -### Capture +### Capture (3/3) - [x] **CAPT-01**: User can quickly capture a new entry with minimal friction - [x] **CAPT-02**: Quick capture defaults to thought (less friction than choosing) - [x] **CAPT-03**: Quick capture is accessible from main view -### UX +### UX (3/3) - [x] **UX-01**: UI works well on mobile devices (touch targets, layout) - [x] **UX-02**: Font sizes are readable for older eyes (configurable or large default) - [x] **UX-03**: UI works in any modern browser (Chrome, Firefox, Safari, Edge) -### Deployment +### Deployment (4/4) - [x] **DEPLOY-01**: App runs in a Docker container - [x] **DEPLOY-02**: Configuration via environment variables - [x] **DEPLOY-03**: Data persists via named Docker volumes - [x] **DEPLOY-04**: Single docker-compose.yml for easy deployment -## v2 Requirements - -Deferred to future release. Tracked but not in current roadmap. +## v2 Requirements (Deferred) ### Polish @@ -84,8 +81,6 @@ Deferred to future release. Tracked but not in current roadmap. ## Out of Scope -Explicitly excluded. Documented to prevent scope creep. - | Feature | Reason | |---------|--------| | Real-time collaboration | Personal tool, single user — massive complexity for no value | @@ -102,8 +97,6 @@ Explicitly excluded. Documented to prevent scope creep. ## Traceability -Which phases cover which requirements. Updated during roadmap creation. - | Requirement | Phase | Status | |-------------|-------|--------| | CORE-01 | Phase 2 | Complete | @@ -138,11 +131,7 @@ Which phases cover which requirements. Updated during roadmap creation. | DEPLOY-03 | Phase 6 | Complete | | DEPLOY-04 | Phase 6 | Complete | -**Coverage:** -- v1 requirements: 31 total -- Mapped to phases: 31 -- Unmapped: 0 +**Coverage:** 31/31 requirements complete --- -*Requirements defined: 2026-01-29* -*Last updated: 2026-01-29 after roadmap creation* +*Archived: 2026-02-01 as part of v1.0 milestone completion* diff --git a/.planning/milestones/v1.0-ROADMAP.md b/.planning/milestones/v1.0-ROADMAP.md new file mode 100644 index 0000000..89beae7 --- /dev/null +++ b/.planning/milestones/v1.0-ROADMAP.md @@ -0,0 +1,160 @@ +# Milestone v1.0: MVP + +**Status:** ✅ SHIPPED 2026-02-01 +**Phases:** 1-6 +**Total Plans:** 18 + +## Overview + +TaskPlanner delivers personal task and notes management with image attachments, accessible from any device via web browser. The roadmap progresses from data foundation through core features (entries, images, tags, search) to containerized deployment, with each phase delivering complete, verifiable functionality that enables the next. + +## Phases + +### Phase 1: Foundation +**Goal**: Data persistence and project structure are ready for feature development +**Depends on**: Nothing (first phase) +**Requirements**: None (foundational — enables all other requirements) +**Success Criteria** (what must be TRUE): + 1. SQLite database initializes with schema on first run + 2. Unified entries table supports both tasks and thoughts via type field + 3. Repository layer provides typed CRUD operations for entries + 4. Filesystem storage directory structure exists for future images + 5. Development server starts and serves a basic page +**Plans**: 2 plans + +Plans: +- [x] 01-01-PLAN.md — SvelteKit project setup with Drizzle schema and unified entries table +- [x] 01-02-PLAN.md — Repository layer with typed CRUD and verification page + +### Phase 2: Core CRUD +**Goal**: Users can create, manage, and view entries with a responsive, accessible UI +**Depends on**: Phase 1 +**Requirements**: CORE-01, CORE-02, CORE-03, CORE-04, CORE-05, CORE-06, CAPT-01, CAPT-02, CAPT-03, UX-01, UX-02, UX-03 +**Success Criteria** (what must be TRUE): + 1. User can create a new entry specifying task or thought type + 2. User can edit entry title, content, and type + 3. User can delete an entry with confirmation + 4. User can mark a task as complete and see visual indicator + 5. User can add notes to an existing entry + 6. Quick capture input is visible on main view with one-click submission + 7. UI is usable on mobile devices with adequate touch targets + 8. Text is readable for older eyes (minimum 16px base font) +**Plans**: 4 plans + +Plans: +- [x] 02-01-PLAN.md — Form actions for CRUD operations and accessible base styling +- [x] 02-02-PLAN.md — Entry list, entry cards, and quick capture components +- [x] 02-03-PLAN.md — Inline editing with expand/collapse, auto-save, and completed toggle +- [x] 02-04-PLAN.md — Swipe-to-delete gesture and mobile UX verification + +### Phase 3: Images +**Goal**: Users can attach, view, and manage images on entries from any device +**Depends on**: Phase 2 +**Requirements**: IMG-01, IMG-02, IMG-03, IMG-04 +**Success Criteria** (what must be TRUE): + 1. User can attach images via file upload on desktop + 2. User can attach images via camera capture on mobile + 3. User can view attached images inline with entry + 4. User can remove image attachments from an entry + 5. Images are stored on filesystem (not in database) +**Plans**: 4 plans + +Plans: +- [x] 03-01-PLAN.md — Database schema, file storage, thumbnail generation, and API endpoints +- [x] 03-02-PLAN.md — File upload form action and ImageUpload component with drag-drop +- [x] 03-03-PLAN.md — CameraCapture component with getUserMedia and preview/confirm flow +- [x] 03-04-PLAN.md — EntryCard integration with gallery, lightbox, and delete functionality + +### Phase 4: Tags & Organization +**Goal**: Users can organize entries with tags and quick access features +**Depends on**: Phase 2 +**Requirements**: TAG-01, TAG-02, TAG-03, TAG-04, ORG-01, ORG-02, ORG-03 +**Success Criteria** (what must be TRUE): + 1. User can add multiple tags to an entry + 2. User can remove tags from an entry + 3. Tag input shows autocomplete suggestions from existing tags + 4. Tags are case-insensitive ("work" matches "Work" and "WORK") + 5. User can pin/favorite an entry for quick access + 6. User can set a due date on a task + 7. Pinned entries appear in a dedicated section at top of list +**Plans**: 3 plans + +Plans: +- [x] 04-01-PLAN.md — Tags schema with case-insensitive index and tagRepository +- [x] 04-02-PLAN.md — Pin/favorite and due date UI (uses existing schema columns) +- [x] 04-03-PLAN.md — Tag input component with Svelecte autocomplete + +### Phase 5: Search +**Goal**: Users can find entries through search and filtering +**Depends on**: Phase 2, Phase 4 (tags for filtering) +**Requirements**: SRCH-01, SRCH-02, SRCH-03, SRCH-04 +**Success Criteria** (what must be TRUE): + 1. User can search entries by text in title and content + 2. User can filter entries by tag (single or multiple) + 3. User can filter entries by date range + 4. User can filter to show only tasks or only thoughts + 5. Search results show relevant matches with highlighting +**Plans**: 3 plans + +Plans: +- [x] 05-01-PLAN.md — SearchBar and FilterBar components with type definitions +- [x] 05-02-PLAN.md — Filtering logic and text highlighting utilities +- [x] 05-03-PLAN.md — Integration with recent searches and "/" keyboard shortcut + +### Phase 6: Deployment +**Goal**: Application runs in Docker with persistent data and easy configuration +**Depends on**: Phase 1-5 (all features complete) +**Requirements**: DEPLOY-01, DEPLOY-02, DEPLOY-03, DEPLOY-04 +**Success Criteria** (what must be TRUE): + 1. Application runs in a Docker container + 2. Configuration is provided via environment variables + 3. Data persists across container restarts via named volumes + 4. Single docker-compose.yml starts the entire application + 5. Backup of data directory preserves all entries and images +**Plans**: 2 plans + +Plans: +- [x] 06-01-PLAN.md — Docker configuration with adapter-node, Dockerfile, and docker-compose.yml +- [x] 06-02-PLAN.md — Health endpoint, environment documentation, and backup script + +## Progress + +**Execution Order:** +Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 -> 6 + +| Phase | Plans Complete | Status | Completed | +|-------|----------------|--------|-----------| +| 1. Foundation | 2/2 | Complete ✓ | 2026-01-29 | +| 2. Core CRUD | 4/4 | Complete ✓ | 2026-01-29 | +| 3. Images | 4/4 | Complete ✓ | 2026-01-31 | +| 4. Tags & Organization | 3/3 | Complete ✓ | 2026-01-31 | +| 5. Search | 3/3 | Complete ✓ | 2026-01-31 | +| 6. Deployment | 2/2 | Complete ✓ | 2026-02-01 | + +--- + +## Milestone Summary + +**Key Decisions:** +- Tailwind CSS v4 with @tailwindcss/vite plugin +- Unified entries table with type discriminator (task/thought) +- SQLite with WAL mode for concurrent reads +- Repository pattern with singleton instances +- Native touch handlers for swipe-to-delete +- File input with capture="environment" for mobile camera (replaced getUserMedia) +- Svelecte for tag autocomplete +- TASKPLANER_ prefix for environment variables + +**Issues Resolved:** +- Docker container restart loop (DATA_DIR env var conflict with adapter-node) +- 403 CSRF errors (missing TASKPLANER_ORIGIN) +- Database schema not initializing (added auto-init) + +**Technical Debt Incurred:** +- CameraCapture.svelte orphaned (313 lines unused, replaced with file input) +- 15 TypeScript warnings (state initialization, non-blocking) + +--- + +*For current project status, see .planning/MILESTONES.md* +*Archived: 2026-02-01 as part of v1.0 milestone completion*