<!-- 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 Ashley’s 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
```
