focus-flow/Codex Documentation/Current Software Plan/UI Plan 2 - Backlog Board Implementation/UI_PLAN_2_IMPLEMENTATION_NOTES.md

12 KiB

UI Plan 2 Implementation Notes

Block 01 Baseline Map

  1. Sidebar and app shell currently render through apps/focus_flow_flutter/lib/widgets/sidebar.dart, apps/focus_flow_flutter/lib/widgets/app_shell.dart, and the FocusFlowHome parts under apps/focus_flow_flutter/lib/app/home/.
  2. Navigation state is not implemented yet. Sidebar hard-codes Today as active, and FocusFlowHome owns only Today controllers. UI Plan 2 should add app-level section state in the home/composition layer before rendering the Backlog board.
  3. Backlog board data needs new public scheduler application read models. The current BacklogQueryResult is list-shaped and returns raw Task values via BacklogItemReadModel, which is not enough for board columns, summary, detail drawer metadata, or suggested slot previews.
  4. Existing commands include quick capture to backlog, schedule backlog item to next available slot, move flexible tasks to backlog, remove task, and break up task. Push-to-Someday and non-destructive backlog archive still need command-level decisions before the drawer actions can be final.
  5. UI Plan 1 components to reuse include FocusFlowTokens, the dark shell, timeline reward icon, difficulty bars, selected overlay patterns, and the top-bar icon/segmented-control styling conventions.

Block 01 Validation

  • scripts/bootstrap_dev.sh: passed.
  • dart analyze: passed.
  • dart test: passed.
  • flutter analyze in apps/focus_flow_flutter: passed.
  • flutter test in apps/focus_flow_flutter: passed.

Block 02 Audit

  1. GetBacklogRequest, BacklogQueryResult, and BacklogItemReadModel remain the compatibility path for the existing simple backlog pane.
  2. UI Plan 2 should add board-specific public read models instead of extending BacklogQueryResult, because the board needs columns, summary distributions, child previews, detail rows, and suggested slots while the current list result intentionally exposes raw tasks plus staleness markers.
  3. The board bucket policy belongs in pure scheduler backlog code under packages/scheduler_core/lib/src/scheduling/backlog/, with Flutter consuming only public scheduler_core.dart exports.

Block 02 Notes/Tags Breakpoint

Adding real V1 task notes and freeform tags is a broad persistence change, not only a drawer read-model change. It would touch at least:

  1. Task, Task.quickCapture, and Task.copyWith.
  2. Task document fields and TaskDocumentMapping.
  3. Persistence contract field sets and document field coverage tests.
  4. In-memory application/repository round trips through the full domain object.
  5. SQLite Drift task table columns, generated database code, schema versioning, migration strategy, migration tests, and both SQLite task mappers.
  6. Command/capture surfaces if the UI can create or edit notes/tags.

Per UI_PLAN_2_BLOCK_02_BACKLOG_READ_MODELS_AND_METADATA.md, this is the breakpoint where Ashley needs to choose whether drawer tags should be read-only placeholders for now or true V1 metadata with a schema migration.

Ashley chose the read-only path for UI Plan 2. Backlog drawer notes remain null, and tags are derived only from existing narrow backlog metadata for now (BacklogTag.wishlist displays as someday). True notes and freeform tags are tracked in Human Documentation/Things to consider todo/Backlog Notes and Freeform Tags Metadata.md for a later migration-backed feature.

Block 02 Board and Detail Queries

  1. GetBacklogBoardRequest and GetBacklogTaskDetailRequest now expose the public query inputs needed by Flutter without importing scheduler src/.
  2. V1ApplicationManagementUseCases.getBacklogBoard loads backlog candidates, project display metadata, direct child previews, search/filter/sort/group state, bucket policy results, and summary distributions through repository read boundaries only.
  3. V1ApplicationManagementUseCases.getBacklogTaskDetail returns the selected backlog task drawer model, read-only derived tags, project options, and non-mutating suggested slot previews. Missing duration returns a display reason instead of attempting scheduling.
  4. Focused application-management tests cover stable empty columns, bucket and summary consistency, search/filter behavior, child previews, not-found detail responses, read-only slot suggestions, and missing-duration handling.

Block 02 Demo Seed Data

  1. The Flutter demo composition now seeds Backlog board data as real scheduler Task and ProjectProfile records, not widget-local mock rows.
  2. The seed matches the feasible textual targets from Chunk 2.7: 24 backlog tasks, project counts of Home 5 / Work 8 / Personal 5 / Learning 4 / Side Project 2, priority counts of High 7 / Medium 9 / Low 8, and 12h 15m total estimated time.
  3. The plan/mockup contains a count conflict: the mockup summary says 24 tasks, while the listed column badge counts add to 22. The current seed keeps 24 repository-backed backlog tasks so the summary target stays truthful through public read models.
  4. Review Q3 budget is seeded with Work, 60 minutes, High priority, medium reward, and easy difficulty. Finance/review freeform tags, notes text, and exact drawer slot copy remain deferred with the approved metadata scope decision above.

