Wire Backlog nav, Break up, Settings dialog + merge Backlog Board feature #20

Open
pyr0ball wants to merge 26 commits from Circuit-Forge/focus-flow:feat/9-12-13-wire-backlog-nav-and-modal-actions into main
23 changed files with 2532 additions and 54 deletions
Showing only changes of commit d26645affb - Show all commits

View file

@ -1,7 +1,7 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors --> <!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only --> <!-- SPDX-License-Identifier: AGPL-3.0-only -->
# AGENTS.md — Codex Project Rules (SQLiteFirst, July 2026) # AGENTS.md — Codex Project Rules (SQLiteFirst, July 2026)
This document supersedes all previous agent rule files. Treat it as the single source of truth. This document supersedes all previous agent rule files. Treat it as the single source of truth.
@ -10,9 +10,10 @@ This document supersedes all previous agent rule files. Treat it as the single s
## 0. Quickstart for Codex ## 0. Quickstart for Codex
* Blocks live in `Codex Documentation/Current Software Plan/`. * Blocks live in `Codex Documentation/Current Software Plan/`.
* Work strictly in numerical order (Block19  20 … 29). * Work strictly in numerical order unless the active plan explicitly says otherwise.
* Each block contains numbered `XHIGH` / `HIGH` chunks. * Treat each block or named plan as the primary work unit.
* Stop at every `BREAKPOINT` in a chunk; wait for confirmation before continuing. * New or updated plan documents must use blocks of work, implementation steps, tasks, or acceptance checks.
* Stop at any explicit `BREAKPOINT` in the active block or plan; wait for confirmation before continuing.
* Before coding, run `scripts/bootstrap_dev.sh` to set up the local dev DB. * Before coding, run `scripts/bootstrap_dev.sh` to set up the local dev DB.
--- ---
@ -21,13 +22,13 @@ This document supersedes all previous agent rule files. Treat it as the single s
| Element | Rule | | Element | Rule |
|---------|------| |---------|------|
| Local storage | **SQLite via Drift**, schemaVersion 1 | | Local storage | **SQLite via Drift**, schemaVersion 1 |
| Abstraction | Domainonly repository interfaces (`scheduler_persistence`) | | Abstraction | Domain-only repository interfaces (`scheduler_persistence`) |
| Swappable | New adapters must pass repository conformance tests | | Swappable | New adapters must pass repository conformance tests |
| Backup | AES256GCM encrypted SQLite file (`Backup library`, Block24) | | Backup | AES-256-GCM encrypted SQLite file (`Backup library`, Block 24) |
| Migrations | Drift migrations with tests (Block20, Block26) | | Migrations | Drift migrations with tests (Block 20, Block 26) |
No MongoDB runtime in V1. SQLite is the selected V1 implementation database. Keep Drift and database details inside the SQLite persistence adapter; core/domain code must not import database libraries or depend on row shapes.
--- ---
@ -35,15 +36,15 @@ No MongoDB runtime in V1.
1. Interfaces expose domain objects only. 1. Interfaces expose domain objects only.
2. Optimistic `revision` on every mutable save. 2. Optimistic `revision` on every mutable save.
3. Owner scope parameter now for future multiuser. 3. Owner scope parameter now for future multi-user.
4. Adapters implement compareandset; core never overwrites stale revision. 4. Adapters implement compare-and-set; core never overwrites stale revision.
--- ---
## 3. Notification Rules ## 3. Notification Rules
* Use `NotificationAdapter` (Block21). * Use `NotificationAdapter` (Block 21).
* Desktop implementation (Block22), fake adapter for tests. * Desktop implementation (Block 22), fake adapter for tests.
* Core never imports platform APIs directly. * Core never imports platform APIs directly.
--- ---
@ -51,7 +52,7 @@ No MongoDB runtime in V1.
## 4. Backup / Export Rules ## 4. Backup / Export Rules
* Backup: encrypted SQLite (`.sqlite.aes`) via Backup library. * Backup: encrypted SQLite (`.sqlite.aes`) via Backup library.
* Readable exports: JSON + CSV via `ExportController` (Block23). * Readable exports: JSON + CSV via `ExportController` (Block 23).
--- ---
@ -64,16 +65,16 @@ No MongoDB runtime in V1.
| Migration | `test/migration` | Drift schema upgrades | | Migration | `test/migration` | Drift schema upgrades |
| Integration | `test/integration` | full stack InMemory + SQLite + fake notifications | | Integration | `test/integration` | full stack InMemory + SQLite + fake notifications |
CI fails below **80% line coverage**. CI fails below **80% line coverage**.
--- ---
## 6. Dev Scripts (Block27) ## 6. Dev Scripts (Block 27)
| Script | Description | | Script | Description |
|--------|-------------| |--------|-------------|
| `bootstrap_dev.sh` | install deps, create dev DB | | `bootstrap_dev.sh` | install deps, create dev DB |
| `dev.sh` | hotreload desktop run | | `dev.sh` | hot-reload desktop run |
| `test.sh` | all tests + coverage | | `test.sh` | all tests + coverage |
| `package_release.sh` | build OS binaries | | `package_release.sh` | build OS binaries |
@ -83,29 +84,48 @@ integrated.
--- ---
## 6.1 File Hygiene ## 6.1 Code Documentation & File Hygiene
All future project files must include the relevant SPDX metadata for their file All future project files must include the relevant SPDX metadata for their file
format. New Dart files must include file-level Dartdoc library docs and Dartdoc format.
comments for every class, enum, enum value, constructor, method, field, and
top-level declaration. When adding code, keep large feature surfaces organized All new and modified code must be commented or documented in detail while the
under descriptive subfolders instead of expanding flat top-level `src` or app work is being done. Update existing comments and docs whenever functionality,
directories. contracts, invariants, side effects, persistence mappings, scheduling rules, or
error behavior change. Stale comments are treated as incorrect code.
New Dart files must include file-level Dartdoc library docs and Dartdoc comments
for every class, enum, enum value, constructor, method, field, and top-level
declaration. Existing Dart declarations touched by a change must have their
Dartdoc added or updated as part of that same change.
Keep files small and focused. If a file grows to cover multiple responsibilities,
split it into smaller files with clear names rather than expanding a broad
catch-all file. Use increasingly specific folder scopes, ordered from broad
package/feature ownership down to concrete responsibility. Prefer descriptive
folder names that explain the domain area or adapter boundary.
Aim for fewer than 10 files per folder. This is a guideline, not a hard rule:
do not create artificial one-file folders merely to satisfy the count, and do
split crowded folders when the files naturally form smaller responsibility
groups.
--- ---
## 7. Branch, Commit & CI ## 7. Branch, Commit & CI
* Start each new block from `main` on a block branch named * Start each new block or plan from `main` on a dedicated branch named for the
`block-XX-simple-name` (for example, `block-20-sqlite-adapter`). work, such as `block-20-sqlite-adapter` or `plan-backlog-tab`.
* Keep all chunk work for that block on the block branch. * Keep all work for the active block or plan on its dedicated branch.
* Commit every completed chunk before moving to the next chunk or breakpoint. * Commit completed work after it is implemented, documented, and locally
validated.
* Do not leave completed work only in the working tree.
* Use conventional commits (`feat`, `fix`, `docs`, `test`, `refactor`, * Use conventional commits (`feat`, `fix`, `docs`, `test`, `refactor`,
`chore`, `ci`). `chore`, `ci`).
* Do not leave completed chunk work only in the working tree. * When a full plan is complete and no work remains for that plan, rerun the
* When the block is complete and verified, merge the block branch back into required validation. If tests still pass, merge the plan branch back into
`main`. `main`.
* CI matrix: ubuntulatest, windowslatest, macoslatest. * CI matrix: ubuntu-latest, windows-latest, macos-latest.
* `dart analyze` and `dart test` must pass. * `dart analyze` and `dart test` must pass.
--- ---
@ -125,4 +145,4 @@ directories.
--- ---
_Last updated: 2026-06-27_ _Last updated: 2026-07-07_

