summaryrefslogtreecommitdiff
path: root/internal/store
AgeCommit message (Collapse)Author
2026-07-16Add availability_blocks CRUD to the store layerPeter Stone
2026-07-16Add estimated_minutes to native task read/write/recurrence pathsPeter Stone
2026-07-16Add schema for task budgets and availability blocksPeter Stone
Creates migrations/025_task_budgets_and_availability.sql with: - New availability_blocks table for manual weekly availability templates - estimated_minutes column on native_tasks for time budgeting - budget_tracked flag on projects and labels for opt-in tracking Fixes pre-existing bug in sqlite_test.go's setupTestStoreWithNativeTasks where project_id column was missing from the schema, causing test failures. Updates all hand-rolled test helpers (sqlite_test.go, native_tasks_test.go) to include the new columns, and adds availability_test.go with newAvailabilityTestStore helper for Task 4's availability CRUD tests. All store tests pass, including the two that were previously failing (TestGetNativeTasksByDateRange_ExcludesOverdue, TestGetOverdueNativeTasks_IncludesOnlyPastDue). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PQaPGQVSfmKUiHXB87qRTC
2026-07-16feat(tasks): add label color CRUD store methodsPeter Stone
2026-07-16feat(tasks): add Projects CRUD store methodsPeter Stone
2026-07-16feat(tasks): add projects/labels schema, wire project_id through native tasksPeter Stone
project_id joins the existing labels JSON column as series-level metadata: CreateNextIteration copies both onto every new recurring occurrence, matching content/description/priority's existing behavior.
2026-07-16refactor(store): extract agent session/trust methods from sqlite.goPeter Stone
Pure move: all agent-session and agent CRUD/trust methods (~340 lines) plus their full test suite and setupTestStoreWithAgents helper, out of sqlite.go/sqlite_test.go into agents.go/agents_test.go. No behavior change. Mirrors internal/handlers/agent.go's domain naming. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-16refactor(store): extract calendar and Google Tasks methods from sqlite.goPeter Stone
Pure move: SaveCalendarEvents/GetCalendarEvents/GetCalendarEventsByDateRange into calendar.go, SaveGoogleTasks/GetGoogleTasks/GetGoogleTasksByDateRange into google_tasks.go. Neither cluster had dedicated tests in sqlite_test.go to move. No behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-16refactor(store): extract shopping methods from sqlite.go into shopping.goPeter Stone
Pure move: UserShoppingItem type, its CRUD methods, and SetShoppingItemChecked/GetShoppingItemChecks, plus their tests and setupTestStoreWithShopping helper, out of sqlite.go. No behavior change. Mirrors the existing internal/handlers/shopping.go naming. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-16refactor(store): extract meal methods from sqlite.go into meals.goPeter Stone
Pure move: SaveMeals/GetMeals/GetMealsByDateRange and their test (plus its setupTestStoreWithMeals helper, used only by that test) out of the 1400+ line sqlite.go into their own file. No behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-16fix(tasks): make CreateNextIteration atomically self-guardingPeter Stone
Folds the "is this still the latest row in its series?" check directly into the INSERT as a single atomic INSERT...SELECT...WHERE NOT EXISTS statement, instead of a separate SELECT-then-INSERT sequence. Closes a narrow race where the completion trigger and the periodic due-date check could both pass their "still latest" check before either had inserted, producing two duplicate successor rows for the same series. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-16fix(tasks): return ErrNativeTaskNotFound from UpdateNativeTask on stale idPeter Stone
HandleWidgetTaskUpdate now returns 404 instead of silently succeeding when the widget's cached task id no longer exists, matching every other native_tasks mutator's checkRowsAffected pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-16feat(tasks): add periodic due-date check for recurring tasksPeter Stone
A recurring task's successor now also gets created once its due date passes, independent of completion -- an ignored/overdue recurring task no longer blocks the next occurrence from appearing. Runs every 15 minutes via a new goroutine in main.go, cancelled on shutdown.
2026-07-16feat(tasks): create the next recurring iteration on completionPeter Stone
CompleteNativeTask now creates a new row for the next occurrence when completing the latest iteration of a recurring series (using the one-shot next_occurrence_override if set, else ComputeNextOccurrence). Completing an already-superseded row (the periodic due-check beat it to creating the successor) just marks it completed, no double-create.
2026-07-16feat(tasks): add recurrence columns and model fields for native tasksPeter Stone
recurrence_series_id != "" is the real recurring indicator (IsRecurring predates this feature and is never set). Adds parseWeekdays/formatWeekdays for the comma-separated weekday-list column, and threads the five new columns through scanNativeTasks and all four existing SELECT queries. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-13Merge github/master: reconcile with parallel widget workPeter Stone
Another session pushed 27 commits in parallel covering quick-add, event detail popups, recurrence display, overdue badges, a manual refresh button, and its own fix for the same overdue-tasks bug (via a separate GetOverdueNativeTasks fetch folded into BuildTimeline, rather than widening GetNativeTasksByDateRange's bound directly). Reconciled rather than blindly taking one side: - Reverted GetNativeTasksByDateRange to its original bounded query and kept upstream's GetOverdueNativeTasks + BuildTimeline fold-in as the sole overdue mechanism for native tasks, to avoid double-counting overdue items (my widened query + their separate fetch would have both returned them). Re-pointed the regression test at the now-correct contract and added a store-level test for GetOverdueNativeTasks directly. - Kept my GetGoogleTasksByDateRange fix as-is (single unbounded query) -- upstream never touched Google Tasks overdue handling, so there's no duplication risk there. - Rewove WidgetRoot's LazyColumn structure (added for scrolling) around upstream's new header buttons, pinned all-day event rows, and the enhanced TomorrowSection, none of which were written LazyColumn-aware since that work landed on this side only. - Combined both sides' additions to TaskDetailActivity/TaskDetailSheet (description-edit detail popup + due-date reschedule label) and WidgetRepository/Actions (optimistic local removal + refresh button wiring) -- these were independent, non-overlapping features that both needed to survive. - Renumbered the migration collision: both sides independently added a migration numbered 022. Card-description was already applied to the live production DB under that filename earlier this session (migrations are tracked by filename), so it keeps 022; the recurring-event-id migration, never deployed under any name here, moves to 023. Verified: go build clean, full test suite passes (only the two pre-existing agent-handler failures and the pre-existing models package build error remain, both confirmed unrelated via git stash before this session began), and a dry run against a copy of the live production database applies both migrations cleanly with no re-run conflicts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
2026-07-13feat(widget): editable task details, scrollable list, and overdue-task fixesPeter Stone
- Add description editing to the widget's task detail popup for doot/gtasks/trello, backed by new GET /api/widget/detail and POST /api/widget/update endpoints - Make Google Tasks and Trello cards completable via the widget (Trello completion archives the card); fix Trello description never being fetched, which meant saving could silently wipe a card's real desc - Fix google_tasks.due_date/updated_at (TEXT columns) never round-tripping through sql.NullTime, which broke cached Google Tasks reads whenever the cache was valid - Fix native-task and Google-Task date-range queries excluding anything due before the window start, which dropped incomplete tasks off the widget the moment their due day passed (the "overdue tasks disappeared" bug) - Fix native task description edits blanking the task's title - Make the widget's day list scroll (LazyColumn) instead of clipping - Optimistically remove a task from the widget immediately on completion, ahead of the authoritative background refresh Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
2026-07-12feat(widget): capture and forward RecurringEventID for calendar eventsPeter Stone
2026-07-12fix(timeline): include overdue native tasks in timeline and widgetPeter Stone
GetNativeTasksByDateRange's SQL bound (due_date >= start) excluded any task overdue from a previous day before ComputeDaySection ever got a chance to mark it IsOverdue, so both the web Timeline view and the widget API (which both call BuildTimeline with start = today) silently dropped overdue tasks entirely -- only the Tasks tab (unbounded GetNativeTasks) showed them. Added GetOverdueNativeTasks and folded its results into BuildTimeline alongside the ranged fetch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VTUSAEKfsPc6WGDq45yPHD
2026-07-12fix(widget): surface unmatched task IDs instead of silently no-oppingPeter Stone
CompleteNativeTask/UncompleteNativeTask/RescheduleNativeTask ran a plain UPDATE ... WHERE id = ? and returned whatever error Exec gave back -- which is nil even when 0 rows match, since that's not a SQL error. A stale or wrong id from the widget looked identical to a real completion: HTTP 200, nothing changed in the database. Real incident: 1 of 3 widget completeTask taps silently no-opped this way. Now checks RowsAffected() and returns ErrNativeTaskNotFound (mirrors the existing pattern in sqlite.go's ApproveAgentSession/DenyAgentSession). HandleWidgetComplete and HandleWidgetReschedule surface this as 404 instead of a fake 200, so the widget can tell 'nothing changed' apart from 'it worked.'
2026-07-06feat: remove Todoist integration entirelyDoot Agent
Native tasks (native_tasks table) fully replace Todoist. All Todoist API code, store functions, handlers, routes, templates, and tests have been removed. Migration 021 drops the now-unused tasks cache table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29feat: reschedule tasks from widget bottom sheetPeter Stone
Tapping a doot task shows a date picker. On confirm, POSTs to /api/widget/reschedule, updates due_date in native_tasks, refreshes widget. Reschedule button only shows for source="doot" tasks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29feat: native task management + Todoist migrationPeter Stone
Adds doot-owned task storage (native_tasks table) so tasks can be managed without Todoist. CompleteTask for 'doot' source just updates the DB — no external API call, no token dependency. Migration path: POST /settings/import-from-todoist — copies Todoist cache → native_tasks Then remove TODOIST_TOKEN from .env to disable Todoist Changes: - migration 020: native_tasks table - store: GetNativeTasks, GetNativeTasksByDateRange, GetUndatedNativeTasks, CreateNativeTask, CompleteNativeTask, UncompleteNativeTask, UpdateNativeTask, ImportFromTodoist - timeline: native tasks appear as source="doot" (teal) - handleAtomToggle: "doot" case — no external API needed - HandleWidgetComplete: method on Handler, handles "doot" natively - HandleUnifiedAdd: "doot" source creates in native_tasks - widget: "doot" tasks are completable, teal color indicator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23feat: unify Google Tasks with main system via caching and integrated UIPeter Stone
- Implement SQLite caching layer for Google Tasks - Integrate Google Tasks into unified Atoms loop (showing in Tasks tab) - Update Planning tab to include cached Google Tasks - Enhance Quick Add form with Todoist project selector - Remove orphaned HandleTasksTab/HandleRefreshTab methods - Update tests to reflect new BuildTimeline signature and data structures
2026-03-23feat: complete Agent Context API Phase 2 & 3 (Write/Create/Management)Peter Stone
- Implement write operations (complete, uncomplete, update due date, update task) - Implement create operations (create task, add shopping item) - Add Trusted Agents management UI in Settings with revocation support - Fix SQLite timestamp scanning bug for completed tasks - Add comprehensive unit tests for all new agent endpoints - Update worklog and feature documentation
2026-03-23fix: parse Todoist local datetimes, show near-future tasks, add undated ↵Peter Stone
tasks to timeline - parseDueDate: handle date field containing "YYYY-MM-DDTHH:MM:SS" (local time, no tz offset) — Todoist REST API v1 uses this format for recurring tasks with a set time, causing due dates to silently parse as nil - IsFuture threshold: widen from tomorrow to 7 days out so tasks due this week show in the main tasks section with dates visible (not collapsed) - BuildTimeline: include undated Todoist tasks in the Today section (mirrors existing Google Tasks behavior) - GetUndatedTasks: new store method for tasks with due_date IS NULL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22chore: unify and centralize agent configuration in .agent/Peter Stone
2026-03-21feat: Phase 1 — remove bug feature and dead codePeter Stone
- Delete Bug struct, BugToAtom, SourceBug, TypeBug, TypeNote - Remove bug store methods (SaveBug, GetBugs, ResolveBug, etc.) - Remove HandleGetBugs, HandleReportBug, bug branches in handlers - Remove bug routes, bugs.html template, bug UI from index.html - Remove AddMealToPlanner stub + interface method - Migration 018: DROP TABLE IF EXISTS bugs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19test: add coverage for planning tab, meals, Google Tasks, bug handlers, ↵Agent
completed task parsing - HandleTabPlanning: happy-path test verifying tasks/cards land in correct sections (scheduled/unscheduled/upcoming); boundary test confirming a task due exactly at midnight of tomorrow lands in Upcoming, not Scheduled - HandleTabMeals: grouping test verifying two meals sharing date+mealType produce one CombinedMeal with both recipe names merged - Google Tasks GetTasksByDateRange: four boundary tests (start inclusive, end exclusive, no-due-date always included, out-of-range excluded) using redirectingTransport mock server pattern - HandleGetBugs: data assertions verifying bug list and empty-list cases - HandleReportBug: success test verifying bug is saved and bugs template is re-rendered - GetCompletedTasks: timestamp parsing test ensuring CompletedAt is not zero when inserted with a known "2006-01-02 15:04:05" string Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04feat: sync log, cache clear endpoint, Todoist projects from cached tasksPeter Stone
- migration 016: sync_log table - store: AddSyncLogEntry, GetRecentSyncLog, InvalidateAllCaches, GetProjectsFromTasks - settings: HandleClearCache (POST /settings/clear-cache), SyncLog in page data - settings: use GetProjectsFromTasks instead of deprecated Todoist REST /projects - handlers: populate atom projects from store - agent: log warning on registration failure instead of silently swallowing - google_tasks: simplify URL literal - tests: sync log CRUD, clear cache handler, settings page includes sync log, sync sources adds log entry, incremental sync paths, task completion response/headers, calendar cache fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-17Add calendar cache layer, incremental sync tests, completion assertionsPeter Stone
- Google Calendar events now cached via CacheFetcher pattern with stale-cache fallback on API errors (new migration 015, store methods, fetchCalendarEvents handler, BuildTimeline reads from store) - Todoist incremental sync path covered by 5 new tests - Task completion tests assert response body, headers, and template data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06Fix missing settings button, disappeared events, and tab refresh bugPeter Stone
- Add settings gear icon link to dashboard header - Fix GetTasksByDateRange/GetCardsByDateRange to include overdue items (changed from BETWEEN to <= end, filter completed tasks) - Fix refresh replacing active tab with tasks tab by using htmx.trigger(body, 'refresh-tasks') instead of innerHTML+htmx.process - Add refresh-tasks hx-trigger to meals, shopping, conditions tabs - Add tests for overdue inclusion/exclusion, settings link, template data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-03Add comprehensive test coverage across packagesPeter Stone
New test files: - api/http_test.go: HTTP client and error handling tests - config/config_test.go: Configuration loading and validation tests - middleware/security_test.go: Security middleware tests - models/atom_test.go: Atom model and conversion tests Expanded test coverage: - api/todoist_test.go: Todoist API client tests - api/trello_test.go: Trello API client tests - auth/auth_test.go: Authentication and CSRF tests - handlers/timeline_logic_test.go: Timeline building logic tests - store/sqlite_test.go: SQLite store operations tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31Add feature toggles system with settings UI (#74)Peter Stone
- Add feature_toggles table (migration 012) - Add source_config table for future source selection (migration 013) - Create settings page at /settings with: - Feature toggle management (enable/disable/create/delete) - Data source configuration (sync and toggle boards/calendars) - Add store methods for feature toggles and source config - Add GetCalendarList and GetTaskLists to Google API clients - Document feature toggle workflow in DESIGN.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28Expand agent context API with completed log and calendar viewPeter Stone
- Add completed_tasks table to log task completions with title, due date, and completion timestamp - Extend agent context date range: 7 days back to 14 days forward - Add completed_log to API response (last 50 completed tasks) - Add day_section field to timeline items (overdue/today/tomorrow/later) - Add calendar-style view for today's schedule (6am-10pm hourly grid) - Add tabbed interface for Timeline vs Completed Log in HTML view Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28Add Agent Context API for external agent integrationPeter Stone
Phase 1: Authentication and read-only context - POST /agent/auth/request - request access with name + agent_id - GET /agent/auth/poll - poll for approval status - POST /agent/auth/approve|deny - user approval (browser auth required) - GET /agent/context - 7-day timeline context (agent session required) Phase 1.5: Browser-only agent endpoints (HTML pages) - GET /agent/web/request - request page with token - GET /agent/web/status - status page with polling - GET /agent/web/context - context page with timeline data WebSocket notifications: - GET /ws/notifications - push agent requests to browsers - Approval modal with trust indicators and countdown timer Database: - agents table for registered agent tracking - agent_sessions table for pending/active sessions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26Fix multiple UI issues and shopping completion bugPeter Stone
- #54: Fix shopping item completion - now works for all sources (trello, plantoeat, user) with state stored in local DB - #48: Hide 12:00am times in timeline (all-day items) - #49: Remove "Task" type label from timeline items for cleaner UI - #51: Combine multiple PlanToEat meals for same date+mealType - #52: Change Conditions tab to standard link to standalone page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26Phase 4: Extract magic numbers to constantsPeter Stone
Create config/constants.go with centralized configuration values: - Concurrency limits (MaxConcurrentTrelloRequests) - Timeouts (HTTP, Google Calendar, graceful shutdown, request) - Meal times (breakfast, lunch, dinner hours) - Database pool settings (connections, lifetime) - Session and rate limiting settings Update all files to use these constants instead of hardcoded values. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26Phase 3: Error handling and security hardeningPeter Stone
- Handle JSON marshal errors in sqlite.go (log + fallback to empty array) - Add 30s timeout to Google Calendar client initialization - Fix CSRF timing attack by using subtle.ConstantTimeCompare Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25Fix all static analysis errors (golangci-lint)Peter Stone
- Fix errcheck: handle all error return values in production code - Fix errcheck: handle all error return values in test files - Fix staticcheck: replace deprecated WithCredentialsFile with WithAuthCredentialsFile - Remove unused code: authHeaders, planToEatPlannerItem, planToEatResponse - Use defer func() { _ = x.Close() }() pattern for ignored close errors Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25Refactor: extract helpers and clean up hardcoded HTMLPeter Stone
- Extract parseEventTime() and deduplicateEvents() in google_calendar.go - Add scanTask() and scanTasks() SQL helpers in sqlite.go - Move completed-atom HTML to partial template - Add loadTestTemplates() test helper for template-dependent tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25Implement architectural refactors for feature requests #28, #30, #31, #33-38Peter Stone
Phase 1: Bugs as First-Class Atoms (#28) - Add resolved_at column to bugs table (migration 007) - Add GetUnresolvedBugs(), ResolveBug(), UnresolveBug() store methods - Include bugs in Tasks tab via BugToAtom() with completion toggle - Add unit tests for bug resolution Phase 2: Timeline as Default + Enhancements (#35, #37) - Change default tab from tasks to timeline - Add IsCompleted, DaySection, Source fields to TimelineItem - Group timeline items by today/tomorrow/later sections - Add completion checkboxes for tasks/cards, grey completed items - Collapse tomorrow/later sections by default Phase 3: Shopping Quick-Add (#33) - Add user_shopping_items table (migration 008) - Add SaveUserShoppingItem(), GetUserShoppingItems(), ToggleUserShoppingItem() - Add HandleShoppingQuickAdd() and HandleShoppingToggle() handlers - Add quick-add form to shopping tab Phase 4: Mobile Swipe Navigation (#38) - Add touch event handlers for swipe left/right tab switching - 50px threshold triggers tab change Phase 5: Consistent Background Opacity (#30) - Add CSS variables for panel/card/input/modal backgrounds - Update templates to use consistent opacity classes Phase 6: Tab Reorganization (#37) - Reorganize tabs: Timeline, Shopping, Conditions as main tabs - Move Tasks, Planning, Meals under Details dropdown Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23Fix uncomplete: add HX-Reswap header to prevent empty swapPeter Stone
The uncomplete response was returning an empty body, causing HTMX to swap the element with nothing before the refresh-tasks trigger fired. Added HX-Reswap: none header to preserve the element while the refresh event propagates. Also fixed TestGetCardsByDateRange test data to include all required columns (list_id, list_name, url). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23Refactor: reduce code duplication with shared abstractionsPeter Stone
- Add BaseClient HTTP abstraction (internal/api/http.go) to eliminate duplicated HTTP boilerplate across Todoist, Trello, and PlanToEat clients - Add response helpers (internal/handlers/response.go) for JSON/HTML responses - Add generic cache wrapper (internal/handlers/cache.go) using Go generics - Consolidate HandleCompleteAtom/HandleUncompleteAtom into handleAtomToggle - Merge TabsHandler into Handler, delete tabs.go - Extract sortTasksByUrgency and filterAndSortTrelloTasks helpers - Update tests to work with new BaseClient structure Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23Fix critical resilience issues from code reviewPeter Stone
- DB connection pool: Allow 5 connections instead of 1 for better concurrency - JSON unmarshal: Add error handling to prevent nil slice issues - Context cancellation: Check ctx.Done() in aggregateData goroutines - Migration path: Make configurable via MIGRATION_DIR env var Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22Fix slice reallocation bug in GetBoardsPeter Stone
The boardMap was storing pointers to Board structs in the boards slice. When the slice grew and reallocated, those pointers became stale, causing cards to be added to old memory locations instead of the current slice. Fixed by storing indices instead of pointers in boardMap. Added tests to verify multiple boards with varying card counts are correctly saved and retrieved. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22Fix slice reallocation bug in GetBoardsPeter Stone
2026-01-22Add debug logging to board save/retrievePeter Stone
2026-01-20Add in-app bug reporting featurePeter Stone
- New bugs table in SQLite (migration 005) - Store methods for saving and retrieving bugs - Handlers for GET/POST /bugs - Floating bug button with modal UI - Shows recent bug reports in modal Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20Add session-based authenticationPeter Stone
Implement secure authentication using scs session manager with SQLite backing store and bcrypt password hashing. - Add users and sessions tables (migration 004) - Create internal/auth package with Service, Middleware, and Handlers - Protect all routes except /login, /logout, /static/* - Add login page template and logout button to dashboard - Default credentials: admin/changeme (configurable via env vars) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>