Block 03 Navigation and Screen Shell

  1. FocusFlowSection now owns app-level navigation state for Today, Backlog, Projects, Reports, and Settings. The sidebar is controlled by this state and exposes stable active keys for Today and Backlog tests.
  2. BacklogBoardController loads BacklogBoardQueryResult, tracks local search/filter/sort/group values, and keeps selected task detail as UI-local state. It uses only public scheduler application read models.
  3. Demo and persistent compositions both create the Backlog controller from the same underlying application store used by Today, so future commands can refresh both surfaces without creating separate fake state.
  4. BacklogBoardScreen renders the desktop Backlog header, controls, column shells, loading/empty/failure states, and a compact summary panel shell. Detailed cards, charts, and drawer contents remain for later UI Plan 2 blocks.

Block 04 Board Columns and Cards

  1. Backlog bucket, priority, project, reward, and future tag-chip colors now live in apps/focus_flow_flutter/lib/theme/backlog_board_visual_tokens.dart instead of inline card mappings.
  2. BacklogBoardScreen delegates column rendering to reusable board column and task card widgets. The board keeps the summary panel fixed on the right and horizontally scrolls the four-column board if the available desktop width is constrained.
  3. BacklogTaskCard renders only public BacklogBoardItemReadModel data: title, subtitle or bucket reason, duration, project dot/name, priority flag, difficulty bars, solid reward marks, selected outline, and direct child previews.
  4. Add-task controls intentionally call a no-op bucket callback until Block 8 wires the create-task command flow. Card taps select through BacklogBoardController.selectTask, which performs a read-only detail query.
  5. The current demo seed still represents mockup child rows as normal backlog tasks rather than parent-child relationships. Child preview rendering is covered by a focused widget test using handcrafted public read models so the seed scope does not expand in this block.

Block 05 Search, Filter, Sort, and Group Controls

  1. The board request now has BacklogBoardFilterSelection for board-only filters: priority group, project, duration bucket, board bucket, and missing duration. Legacy BacklogFilter.noRewardSet remains the cleanup filter for no-reward tasks.
  2. BacklogSortKey.custom preserves source/read-model order for the board default, and BacklogSortKey.duration supports duration ordering. The simple backlog list still keeps its existing priority default.
  3. BacklogBoardGroupMode now supports project, priority, and duration grouping as stable ordering inside the existing four bucket columns. The UI does not add section dividers in this block.
  4. The Backlog control row lives in apps/focus_flow_flutter/lib/widgets/backlog/backlog_board_controls.dart. Search reloads through the board query, filters apply through the public request object, sort/group menus update controller state, and Compact, Settings, and New Task remain safe inert shells until later blocks.

Block 06 Summary Panel

  1. BacklogSummaryPanel now owns the right-side summary surface and consumes only BacklogBoardSummaryReadModel data from the public scheduler API.
  2. The panel renders total tasks, total estimated time, priority distribution, project distribution, a custom-painted duration donut with legend rows, and the planning tip card without hardcoded summary values.
  3. Summary panel color decisions use apps/focus_flow_flutter/lib/theme/backlog_board_visual_tokens.dart for priority, project, and duration colors so board cards and summary rows share the same visual mapping.
  4. Collapse and expand state is local to the Flutter widget. It hides body sections while leaving the summary header visible and does not write any scheduler state.

Block 07 Task Detail Drawer

  1. BacklogBoardController now keeps selected-task id, detail loading state, and detail-read failures as UI-local state. Detail failures render in the drawer and no longer replace the whole Backlog screen.
  2. BacklogBoardScreen renders BacklogTaskDrawer in a right-anchored Stack overlay. The board and summary row stay in their original layout, so opening and closing the drawer does not shift cards.
  3. BacklogTaskDrawer renders header metadata, empty or read-only notes, project display, read-only tags, duration/reward/difficulty metrics, suggested slot previews, and Block-8-ready action buttons from public BacklogTaskDetailReadModel data.
  4. Real notes and freeform tags remain deferred per the Block 02 metadata decision. The drawer shows calm empty states when the read model has no notes or tags instead of inventing Flutter-only persisted metadata.

Block 08 Commands Through Drawer Actions

  1. Metadata edit controls remain safe non-mutating placeholders at this point because real notes and freeform tags were explicitly deferred in Block 02. Project and tag editing should be revisited with a migration-backed metadata command rather than Flutter-only state.
  2. BacklogBoardScreen now accepts the app SchedulerCommandController. Backlog command state is rendered in a compact status banner below the controls.
  3. Top-level New Task and column Add task open a title-first creation dialog. Successful submission calls the existing quickCaptureToBacklog command and refreshes Backlog through the shared command controller.
  4. Drawer Schedule calls the existing scheduleBacklogItemToNextAvailableSlot command through SchedulerCommandController.scheduleBacklogItem. Missing duration shows a drawer-local message and does not start a command.
  5. Drawer Break Up opens a focused child-entry dialog with two initial rows. The dialog validates at least two titled rows, optional whole-minute estimates, and submits ApplicationChildTaskDraft values through the existing breakUpTask application command. Successful saves refresh the board and selected detail so child previews come from scheduler read models.
  6. Drawer Push to Someday now uses a Backlog-specific application command that adds the existing BacklogTag.wishlist flag without scheduling or deleting the task. The selected detail and board refresh into the Not Now bucket.
  7. Drawer Remove now confirms with the requested copy and archives the task through a Backlog-specific application command. It marks the task TaskStatus.noLongerRelevant, clears active Backlog selection on success, and does not physically delete repository data.
  8. The shared application-command change detector now includes Backlog metadata such as backlogTags, so metadata-only commands are persisted even when the command clock equals the task's previous updatedAt.