View file

@ -0,0 +1,120 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 01 — Repo Scope, Guardrails, and Mockup Assets
**Goal:** Prepare the repo for Backlog board implementation without changing product behavior yet.
---
## Block outcome
After this block, Codex has verified repo conventions, copied/registered the mockups for local reference, captured baseline validation, and identified the smallest safe implementation path.
---
## Chunk 1.1 — Read repo instructions and baseline state
### Tasks
1. Read `AGENTS.md` first.
2. Read root `README.md`.
3. Read `apps/focus_flow_flutter/README.md`.
4. Read UI Plan 1 summary and block files under:
- `Codex Documentation/Completed Plans/UI Plan 1 - Compact Today Timeline Mockup/`
5. Inspect current Backlog-related files:
- `apps/focus_flow_flutter/lib/widgets/backlog_pane.dart`
- `apps/focus_flow_flutter/lib/widgets/schedule_components.dart`
- `apps/focus_flow_flutter/lib/controllers/scheduler_read_controller.dart`
- `apps/focus_flow_flutter/lib/controllers/command/scheduler_command_controller_impl.dart`
- `packages/scheduler_core/lib/src/application/application_management/**`
- `packages/scheduler_core/lib/src/scheduling/backlog/**`
6. Confirm that Flutter app code imports only public scheduler APIs.
7. Confirm current tests and expected command names.
### Acceptance criteria
- Codex understands that V1 is SQLite-first and Flutter must not import persistence adapters directly.
- Codex has identified whether domain/persistence changes are needed for notes/tags/remove/someday.
- No code behavior changed in this chunk.
---
## Chunk 1.2 — Place mockup references in the plan folder
### Tasks
1. Ensure the plan folder contains:
- `mockups/backlog_board_default.png`
- `mockups/backlog_task_drawer.png`
2. Add or preserve `mockups/README.md` explaining which image represents which state.
3. Do not store generated image prompt text in code comments.
4. Do not overwrite existing UI Plan 1 mockups.
### Acceptance criteria
- Mockup files are available from the plan folder.
- The default and drawer states are unambiguous.
---
## Chunk 1.3 — Run baseline validation
### Tasks
From repo root:
```sh
dart analyze
dart test
```
From Flutter app:
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```
If environment setup is missing, run the highest-confidence subset and record exact failures.
### Acceptance criteria
- Baseline validation result is known before coding.
- Existing failures are documented separately from new work.
---
## Chunk 1.4 — Create implementation notes for scope boundaries
### Tasks
Create a short working note, either in the block commit message or a temporary implementation checklist, identifying:
1. Which files currently render the sidebar and app shell.
2. Which controller/composition object will own navigation state.
3. Which read-model expansion is required for the board.
4. Which commands already exist and which must be added.
5. Which UI widgets can be reused from UI Plan 1:
- dark theme tokens,
- reward icon,
- difficulty bars,
- selected overlay patterns,
- top-bar button style patterns.
### Acceptance criteria
- Codex has a narrow implementation map before writing new code.
- No speculative large refactors are planned.
BREAKPOINT: Stop here if baseline tests fail in a way that could hide regressions.
---
## Block acceptance criteria
- Repo instructions read.
- Mockup assets placed and documented.
- Baseline validation attempted and recorded.
- No unrelated code changed.

View file

@ -0,0 +1,328 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 02 — Backlog Read Models, Metadata, and Demo Data
**Goal:** Add the application/read-model support needed to render the Backlog board, summary, and drawer from backend-owned data.
---
## Block outcome
After this block, the scheduler/application layer can provide a Backlog board projection with columns, summary statistics, detail metadata, and suggested slot previews. Flutter should not need to invent board grouping or summary counts.
---
## Chunk 2.1 — Audit current backlog API and identify exact extension points
### Tasks
1. Inspect the public export path in `packages/scheduler_core/lib/scheduler_core.dart`.
2. Inspect existing:
- `GetBacklogRequest`
- `BacklogQueryResult`
- `BacklogItemReadModel`
- `BacklogView`
- `BacklogFilter`
- `BacklogSortKey`
- `V1ApplicationManagementUseCases.getBacklog`
3. Decide whether to extend existing types or add board-specific types.
4. Prefer adding board-specific read models if extending existing types would break existing tests or consumers.
### Acceptance criteria
- Existing simple backlog query remains compatible.
- New board query is public through `scheduler_core.dart` if Flutter needs it.
---
## Chunk 2.2 — Add board bucket policy in pure Dart
### Tasks
Add a deterministic policy type in scheduler core, such as:
- `BacklogBoardBucket`
- `BacklogBoardBucketPolicy`
- `BacklogBoardBucketResolution`
Default V1 policy, unless repo docs already define a better one:
1. `notNow`
- task has `BacklogTag.wishlist`, or
- priority is `veryLow`/`low` and not otherwise urgent, or
- duration is missing and task is not ready to schedule.
2. `breakUpFirst`
- duration is `>= 90`, or
- difficulty is `hard`/`veryHard`, or
- task has child previews / parent-child metadata indicating it is already broken down.
3. `needTimeBlock`
- duration is `>= 45`, or
- priority is `high`/`veryHigh`, or
- task is estimated to require focused work.
4. `doNext`
- default for schedule-ready flexible backlog items.
Each resolution must include a short user-facing reason string.
### Acceptance criteria
- Policy is pure Dart.
- Policy is deterministic.
- Unit tests cover all four buckets and tie-breaking precedence.
- No Flutter code duplicates this policy.
---
## Chunk 2.3 — Add board and summary read models
### Tasks
Add read models following repo style. Exact file paths may vary, but keep them under scheduler core application management read models.
Required models:
1. `BacklogBoardQueryResult`
2. `BacklogBoardColumnReadModel`
3. `BacklogBoardItemReadModel`
4. `BacklogBoardSummaryReadModel`
5. `BacklogDistributionReadModel`
6. `BacklogDistributionEntryReadModel`
7. `BacklogChildPreviewReadModel`
8. `BacklogTaskDetailReadModel`
9. `SuggestedSlotReadModel`
10. `ProjectOptionReadModel` if not already available.
Required summary fields:
- total task count,
- total estimated minutes,
- count by priority,
- count by project,
- count and percentage by duration bucket,
- planning tip copy.
Required card fields:
- task id,
- title,
- subtitle/notes preview,
- project id/name/color token,
- duration,
- priority,
- reward,
- difficulty,
- bucket,
- bucket reason,
- created/updated timestamps,
- child previews,
- tag strings.
### Acceptance criteria
- Read models are immutable where repo conventions expect immutability.
- Read models expose display-ready values only where appropriate; do not bury domain objects inside the UI-only result if that would leak unnecessary mutation surface.
- Existing `BacklogQueryResult` tests remain passing.
---
## Chunk 2.4 — Add notes and freeform tags metadata if absent
### Tasks
Current `Task` appears to lack freeform notes and general tags. Add the minimal V1 metadata needed by the drawer:
- `String? notes`
- `Set<String> tags` or a small `TaskTag` value object if repo style requires validation.
Validation rules:
- notes may be null or non-empty trimmed string; blank notes normalize to null if the repo has normalization helpers.
- tag labels are trimmed.
- blank tags are rejected or filtered consistently.
- duplicate tags collapse case-insensitively if repo conventions support that; otherwise preserve normalized unique strings.
- impose a safe maximum count/length consistent with existing persistence payload guards.
Update all affected layers:
- `Task` constructor and `copyWith`.
- quick capture/create paths where tags/notes are supported.
- document mapping.
- persistence contract fields.
- SQLite task table and DAO/repository mapping.
- in-memory repository if it stores full domain objects.
- tests.
If adding persistence migration is required, keep it within SQLite/Drift V1 conventions and add migration tests if existing schema tooling supports them.
### Acceptance criteria
- Existing tasks still construct without notes/tags.
- Notes/tags round-trip through repository mappings.
- Flutter receives notes/tags from public read models.
- No direct SQLite/Drift import leaks into Flutter.
BREAKPOINT: Stop here if notes/tags would require a broad migration beyond the current plan. Ask Ashley whether drawer tags should be read-only placeholders or true V1 metadata.
---
## Chunk 2.5 — Add board query use case
### Tasks
Add a method to `V1ApplicationManagementUseCases`, such as:
```dart
Future<ApplicationResult<BacklogBoardQueryResult>> getBacklogBoard(
GetBacklogBoardRequest request,
)
```
Request should include:
- `ApplicationOperationContext context`,
- selected `CivilDate localDate` for slot suggestions,
- optional search text,
- optional filters,
- sort key,
- group mode.
Behavior:
1. Load backlog tasks through repositories.
2. Load projects for display names/colors.
3. Load child relationships/previews as needed.
4. Apply search/filter/sort/group using application/core policies.
5. Resolve board bucket for every item.
6. Build summary from the same filtered item set.
7. Return stable column order: Do Next, Need Time Block, Break Up First, Not Now.
### Acceptance criteria
- Query does not mutate repositories.
- Query returns all four columns even when empty.
- Counts match filtered item set.
- Summary and board columns use the same source task list.
- Unit tests cover empty backlog, default seed-like backlog, search/filter, and summaries.
---
## Chunk 2.6 — Add task detail query and suggested slot preview
### Tasks
Add a detail query method, such as:
```dart
Future<ApplicationResult<BacklogTaskDetailReadModel>> getBacklogTaskDetail(
GetBacklogTaskDetailRequest request,
)
```
Behavior:
1. Load selected backlog task.
2. Load project options.
3. Load notes/tags/duration/reward/difficulty/project.
4. Generate suggested slots without mutating state.
5. Suggested slots should respect locked/required time by using scheduler/application services or cloned scheduler input.
6. If exact slot-specific scheduling is not supported, return preview rows and mark which one corresponds to `next available`.
Suggested slot labels for demo should support:
- `Great Fit`
- `Okay`
- no-fit or conflict copy if applicable.
### Acceptance criteria
- Detail query returns not found if selected task no longer exists.
- Suggested slots do not write snapshots/tasks.
- Missing duration returns an empty suggestions list plus a display reason instead of crashing.
- Unit tests prove the query is read-only.
---
## Chunk 2.7 — Expand demo seed data for Backlog board
### Tasks
Create or extend app demo seed files under `apps/focus_flow_flutter/lib/app/demo/`.
Seed must include enough data to match the mockup:
- 24 backlog tasks total.
- Column counts:
- Do Next: 5
- Need Time Block: 6
- Break Up First: 6
- Not Now: 5
- Projects:
- Home: 5
- Work: 8
- Personal: 5
- Learning: 4
- Side Project: 2
- Priorities:
- High: 7
- Medium: 9
- Low: 8
- Total estimated time: 12h 15m.
- Include visible mockup tasks:
- Reply to 3 emails
- Update project status
- Schedule dentist appt
- Clean up downloads folder
- Plan tomorrow
- Review Q3 budget
- Plan next week
- Define weekly goals
- Time block schedule
- Organize kitchen drawers
- Build analytics dashboard
- Write marketing strategy
- Complete online course
- Module 1: Foundations
- Module 2: Deep Dive
- Module 3: Practice
- Learn guitar
- Start YouTube channel
- Travel to Japan
- Home office upgrade
- Read 2 books
- `Review Q3 budget` must have:
- duration 60 min,
- Work project,
- High priority,
- reward 3/5 equivalent,
- difficulty 2/5 equivalent,
- notes shown in drawer,
- tags `finance` and `review`,
- suggested slots matching the drawer mockup labels.
The remaining 3 tasks may be seed-only hidden lower in scroll or included below the fold.
### Acceptance criteria
- Seed data is domain/application data, not a hardcoded widget list.
- Default board can render from public read models.
- Summary totals match the mockup.
---
## Block acceptance criteria
- Public application/read models can produce the Backlog board, summary, and detail drawer data.
- Notes/tags support is either implemented end-to-end or explicitly deferred at the breakpoint with Ashleys approval.
- Core/application tests cover bucket policy, summary, detail, and read-only suggested slots.
- Flutter code still does not know scheduler internals.
## Validation after block
```sh
dart analyze
dart test
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,162 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 03 — Navigation and Backlog Screen Shell
**Goal:** Add the Backlog tab route/screen shell and make the sidebar navigation render `Backlog` as active.
---
## Block outcome
After this block, the app can switch between the existing Today screen and the new Backlog screen shell. The Backlog shell matches the finalized header/control layout but may still use placeholder board content until later blocks fill it in.
---
## Chunk 3.1 — Introduce app section navigation state
### Tasks
1. Add an app-level enum/model such as `FocusFlowSection` with values:
- `today`
- `backlog`
- `projects`
- `reports`
- `settings`
2. Move the currently hardcoded active `Today` sidebar state into `FocusFlowHome` or a small shell controller.
3. Update `Sidebar` to accept:
- `activeSection`,
- `onSectionSelected` callback.
4. Keep Projects/Reports/Settings visible. They may switch to placeholder empty screens or remain inert, but Today and Backlog must work.
### Acceptance criteria
- Today still renders as before when active.
- Backlog nav item can become active.
- Sidebar widget tests can verify active styling for Today and Backlog.
---
## Chunk 3.2 — Add Backlog screen controller skeleton
### Tasks
Add controller/read-state classes under app conventions, for example:
```text
apps/focus_flow_flutter/lib/controllers/backlog_board_controller.dart
apps/focus_flow_flutter/lib/models/backlog/backlog_board_screen_data.dart
```
Controller responsibilities:
- load `BacklogBoardQueryResult`,
- track loading/ready/empty/failure states,
- track selected task id for drawer,
- track search/filter/sort/group UI values,
- request detail data for selected task,
- expose reload method after commands.
Avoid canonical scheduling state in the controller.
### Acceptance criteria
- Controller can load the demo/app composition read model.
- Controller has no direct persistence dependency.
- Selection is UI-local and not persisted.
---
## Chunk 3.3 — Extend composition factory
### Tasks
Update `DemoSchedulerComposition` or the current app composition to create:
- Backlog board controller,
- Backlog command controller if needed,
- any date/context provider needed for suggestions.
Behavior:
- Use same owner/timezone/date context style as Today.
- Reuse existing in-memory application store seeded by domain objects.
- Ensure Today and Backlog share the same underlying demo store so commands can refresh both later.
### Acceptance criteria
- Backlog can load without constructing a separate unrelated fake app state.
- Existing Today seed still works.
---
## Chunk 3.4 — Build Backlog screen shell
### Tasks
Create `BacklogBoardScreen` or equivalent under a feature folder such as:
```text
apps/focus_flow_flutter/lib/widgets/backlog/backlog_board_screen.dart
```
Screen sections:
1. Header title/subtitle row.
2. Header mode/settings row.
3. Search/filter/sort/group/new-task control row.
4. Content body with board region and summary panel slot.
5. Drawer overlay slot above content.
Use mockup spacing:
- main left/top padding close to current app gutter,
- title around 3236 px,
- dark navy/black background,
- controls height around 4044 px,
- right summary panel around 285300 px wide.
### Acceptance criteria
- Backlog shell visually resembles the default mockup header/control skeleton.
- Summary panel area exists but may display placeholder data until Block 6.
- Board area exists but may display placeholder columns until Block 4.
- No white Material surfaces.
---
## Chunk 3.5 — Implement loading/empty/error states
### Tasks
Use existing `ReadStateView` patterns only if they can match the mockup. Otherwise build Backlog-specific states:
- Loading: subtle centered progress or skeleton columns.
- Empty: calm empty board with new-task CTA.
- Failure: compact error panel with retry.
Do not show blame language.
### Acceptance criteria
- Controller state maps to UI states.
- Tests can render loading, empty, failure, and ready states.
BREAKPOINT: Stop here for visual review if the shell deviates from the default mockup header/sidebar layout.
---
## Block acceptance criteria
- Backlog nav is functional.
- Backlog shell renders without board details.
- Today screen remains functional and visually unchanged except sidebar now supports active state.
- App still passes Flutter analyze/test.
## Validation after block
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,231 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 04 — Board Columns and Task Cards
**Goal:** Render the four finalized Backlog board columns and task cards from Backlog board read models.
---
## Block outcome
After this block, the default Backlog board displays all four columns, counts, visible tasks, card metadata, child previews, and add-task footers.
---
## Chunk 4.1 — Add board visual tokens
### Tasks
Add or extend Flutter visual tokens for Backlog-specific accents:
- Do Next green.
- Need Time Block orange/yellow.
- Break Up First purple.
- Not Now blue.
- High priority red flag.
- Medium priority yellow/orange flag.
- Low priority green flag.
- Project dot colors matching seed projects.
- Tag chip colors for drawer later.
Prefer central token/mapping files over inline colors.
### Acceptance criteria
- Colors are centralized.
- Existing Today color mappings remain unchanged.
- No one-off hardcoded color scatter in card widgets.
---
## Chunk 4.2 — Build column header widget
### Tasks
Create a reusable `BacklogBoardColumn` and `BacklogColumnHeader`.
Header content:
- bucket icon,
- bucket title,
- count pill,
- add icon button on the far right,
- subtitle line.
Icon suggestions:
- Do Next: check circle.
- Need Time Block: clock.
- Break Up First: target/radio button/segmented circle.
- Not Now: cloud outline.
### Acceptance criteria
- Header count is read from `BacklogBoardColumnReadModel.count`.
- Header add icon calls the same create-task flow as the footer with bucket preselection if available.
- Header does not compute bucket counts in Flutter.
---
## Chunk 4.3 — Build board layout
### Tasks
1. Render columns in stable order:
- Do Next
- Need Time Block
- Break Up First
- Not Now
2. Use horizontal layout at desktop width.
3. Make board horizontally scrollable if width becomes constrained.
4. Make column card stacks vertically scrollable or allow the whole board body to scroll, whichever best matches current app ergonomics.
5. Keep the summary panel fixed on the right in default state.
Sizing guidance at 1672 px mockup width:
- board starts after left content gutter,
- 4 columns fit before summary panel,
- column width around 270300 px,
- column gap around 812 px,
- column border/fill tinted by bucket accent.
### Acceptance criteria
- Four columns are visible at mockup-like desktop width.
- Board can be used at narrower desktop widths without overflow exceptions.
- Summary panel does not overlap default board state.
---
## Chunk 4.4 — Build backlog task card widget
### Tasks
Create `BacklogTaskCard` with:
- leading checkbox/selection square,
- title,
- subtitle/notes preview,
- metadata row:
- duration icon and minutes,
- project color dot/name,
- priority flag/label,
- footer:
- difficulty label and five bars,
- reward label and solid reward icons.
Use existing `DifficultyBars` and reward icon widgets where possible. If existing widgets are Today-specific, extract reusable versions without breaking Today.
Difficulty requirements:
- exactly five bars,
- `veryEasy` = 1 filled,
- `easy` = 2 filled,
- `medium` = 3 filled,
- `hard` = 4 filled,
- `veryHard` = 5 filled,
- unfilled bars are outline/subtle.
Reward requirements:
- display 15 solid sparkle/bolt-style marks matching the mockup language,
- no line-only star outlines.
### Acceptance criteria
- Card content is read from `BacklogBoardItemReadModel`.
- Card supports selected state with magenta outline.
- Card click selects task and opens drawer in Block 7.
- Card does not mutate task status by itself.
---
## Chunk 4.5 — Build child preview card section
### Tasks
For tasks with child previews, render nested child rows inside the parent card, as shown under:
- `Plan next week`
- `Complete online course`
Child row content:
- checkbox-like icon,
- child title,
- optional duration at right.
Interaction for this block:
- Child rows may be non-interactive or select the parent unless a public child-detail model already exists.
- Do not implement child completion from the Backlog board unless command wiring is explicitly available and tested.
### Acceptance criteria
- Parent card remains visually coherent with child preview rows.
- Child previews come from read model, not title parsing.
- No scheduling/child completion rules are duplicated in Flutter.
---
## Chunk 4.6 — Add column footer Add Task buttons
### Tasks
Footer content:
- `+ Add task`, colored by bucket accent.
Behavior for this block:
- Calls a callback with intended bucket.
- Actual create drawer/command wiring happens in Block 8.
### Acceptance criteria
- Footer is visible in every column.
- Footer does not throw when pressed before Block 8 wiring; it can open a placeholder or no-op with a TODO callback in tests.
---
## Chunk 4.7 — Tune board visuals against default mockup
### Tasks
Tune:
- background fills,
- border opacities,
- column corner radius,
- card height,
- card vertical spacing,
- title and metadata font sizes,
- count pill styling,
- icon sizes,
- card selected/hover states.
### Acceptance criteria
- Default board content closely matches `mockups/backlog_board_default.png`.
- Visible mockup tasks are present in the expected columns.
- No white surfaces or accidental Material default cards.
BREAKPOINT: Stop here for visual review if card density or column spacing is substantially off.
---
## Block acceptance criteria
- Backlog board renders from read models.
- All four columns, counts, visible task cards, child previews, difficulty bars, reward icons, and add footers are present.
- Board layout is responsive enough for desktop width changes.
- No domain mutations happen from basic card rendering.
## Validation after block
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,189 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 05 — Search, Filter, Sort, Group, and Mode Controls
**Goal:** Implement the Backlog top controls shown in the finalized default mockup with safe, deterministic behavior.
---
## Block outcome
After this block, the Backlog screen has working search/filter/sort/group controls that reload or transform the Backlog board without duplicating scheduling rules.
---
## Chunk 5.1 — Search field
### Tasks
Add search field matching the mockup:
- leading search icon,
- placeholder `Search backlog...`,
- dark outlined field,
- clear affordance when text is non-empty if it fits cleanly.
Behavior:
- Debounce user input lightly or trigger search on change if current data size is small.
- Search across title, subtitle/notes preview, project name, and tags.
- Prefer passing `searchText` into the board query so search is part of the read-model request.
### Acceptance criteria
- Typing filters cards and updates summary counts.
- Clearing search restores all tasks.
- Search does not alter persisted task data.
---
## Chunk 5.2 — Filter menu
### Tasks
Implement `Filters` button and popover/menu.
Minimum filters:
- priority: High, Medium, Low,
- project,
- duration bucket,
- bucket/column,
- missing duration,
- no reward set if existing backlog filter supports it.
Behavior:
- Multi-select where useful.
- Apply and clear controls.
- Active filter count may be shown as a small badge if it does not clutter the mockup.
- Filter state should update board columns and summary from the same result set.
### Acceptance criteria
- Filter button opens a dark popover.
- Applying filters updates columns and summary.
- Clearing filters restores default board.
- Filter logic lives in application read policy or safe query layer, not widget-only scheduling logic.
---
## Chunk 5.3 — Sort dropdown
### Tasks
Implement `Sort: Custom` dropdown.
Sort options:
- Custom/default.
- Priority.
- Reward vs Effort.
- Age.
- Project.
- Times Pushed if available.
- Duration if added to board sorting.
Behavior:
- Sort applies inside each bucket by default.
- Do not reorder bucket columns.
- Stable tie-breaker preserves source/read-model order.
### Acceptance criteria
- Sort selection updates card order.
- `Custom` default matches mockup seed ordering.
- Sort state is visible in the control label.
---
## Chunk 5.4 — Group dropdown
### Tasks
Implement `Group: None` dropdown.
Group options:
- None.
- Project.
- Priority.
- Duration.
Behavior:
- `None` is default and matches mockup.
- Non-none group mode adds compact section dividers inside each column or transforms card ordering only if section dividers are visually too disruptive.
- Summary panel remains based on filtered item set, not group sections.
### Acceptance criteria
- Group dropdown opens and changes state.
- Group none returns the exact default visual organization.
- No overflow or large layout jump when grouping.
---
## Chunk 5.5 — Compact/Board toggle and Settings button
### Tasks
Implement the upper-right controls:
- `Compact` segment.
- `Board` segment active.
- `Settings` button.
Behavior:
- Board is active by default.
- If an existing compact backlog list can be safely reused, clicking Compact may swap to that list. Otherwise, keep Compact inert for this plan and document it in the widget callback TODO.
- Settings remains visible and inert unless there is an existing settings screen.
### Acceptance criteria
- Toggle visually matches mockup.
- Board remains active by default.
- Pressing Compact/Settings does not throw.
- Tests assert Board selected state.
---
## Chunk 5.6 — New Task button shell
### Tasks
Add magenta `+ New Task` button with trailing chevron.
Behavior for this block:
- Button calls a callback or opens a placeholder drawer shell.
- Full create task wiring happens in Block 8.
- Dropdown chevron may later expose quick destination choices; do not implement a broad menu unless already designed.
### Acceptance criteria
- Button matches the mockup visually.
- Button has a stable key for tests.
- Button press is safe before full Block 8 wiring.
BREAKPOINT: Stop here if control behavior requires unresolved product decisions about compact mode or filter semantics.
---
## Block acceptance criteria
- Search/filter/sort/group controls are present and safe.
- Default state matches mockup.
- Interactions update or preserve board data predictably.
- No scheduling rules are duplicated in Flutter.
## Validation after block
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,176 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 06 — Backlog Summary Panel
**Goal:** Implement the right-side default Backlog summary panel from the finalized mockup.
---
## Block outcome
After this block, the default Backlog state includes a data-driven summary panel with totals, distributions, duration donut, and planning tip.
---
## Chunk 6.1 — Build summary panel structure
### Tasks
Create `BacklogSummaryPanel` under the backlog feature widgets.
Panel sections:
1. Header:
- sparkle icon,
- `Backlog summary`,
- collapse chevron.
2. Totals:
- total tasks,
- total estimated time.
3. Priority distribution.
4. Project distribution.
5. Duration distribution.
6. Planning tip card.
### Acceptance criteria
- Panel consumes `BacklogBoardSummaryReadModel`.
- No summary value is hardcoded in the widget.
- Panel aligns to the right of the default board layout.
---
## Chunk 6.2 — Totals and distribution rows
### Tasks
Implement reusable compact distribution rows:
- icon/dot/flag at left,
- label,
- count at right.
Priority rows:
- High: red flag.
- Medium: yellow flag.
- Low: green flag.
Project rows:
- colored dot.
- project name.
- count.
### Acceptance criteria
- Distribution rows match mockup density.
- Counts come from summary read model.
- Project colors use centralized visual token mapping.
---
## Chunk 6.3 — Duration donut chart
### Tasks
Implement a small donut chart using Flutter painting, not external chart dependencies unless already present.
Segments:
- `030 min`
- `3060 min`
- `60120 min`
- `120+ min`
Behavior:
- Use read-model percentages/counts.
- Show legend at right with count and percentage.
- Handle zero-task state gracefully.
### Acceptance criteria
- Donut is visually similar to mockup.
- Widget does not crash for empty or all-zero distribution.
- Tests can find legend labels/counts.
---
## Chunk 6.4 — Planning tip card
### Tasks
Render planning tip:
- sparkle icon,
- title `Planning tip`,
- copy: `Pick 24 tasks for today. Keep it realistic and leave space for focus.`
The initial tip may be static in read model. Later plans can make tips dynamic.
### Acceptance criteria
- Tip card matches dark glass styling.
- Text uses calm product language.
---
## Chunk 6.5 — Collapse behavior
### Tasks
Implement chevron behavior:
- Expanded by default.
- Clicking collapse hides body sections and leaves a compact header or narrow rail if it fits the design.
- Collapsed state is UI-local only.
If collapse visual is not in mockup beyond chevron, simple body hide is enough.
### Acceptance criteria
- Collapse/expand works.
- Board widens or summary area reduces only in default summary mode; drawer overlay behavior remains unchanged.
- No persisted state change.
---
## Chunk 6.6 — Tune panel visuals
### Tasks
Tune:
- panel width,
- border opacity,
- header spacing,
- section dividers,
- row heights,
- donut size,
- planning tip background.
### Acceptance criteria
- Panel closely matches `mockups/backlog_board_default.png`.
- At mockup width, panel is fully visible and does not scroll independently unless content exceeds height.
BREAKPOINT: Stop here for visual review if donut or summary spacing substantially differs from the mockup.
---
## Block acceptance criteria
- Default Backlog screen includes summary panel.
- All panel values come from read model.
- Collapse state works.
- Search/filter changes update summary values.
## Validation after block
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,272 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 07 — Right-Anchored Task Detail Drawer
**Goal:** Implement the selected-task drawer shown in the finalized drawer mockup.
---
## Block outcome
After this block, selecting a backlog card opens a right-side drawer that overlays the board without shifting any existing elements.
---
## Chunk 7.1 — Add selection and detail loading behavior
### Tasks
1. Store selected task id in `BacklogBoardController`.
2. On card click:
- set selected task id,
- request `BacklogTaskDetailReadModel`,
- keep current board data unchanged.
3. If another card is selected while drawer is open, replace detail content without closing first.
4. If selected task disappears after a command/reload, close drawer and show quiet status if appropriate.
### Acceptance criteria
- Card click opens drawer.
- Selecting another card changes drawer content.
- Selection is UI-local.
- Detail query failures are rendered as drawer-local error, not full screen crash.
---
## Chunk 7.2 — Implement drawer overlay anchoring
### Tasks
Use a `Stack` at the Backlog screen body level.
Drawer layout:
```dart
Positioned(
top: 0,
right: 0,
bottom: 0,
width: drawerWidth,
child: BacklogTaskDrawer(...),
)
```
Sizing:
- Preferred width: 460470 px.
- Clamp to available width minus safe left minimum for small desktop windows.
- Drawer height fills content area inside app frame.
Behavior:
- Do not shift columns or summary panel.
- Do not use a heavy scrim.
- Board remains visible behind/left of drawer.
- Close icon closes drawer.
- Escape key may close drawer if easy and testable.
### Acceptance criteria
- Drawer overlays content without moving board columns.
- No layout jump occurs when drawer opens/closes.
- Drawer remains attached to right edge during window resize.
---
## Chunk 7.3 — Drawer header
### Tasks
Header content:
- bucket/status icon with accent color,
- selected task title,
- sparkle icon at right of title area if available,
- close icon button in top-right,
- subtitle/description,
- age metadata such as `Added 2h ago (Jul 3, 2024 • 6:17 AM)`.
Behavior:
- Metadata should be display-ready from read model or a UI formatter that only formats dates/times.
- Title wraps at sensible line count.
### Acceptance criteria
- `Review Q3 budget` header matches drawer mockup for seeded task.
- Close button works.
---
## Chunk 7.4 — Notes, project, and tags sections
### Tasks
Render:
1. Notes panel:
- label `Notes`,
- notes body.
2. Project selector:
- label `Project`,
- colored dot,
- project name,
- dropdown chevron.
3. Tags section:
- label `Tags`,
- tag chips,
- add button.
Behavior:
- If update commands exist by this block, project/tags can be editable.
- If update commands are deferred to Block 8, controls should call placeholder callbacks and not mutate state.
- Do not invent Flutter-only persisted tags.
### Acceptance criteria
- Seeded `finance` and `review` chips display for `Review Q3 budget`.
- Empty notes/tags render calm empty states.
- Project and tag values come from detail read model.
---
## Chunk 7.5 — Metric tiles
### Tasks
Render three tiles:
1. Duration:
- clock icon,
- `60 min`,
- `Estimated`.
2. Reward:
- reward icon,
- `3/5`,
- `Satisfying` or equivalent label.
3. Difficulty:
- difficulty icon,
- `2/5`,
- `Easy` or equivalent label.
Use centralized mapping helpers for reward/difficulty numeric labels.
### Acceptance criteria
- Tiles match drawer mockup density.
- Values update for different selected tasks.
- Missing values render `Not set` without throwing.
---
## Chunk 7.6 — Suggested slots section
### Tasks
Render:
- section title `Suggested slots`,
- `View day` button,
- rows with calendar icon, date label, time range, duration, fit badge, chevron.
Rows must support:
- green `Great Fit`,
- yellow/orange `Okay`,
- future/tomorrow labels.
Behavior:
- Rows may set a selected suggested slot id if slot-specific scheduling is implemented in Block 8.
- Otherwise rows are preview-only and pressing primary `Schedule` uses backend next-available command.
### Acceptance criteria
- Seeded drawer shows three suggested slot rows similar to mockup.
- Missing duration or no-fit returns a calm explanation.
- Slot rows are generated by read model/scheduler preview, not widget-only calculations.
---
## Chunk 7.7 — Drawer action buttons
### Tasks
Render action buttons:
- Primary magenta `Schedule`.
- Secondary `Break Up`.
- Full-width `Push to Someday`.
- Full-width `Remove`.
Behavior in this block:
- Buttons call callbacks supplied by parent.
- Actual commands are finalized in Block 8.
- Disable only when the read model explicitly says the action is unavailable. Do not make them look disabled because wiring is pending; instead route callbacks safely.
### Acceptance criteria
- Buttons visually match drawer mockup.
- Button presses do not throw before command wiring.
- Stable keys exist for widget tests.
---
## Chunk 7.8 — Selected card styling behind drawer
### Tasks
When selected:
- card gets magenta border/outline,
- checkbox/leading control reflects selected/focused state if visually needed,
- underlying board remains scrollable if drawer does not cover that area.
### Acceptance criteria
- `Review Q3 budget` selected card matches drawer mockup highlight.
- Closing drawer clears selected styling.
---
## Chunk 7.9 — Drawer polish and accessibility
### Tasks
Polish:
- drawer background, border, radius,
- internal section spacing,
- text sizes,
- button heights,
- hover/focus states,
- semantic labels for close and action buttons.
### Acceptance criteria
- Drawer closely matches `mockups/backlog_task_drawer.png`.
- Drawer is keyboard reachable enough for desktop tests.
- No white surfaces.
BREAKPOINT: Stop here for visual review if drawer is not right-anchored or if it shifts the board.
---
## Block acceptance criteria
- Clicking a task opens the right drawer.
- Drawer overlays without shifting layout.
- Drawer content is data-driven.
- Close behavior works.
- Selected card styling works.
## Validation after block
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,267 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 08 — Commands, New Task, Create/Edit Metadata, and Drawer Actions
**Goal:** Wire the Backlog tabs visible actions to application commands while preserving backend/domain authority.
---
## Block outcome
After this block, `New Task`, `Add task`, `Schedule`, `Break Up`, `Push to Someday`, `Remove`, and metadata edits are either implemented through application commands or explicitly left as safe non-mutating placeholders with tests and TODO notes.
---
## Chunk 8.1 — Add/update task metadata command
### Tasks
Add an application command/use case such as `updateBacklogTaskDetails` or general `updateTaskDetails`.
Input fields:
- task id,
- expected updated timestamp/revision if available,
- title,
- notes,
- project id,
- duration minutes,
- priority,
- reward,
- difficulty,
- tags,
- backlog tags.
Behavior:
- Validate task exists.
- Validate stale update guard using existing `expectedUpdatedAt` style or repository revision style.
- Preserve schedule/source-of-truth rules.
- For backlog tasks, metadata changes should not schedule the task.
- For planned tasks, do not use this command from Backlog UI.
### Acceptance criteria
- Metadata update command is tested.
- Notes/tags/project edits persist through repository layer.
- Flutter calls command controller, not repositories.
---
## Chunk 8.2 — New Task drawer/create flow
### Tasks
Implement reusable task editor drawer/sheet for Backlog create mode.
Open from:
- top `+ New Task`,
- column header add icon,
- column footer `+ Add task`.
Fields:
- title required,
- notes optional,
- project optional/default Inbox or selected bucket/project default,
- duration optional,
- priority default Medium,
- reward optional/not set,
- difficulty optional/not set,
- tags optional.
Behavior:
- Create through `quickCaptureToBacklog` or a new richer create command if notes/tags are required.
- Do not force scheduling.
- On success:
- close create drawer,
- refresh Backlog board,
- show quiet success text if existing command banner pattern supports it.
- Empty title validation stays inline and preserves input.
### Acceptance criteria
- `New Task` creates a backlog task.
- Column Add Task can preselect or hint bucket defaults without writing a fake bucket field.
- Created task appears in board after refresh according to bucket policy.
---
## Chunk 8.3 — Schedule selected backlog task
### Tasks
Wire drawer `Schedule` to existing command:
```dart
scheduleBacklogItem(
taskId: selectedTaskId,
durationMinutes: optionalDurationIfEdited,
expectedUpdatedAt: selectedUpdatedAt,
)
```
Behavior:
- If duration is missing, focus/show duration requirement instead of discarding task.
- If scheduling succeeds:
- task leaves Backlog board if its status changes to planned,
- drawer closes,
- summary and counts refresh,
- command status shows calm success.
- If no fit/conflict:
- keep task in Backlog,
- show drawer-local or command-banner explanation.
### Acceptance criteria
- UI does not choose canonical time slot by itself.
- Schedule command handles stale updates.
- Tests verify success callback and failure display with fake command controller.
---
## Chunk 8.4 — Break Up flow
### Tasks
Use existing `breakUpTask` command if possible.
Minimum V1 UI:
- Pressing `Break Up` opens a focused child-task drawer/dialog.
- User can add at least two child rows with title and optional duration.
- Saving calls `breakUpTask` with `ApplicationChildTaskDraft` entries.
- On success:
- refresh board,
- selected detail updates or drawer closes,
- child previews appear under parent.
If full child-entry UI is too large for this plan, implement a safe placeholder that opens a drawer-local message: `Break-up flow is coming next` and do not mutate state. Only use placeholder if Ashley approves at breakpoint.
### Acceptance criteria
- No child tasks are created in Flutter-only state.
- Break-up command path is covered by tests if implemented.
BREAKPOINT: Stop before using a placeholder for Break Up. Ask Ashley whether to include full child-entry UI now or defer.
---
## Chunk 8.5 — Push to Someday command
### Tasks
Add/wire application command such as `pushBacklogTaskToSomeday`.
Behavior:
- Task remains backlog.
- Add `BacklogTag.wishlist` or equivalent someday metadata.
- Clear any selected scheduling preview if needed.
- Refresh board so task appears in `Not Now`.
- Record task activity/statistics if existing lifecycle service supports it.
### Acceptance criteria
- Command is tested.
- It is non-destructive.
- It does not schedule or delete the task.
- UI refreshes board and drawer content.
---
## Chunk 8.6 — Remove/archive command
### Tasks
Add/wire application command such as `removeBacklogTask`.
Assumed behavior:
- non-destructive archive from active backlog,
- prefer `TaskStatus.noLongerRelevant` unless repo conventions define `cancelled` or a separate archive flag,
- require confirmation before applying,
- close drawer on success,
- refresh board/summary.
Confirmation copy:
- Title: `Remove from Backlog?`
- Body: `This hides the task from active planning. It will not schedule anything.`
- Actions: `Cancel`, `Remove`.
### Acceptance criteria
- Remove does not physically delete repository data unless Ashley explicitly changed the product decision.
- User can cancel confirmation.
- Success refreshes the board.
---
## Chunk 8.7 — Project and tags inline edits
### Tasks
Once update command exists:
- Project dropdown updates project id.
- Tag add button opens small input or menu.
- Tag chip can be removed if design supports it.
- Use optimistic UI only if command result can reconcile cleanly; otherwise reload after save.
If inline autosave feels too chatty, use a small `Save changes` action inside the drawer only when fields are dirty. The mockup does not show a save button, so prefer careful inline save with visible running/success/failure states.
### Acceptance criteria
- Project/tags update through command controller.
- Stale/failure result is visible and does not lose local input.
- Tests cover project/tag command callback.
---
## Chunk 8.8 — Command state feedback
### Tasks
Add a Backlog command status pattern:
- running state near top controls or drawer action area,
- success state quiet and auto-dismissable if existing app pattern supports it,
- failure state calm and specific.
Messages:
- `Added to Backlog.`
- `Scheduled.`
- `Kept in Backlog — no fitting slot found.`
- `Moved to Someday.`
- `Removed from active Backlog.`
### Acceptance criteria
- Failures do not crash screen.
- User input is not lost on validation failure.
- Command controller reloads board on success.
---
## Block acceptance criteria
- Visible Backlog actions either work through application commands or have explicit Ashley-approved deferral.
- Create/schedule/someday/remove paths are implemented and tested.
- Break Up is implemented or explicitly deferred at its breakpoint.
- No Flutter widget mutates domain state directly.
## Validation after block
```sh
dart analyze
dart test
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

View file

@ -0,0 +1,263 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 Block 09 — Testing, Validation, Polish, and Handoff
**Goal:** Complete tests, final visual polish, validation commands, and handoff notes for the Backlog tab.
---
## Block outcome
After this block, the Backlog board implementation is tested, validated, documented, and ready for Ashley review or the next implementation plan.
---
## Chunk 9.1 — Core/application tests
### Tests
Add or update tests for:
1. Backlog bucket policy:
- Do Next,
- Need Time Block,
- Break Up First,
- Not Now,
- precedence/tie-breaking.
2. Backlog board query:
- empty state,
- 24-task seed-like board,
- search,
- filters,
- sort,
- group none/default,
- summary totals.
3. Backlog detail query:
- selected task detail,
- notes/tags/project metadata,
- suggested slots,
- missing duration/no-fit.
4. Commands:
- create backlog task,
- update metadata,
- schedule backlog item,
- push to someday,
- remove/archive,
- break up if implemented.
### Acceptance criteria
- Tests are deterministic.
- Tests do not require Flutter.
- Tests do not depend on wall-clock time without injected context.
---
## Chunk 9.2 — Flutter widget tests
### Tests
Add tests under `apps/focus_flow_flutter/test/` that verify:
1. Sidebar renders `Backlog` active on Backlog screen.
2. Default Backlog screen shows:
- `Backlog`,
- `24 tasks`,
- search placeholder,
- `Filters`,
- `Sort: Custom`,
- `Group: None`,
- `New Task`,
- all four column names,
- `Backlog summary`.
3. Visible seed cards render in expected columns.
4. `Review Q3 budget` card opens drawer.
5. Drawer shows:
- title,
- notes,
- Work project,
- `finance`,
- `review`,
- `60 min`,
- reward/difficulty labels,
- suggested slots,
- all action buttons.
6. Close button closes drawer and clears selected styling.
7. Search narrows visible cards and updates state.
8. Filter/sort/group menus open without throwing.
9. New Task opens create drawer; empty title validation works.
10. Command callbacks are invoked for Schedule/Someday/Remove using fakes/mocks.
### Acceptance criteria
- Widget tests avoid brittle pixel assertions.
- Stable keys are used for important controls.
- Tests remain readable and scoped.
---
## Chunk 9.3 — Forbidden import and boundary tests
### Tasks
Update or preserve `test/forbidden_imports_test.dart` so app still cannot import:
- `scheduler_core/src`,
- Drift/SQLite adapters,
- backup/export internals,
- notification platform internals,
- direct OS APIs for this UI slice.
### Acceptance criteria
- Boundary test passes.
- Any new controller/widget files are covered by forbidden import scan.
---
## Chunk 9.4 — Responsive and overflow validation
### Tasks
Manually or via widget tests inspect Backlog layout at widths:
- 1672 px reference width,
- 1440 px,
- 1280 px,
- 1100 px if supported.
Expected behavior:
- desktop reference matches mockup closely,
- narrower widths use horizontal board scroll or reduce column widths without overflow,
- drawer remains anchored right,
- drawer never shifts board elements,
- summary can collapse or be hidden below a sensible width if needed.
### Acceptance criteria
- No RenderFlex overflow in tested widths.
- Drawer overlay behavior remains correct.
---
## Chunk 9.5 — Final visual polish pass
### Tasks
Compare against both mockups and tune:
- sidebar active state,
- main gutters,
- title/count pill,
- controls spacing,
- column widths/heights,
- card density,
- icons,
- difficulty/reward indicators,
- summary panel,
- drawer width/spacing,
- selected card highlight,
- button heights.
Allowed deviations:
- minor font metric differences,
- safe hit target sizing,
- small responsive adjustments,
- platform-specific rendering differences.
Not allowed:
- white backgrounds,
- drawer shifting columns,
- cards not data-driven,
- missing summary panel,
- missing visible action buttons.
### Acceptance criteria
- Backlog default state and drawer state are close enough for Ashley review.
BREAKPOINT: Stop here for visual review if any major visual section is missing.
---
## Chunk 9.6 — Run validation commands
### Commands
From repo root:
```sh
dart format --set-exit-if-changed .
dart analyze
dart test
```
From Flutter app:
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```
If supported by environment:
```sh
scripts/test.sh
```
### Acceptance criteria
- Validation passes, or exact environment-related blockers are documented.
- New failures are fixed before handoff unless Ashley approves deferral.
---
## Chunk 9.7 — Update docs and handoff
### Tasks
Update relevant docs:
- `apps/focus_flow_flutter/README.md` current scope.
- `Codex Documentation/Current Software Plan/README.md` if this plan becomes the active plan.
- Optional implementation summary in completed plans if the repo tracks completed plan copies after execution.
Handoff summary must include:
- files changed,
- implementation decisions,
- commands run and results,
- features implemented,
- deferred items,
- known risks,
- next recommended plan.
### Acceptance criteria
- A new developer/Codex run can understand what changed.
- Deferred items are explicit, not hidden.
---
## Final acceptance checklist
- [ ] Backlog navigation works.
- [ ] Default board matches mockup.
- [ ] Drawer state matches mockup.
- [ ] Drawer overlays and does not shift layout.
- [ ] Four board buckets and counts are data-driven.
- [ ] Summary panel is data-driven.
- [ ] Search/filter/sort/group controls are safe.
- [ ] New Task/Add Task create backlog tasks.
- [ ] Schedule uses backend/application command.
- [ ] Push to Someday is non-destructive.
- [ ] Remove is non-destructive unless Ashley explicitly changed this.
- [ ] Break Up works or is explicitly deferred with approval.
- [ ] Notes/tags/project metadata is either implemented end-to-end or explicitly deferred with approval.
- [ ] Flutter app avoids forbidden imports.
- [ ] Tests pass or blockers are documented.

