# UI Plan 2 — Backlog Board Tab Implementation **Status:** Proposed plan. **Primary target:** Implement the finalized Backlog tab shown in the two supplied mockups. **Default mockup:** `mockups/backlog_board_default.png`. **Drawer mockup:** `mockups/backlog_task_drawer.png`. **Execution mode:** Feed this folder to Codex and execute block files in numeric order. Use `xhigh` reasoning for all chunks unless Ashley explicitly says otherwise. **Implementation branch suggestion:** `block-ui-backlog-board` or the repo’s closest existing branch convention. --- ## 1. Purpose Build the desktop-first Backlog tab for FocusFlow as a real Flutter screen, not a throwaway static mockup. The final state should provide: 1. Sidebar navigation with `Backlog` active. 2. Backlog title, task count, search, filters, sort, group, board/compact toggle, settings button, and `New Task` primary action. 3. Four-column backlog board: - `Do Next` - `Need Time Block` - `Break Up First` - `Not Now` 4. Backlog task cards with project, priority, duration, difficulty bars, reward icons, child-task previews, and selection styling. 5. Right-side Backlog summary panel in the default state. 6. Right-anchored task detail drawer when a backlog card is selected. 7. Suggested slots and task actions in the drawer. 8. New task / add task entry points wired to backlog-safe capture. 9. Tests and validation that preserve the existing backend-source-of-truth rule. This plan intentionally treats the mockups as finalized visual direction and uses the current repo architecture as implementation truth. --- ## 2. Source truth and constraints Use sources in this order: 1. Repo files, especially `AGENTS.md`, package boundaries, existing app structure, and tests. 2. This plan folder. 3. The two mockups in `mockups/`. 4. Existing completed UI Plan 1 files. 5. Human documentation and UX flow documents already in the repo. Hard constraints: - V1 is SQLite-first. Do not add MongoDB runtime work. - `scheduler_core` remains pure Dart and is the scheduling/application source of truth. - Flutter must not import scheduler `src/`, Drift/SQLite adapters, notification platform packages, backup/export internals, or OS APIs directly. - UI may own local visual selection state, menu open/closed state, scroll position, text controller state, and drawer open/closed state. - UI must not own canonical scheduling rules, placement rules, task lifecycle rules, or persistence mutations. - Any scheduling/task mutation must go through public scheduler application commands/controllers. - New Dart files require file-level Dartdoc library docs plus Dartdoc for every public/private class, enum, enum value, constructor, method, field, and top-level declaration, following `AGENTS.md`. - New project files require SPDX metadata. --- ## 3. Confirmed repo observations from this planning pass The supplied repo already contains: - Flutter app target: `apps/focus_flow_flutter/`. - Current provisional/Plan 1 Today UI with sidebar, app shell, theme tokens, top bar, timeline cards, difficulty bars, reward icons, and selected-task modal pieces. - Current simple `BacklogPane` and `BacklogRow` that are not visually aligned with the finalized board mockup. - Existing public scheduler application/query concepts: - `V1ApplicationManagementUseCases.getBacklog`. - `BacklogQueryResult`. - `BacklogItemReadModel`. - `GetBacklogRequest`. - `BacklogView`, `BacklogFilter`, and `BacklogSortKey`. - `V1ApplicationCommandUseCases.quickCaptureToBacklog`. - `V1ApplicationCommandUseCases.scheduleBacklogItemToNextAvailableSlot`. - `V1ApplicationCommandUseCases.breakUpTask`. - Existing domain `Task` supports core scheduling fields, project id, duration, priority, reward, difficulty, backlog tags, parent task id, stats, timestamps, scheduled/actual/completed intervals, status, and type. - Current domain `Task` does **not** appear to include freeform notes or general tags, which the drawer mockup shows. - Current application commands do **not** appear to include a general update/edit-backlog-task command, push-to-someday command, or remove/archive backlog command. Plan implication: this is a UI implementation plus a small application/domain read-model expansion, not only a widget rewrite. --- ## 4. Product assumptions to implement unless Ashley changes them These assumptions unblock Codex without inventing broad product scope: 1. **Backlog columns are a V1 read-model policy.** The Flutter board consumes a `BacklogBoardReadModel`; it does not independently decide canonical task grouping. 2. **Column assignment is deterministic and explainable.** Each item exposes `bucket`, `bucketReason`, and optional `reasonMetadata` so the UI can show why it is in that column. 3. **General tags and notes are V1 task metadata.** Add minimal domain/persistence/application support needed for the drawer and create/edit flows. 4. **Remove means archive from active backlog, not physical delete.** Use an application-level remove/archive transition that hides the task from backlog. Prefer `TaskStatus.noLongerRelevant` unless a repo-local convention already says otherwise. 5. **Push to Someday means mark the task as a someday/wishlist backlog item.** Use existing `BacklogTag.wishlist` where possible. This should move or keep the task in `Not Now`. 6. **Suggested slots are non-mutating previews.** They must be generated by application/core read logic or by calling scheduler logic against cloned/current state. They must not save anything until the user presses `Schedule`. 7. **Schedule button chooses a suggested slot only through backend intent.** If the current command only supports “next available slot,” wire the primary button to that command and label suggested rows as preview-only until a slot-specific command exists. 8. **Compact mode can remain a non-primary visual affordance.** Board mode is the acceptance target because only Board has a finalized mockup. If a low-risk compact list already exists, it may be reused behind the toggle, but do not invent a second finalized design. 9. **Settings remains visible and inert for this plan** unless a settings surface already exists. 10. **Project dropdown and tag controls in the drawer should support inline edits only after the relevant update command exists.** If the command is not completed in the same block, render them as disabled/read-only with active visual styling deferred only at the final polish pass. Non-blocking clarification items for Ashley after plan review: - Exact board bucket policy thresholds for `Do Next`, `Need Time Block`, `Break Up First`, and `Not Now`. - Whether `Remove` should be reversible archive, cancellation, no-longer-relevant, or hard delete. - Whether slot rows should support picking a specific slot in V1 or only preview the result of next-available scheduling. - Whether freeform tags should be global reusable tags or simple task-local strings in V1. Do not stop implementation on those questions unless Ashley explicitly requests a policy change before coding. --- ## 5. Visual target summary ### App shell and sidebar - Keep the dark rounded app frame and left sidebar style from UI Plan 1. - Sidebar width remains approximately 250 px. - `Backlog` nav item is active with magenta-tinted fill and outline. - `Today`, `Projects`, `Reports`, and `Settings` remain visible. - Bottom-left status card shows: - green check icon, - `Schedule up to date`, - `All changes are saved.` ### Backlog default state At desktop width around 1672×941: - Main content has a left board region and a right summary panel. - Header row: - `Backlog` title, - `24 tasks` count pill, - subtitle: `Choose work that fits your current energy.` - right controls: `Compact`, `Board` active, `Settings`. - Control row: - search field with placeholder `Search backlog...`, - `Filters` button, - `Sort: Custom` dropdown, - `Group: None` dropdown, - magenta `+ New Task` button with trailing chevron. - Board columns: - each column has an icon, title, count pill, subtitle, add icon, card stack, and `+ Add task` footer. - Summary panel: - `Backlog summary` header with sparkle icon and collapse chevron, - total tasks and total estimated time, - priority counts, - project counts, - duration distribution donut/list, - planning tip card. ### Selected-card drawer state - Selecting/clicking a backlog card opens a right-side drawer. - Drawer is anchored to the right edge of the app content/window. - Drawer overlays existing content and does **not** shift columns, header controls, or summary panel. - No heavy scrim; underlying board remains visible. - Selected card remains highlighted with magenta outline behind the drawer. - Drawer width should be approximately 460–470 px at mockup width, clamped for smaller desktop windows. - Drawer sections: - header with bucket/status icon, title, sparkle icon, close icon, - subtitle and age/created metadata, - notes panel, - project selector and tag chips, - duration/reward/difficulty metric tiles, - suggested slots list, - action buttons: `Schedule`, `Break Up`, `Push to Someday`, `Remove`. --- ## 6. Feature scope ### In scope - Backlog route/tab under current Flutter app. - Sidebar nav state and Backlog active rendering. - Backlog-specific controllers/read state. - Backlog board read models in public scheduler/application API. - Demo seed data sufficient to render the exact mockup composition. - Four board columns with counts and card ordering. - Default summary panel. - Drawer open/close/select-another behavior. - Search/filter/sort/group controls with at least deterministic basic behavior. - New Task and Add Task entry points with backlog-safe capture. - Schedule action for a selected backlog item. - Break Up action path if the existing `breakUpTask` command can be surfaced safely; otherwise the drawer button may open a non-persisting placeholder form until Block 8 completes the command wiring. - Push to Someday command using `BacklogTag.wishlist` or equivalent. - Remove/archive command using the chosen non-destructive lifecycle transition. - Notes and tags support needed for drawer/create/edit read and persistence. - Responsive handling for desktop width reductions. - Widget tests and core/application tests. ### Out of scope - Week/month views. - Drag-and-drop card movement. - Reports implementation. - Shield/Recovery flows. - Calendar sync. - OS notifications. - Backup/restore UI. - Export/import UI. - Full settings implementation. - Perfect pixel golden tests. - Mobile-first layout. --- ## 7. Target data/read-model shape Codex may adjust exact names to match repo conventions, but preserve the information architecture. ```dart enum BacklogBoardBucket { doNext, needTimeBlock, breakUpFirst, notNow, } class BacklogBoardQueryResult { final String ownerId; final CivilDate localDate; final BacklogBoardSummaryReadModel summary; final List columns; final List projectOptions; } class BacklogBoardColumnReadModel { final BacklogBoardBucket bucket; final String title; final String subtitle; final String accentToken; final int count; final List items; } class BacklogBoardItemReadModel { final String taskId; final String title; final String? subtitle; final String projectId; final String projectName; final String projectColorToken; final int? durationMinutes; final PriorityLevel? priority; final RewardLevel reward; final DifficultyLevel difficulty; final BacklogBoardBucket bucket; final String bucketReason; final DateTime createdAt; final DateTime updatedAt; final bool hasChildren; final List childPreview; final List tags; } class BacklogTaskDetailReadModel { final BacklogBoardItemReadModel item; final String? notes; final String addedLabel; final List tags; final List projectOptions; final List suggestedSlots; } ``` Summary should include: - total tasks, - total estimated minutes, - priority distribution, - project distribution, - duration distribution buckets: `0–30`, `30–60`, `60–120`, `120+`, - planning tip string. Suggested slots should include: - stable id, - local date label, - start/end display text, - duration minutes, - fit label (`Great Fit`, `Okay`, no-fit/conflict if relevant), - fit severity token, - whether it is the primary/default scheduling target. --- ## 8. Block list Execute these files in order: 1. `UI_PLAN_2_BLOCK_01_REPO_SCOPE_AND_ASSETS.md` 2. `UI_PLAN_2_BLOCK_02_BACKLOG_READ_MODELS_AND_METADATA.md` 3. `UI_PLAN_2_BLOCK_03_NAVIGATION_AND_SCREEN_SHELL.md` 4. `UI_PLAN_2_BLOCK_04_BOARD_COLUMNS_AND_CARDS.md` 5. `UI_PLAN_2_BLOCK_05_SEARCH_FILTER_SORT_GROUP.md` 6. `UI_PLAN_2_BLOCK_06_SUMMARY_PANEL.md` 7. `UI_PLAN_2_BLOCK_07_TASK_DETAIL_DRAWER.md` 8. `UI_PLAN_2_BLOCK_08_COMMANDS_CREATE_AND_ACTIONS.md` 9. `UI_PLAN_2_BLOCK_09_TESTING_VALIDATION_HANDOFF.md` --- ## 9. Expected final changed areas Likely changed or added areas: ```text packages/scheduler_core/lib/src/domain/models/entities/task.dart packages/scheduler_core/lib/src/application/application_management/** packages/scheduler_core/lib/src/application/application_commands/** packages/scheduler_core/lib/src/persistence/document_mapping/tasks/** packages/scheduler_core/lib/src/persistence/persistence_contract/fields/tasks/** packages/scheduler_persistence/lib/persistence/repositories/task_repository.dart packages/scheduler_persistence_memory/** packages/scheduler_persistence_sqlite/lib/src/scheduler_db/tables/tasks/tasks.dart packages/scheduler_persistence_sqlite/lib/src/scheduler_db/daos/task_dao.dart packages/scheduler_persistence_sqlite/lib/src/sqlite_repositories/sqlite_task_repository.dart apps/focus_flow_flutter/lib/app/** apps/focus_flow_flutter/lib/controllers/** apps/focus_flow_flutter/lib/models/backlog/** apps/focus_flow_flutter/lib/widgets/backlog/** apps/focus_flow_flutter/lib/widgets/sidebar.dart apps/focus_flow_flutter/lib/theme/** apps/focus_flow_flutter/test/** ``` Do not modify unrelated packages unless tests prove a required boundary update. --- ## 10. Final acceptance criteria The plan is complete when: - Backlog sidebar item opens/renders the Backlog tab and is visually active. - Default Backlog board state closely matches `backlog_board_default.png`. - Selecting `Review Q3 budget` or any task card opens a right-side drawer matching `backlog_task_drawer.png`. - Drawer overlays content without moving columns or summary. - Search/filter/sort/group controls are visible and do not break board state. - Board columns, cards, summary, and drawer are all driven by scheduler/application read models or controller-level display models derived from those read models. - Schedule action uses scheduler application command(s); UI does not compute canonical placement. - New task capture creates backlog tasks through scheduler application command(s). - Push to Someday and Remove are non-destructive domain/application commands, not Flutter-only state deletion. - Tests cover default render, navigation, controls, card selection, drawer close, summary data, and command callbacks. - `flutter analyze` and `flutter test` pass under `apps/focus_flow_flutter`. - Root/package tests touched by domain/persistence changes pass or are explicitly reported if environment prevents full validation.