Current state
Every call to list_visible issues a separate for_task comment query for each task row returned, creating an N+1 query pattern against SQLite. Any caller that loads the task list — including the TUI's main refresh loop — pays O(n) round-trips per render cycle, where n is the number of visible tasks.
Ideal state
list_visible loads task comments in a single JOIN or a single batched WHERE task_id IN (...) query alongside task rows.
- The total number of SQLite calls to load the visible task list is O(1) regardless of how many tasks are visible.
- All callers of
list_visible receive fully-hydrated tasks without any change to their call sites.
Starting points
store/src/tasks.rs — list_visible function; the .map(...) closure at line 224 where crate::task_comments::for_task(conn, id)? is called per row
store/src/task_comments.rs — for_task implementation to understand the query shape
QA plan
- Open
store/src/tasks.rs and locate list_visible. Expect to see for_task called inside a per-row map — this is the pattern to replace.
- After the fix, read the new implementation. Expect a single SQL query (JOIN or batched
IN) rather than a loop of individual queries.
- Run
just test. Expect all store tests to pass.
- With SQLite query logging or tracing enabled, call
list_visible with 10+ tasks present. Expect exactly 1–2 queries total (tasks + comments in one pass), not n+1.
Done when
list_visible retrieves all visible tasks and their comments with a fixed number of SQLite queries, not one query per task row.
Current state
Every call to
list_visibleissues a separatefor_taskcomment query for each task row returned, creating an N+1 query pattern against SQLite. Any caller that loads the task list — including the TUI's main refresh loop — pays O(n) round-trips per render cycle, where n is the number of visible tasks.Ideal state
list_visibleloads task comments in a single JOIN or a single batchedWHERE task_id IN (...)query alongside task rows.list_visiblereceive fully-hydrated tasks without any change to their call sites.Starting points
store/src/tasks.rs—list_visiblefunction; the.map(...)closure at line 224 wherecrate::task_comments::for_task(conn, id)?is called per rowstore/src/task_comments.rs—for_taskimplementation to understand the query shapeQA plan
store/src/tasks.rsand locatelist_visible. Expect to seefor_taskcalled inside a per-row map — this is the pattern to replace.IN) rather than a loop of individual queries.just test. Expect all store tests to pass.list_visiblewith 10+ tasks present. Expect exactly 1–2 queries total (tasks + comments in one pass), not n+1.Done when
list_visibleretrieves all visible tasks and their comments with a fixed number of SQLite queries, not one query per task row.