View file

@ -0,0 +1,48 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# UI Plan 2 — Execution Order
Follow this order exactly. Stop at each `BREAKPOINT` if Codex is operating in an interactive repo session.
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`
Minimum validation after each block:
```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```
Additional validation after blocks that touch packages:
```sh
dart analyze
dart test
```
Full project validation at the end, if available in the working environment:
```sh
scripts/test.sh
```
Commit guidance:
- Commit after each completed block.
- Use conventional commit style.
- Example block commits:
- `feat(backlog): add board read models`
- `feat(ui): add backlog navigation shell`
- `feat(ui): render backlog board cards`
- `feat(ui): add backlog detail drawer`
- `test(ui): cover backlog board interactions`

View file

@ -0,0 +1,345 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# 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 repos 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 460470 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<BacklogBoardColumnReadModel> columns;
final List<ProjectOptionReadModel> projectOptions;
}
class BacklogBoardColumnReadModel {
final BacklogBoardBucket bucket;
final String title;
final String subtitle;
final String accentToken;
final int count;
final List<BacklogBoardItemReadModel> 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<BacklogChildPreviewReadModel> childPreview;
final List<String> tags;
}
class BacklogTaskDetailReadModel {
final BacklogBoardItemReadModel item;
final String? notes;
final String addedLabel;
final List<String> tags;
final List<ProjectOptionReadModel> projectOptions;
final List<SuggestedSlotReadModel> suggestedSlots;
}
```
Summary should include:
- total tasks,
- total estimated minutes,
- priority distribution,
- project distribution,
- duration distribution buckets: `030`, `3060`, `60120`, `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.

View file

@ -0,0 +1,16 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# Backlog Board Mockups
These images are the visual references for UI Plan 2.
- `backlog_board_default.png` — finalized default Backlog board state with summary panel.
- `backlog_task_drawer.png` — finalized selected-task state with right-anchored drawer.
Implementation notes:
- Treat these as semi-strict visual references.
- Preserve the dark theme, board density, summary panel, and drawer anchoring.
- The drawer must overlay existing content and must not move board columns or summary layout.
- Do not introduce a white app background.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

View file

@ -1,13 +0,0 @@
# ADHD-Friendly Scheduling Application
Unified Product and Design Specification
Draft compiled from user requirements - June 19, 2026
## Executive Summary
This application is a failure-tolerant scheduling system for people who struggle with executive dysfunction, task migration, reminders, volatile schedules, and missed logging. It is not intended to be a generic productivity app. Its core job is to preserve intent when the plan breaks: move flexible tasks forward, protect required commitments, keep locked unavailable time out of the way visually, and make recovery simple instead of punitive.
The MVP focuses on Today, Backlog, recurring hidden locked blocks, push/rollover behavior, task capture, and simple state management. Version 2.0 adds week/month views, reports, drag-and-drop, task history, and the full overwhelm shield/recovery system.
See the DOCX file for the complete formatted specification.

View file

@ -1,10 +0,0 @@
# Human Documentation
This folder contains human-facing product documentation.
Start with:
- `Overall App Design Spec.docx`
- `Original Chat-Compiled Design Spec.md`
These documents define the product intent, terminology, major features, and version boundaries. Codex should use these files for product context but should execute from the files in `Codex Documentation/Current Software Plan/`.

View file

@ -0,0 +1,64 @@
<!-- SPDX-FileCopyrightText: 2026 FocusFlow contributors -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# Backlog Notes and Freeform Tags Metadata
## Status
Deferred from UI Plan 2 on 2026-07-07.
For the current Backlog board implementation, notes and freeform tags are
read-only presentation placeholders. Do not expand the current UI Plan 2 scope
to add persisted task notes or general-purpose tags.
## Why this is deferred
The drawer mockup includes notes and tag chips, but the current V1 `Task` domain
model only has narrow `BacklogTag` flags such as `wishlist`. It does not yet
have general freeform notes or user-defined task tags.
Adding those fields correctly is not a local widget change. It is a real V1
metadata and persistence feature with schema, migration, command, and test
impact.
## Work left for the future feature
When this feature is resumed, decide the exact product behavior first:
1. Whether notes are plain text only or support lightweight formatting later.
2. Whether tags are task-local strings or reusable global tag records.
3. Maximum note length.
4. Maximum tag count per task.
5. Maximum tag label length.
6. Case and duplicate handling for tags.
7. Whether tag edits are allowed in quick capture, the Backlog drawer, or both.
8. Whether existing imports/exports should include notes and tags immediately.
Expected implementation areas:
1. Add `String? notes` and either `Set<String> tags` or a small validated tag
value object to `Task`.
2. Update `Task.quickCapture`, `Task.copyWith`, and domain invariant tests.
3. Add validation and normalization for blank notes, blank tags, duplicate tags,
and safe payload limits.
4. Extend task document fields and `TaskDocumentMapping`.
5. Update document mapping, migration, and persistence field coverage tests.
6. Update repository conformance expectations so notes/tags round-trip through
every adapter.
7. Add SQLite Drift task columns or a normalized tag table, depending on the
chosen tag model.
8. Bump or migrate SQLite schema as required and add migration tests for old
databases.
9. Regenerate Drift code.
10. Update SQLite application and repository task row mappers.
11. Extend quick-capture/create/update command surfaces if users can write notes
or tags.
12. Update readable export/import behavior if these fields are part of user data
portability.
## Current UI Plan 2 handling
For UI Plan 2, the Backlog board and drawer may display placeholder or derived
read-only tag text where useful, but Flutter must not pretend those values are
persisted editable task metadata. Editing controls should remain disabled,
hidden, or clearly non-editing until the future metadata feature lands.