# V1 Block 14 — Application Use Cases and UI-Ready Read Models

Status: Complete

Purpose: Add the orchestration layer that a future Flutter UI can call without
assembling scheduler inputs, coordinating multiple repositories, or manually
keeping tasks, activities, statistics, and notices consistent.

## Chunk 14.1 — Application operation context and unit-of-work contracts

Recommended Codex level: high

Status: Complete

Tasks:

- Introduce an application facade/use-case layer above the pure domain services.
- Define an operation context containing operation ID, current instant, owner
  time-zone context, and injected ID/clock services.
- Define typed application result/failure contracts for validation, not found,
  conflict, stale revision, no slot, duplicate operation, persistence failure,
  and unexpected failure.
- Add a unit-of-work/repository transaction boundary capable of atomically
  persisting task changes, activities, project aggregates, settings, and
  operation records.
- Provide an in-memory implementation that stages changes and rolls back on
  failure for deterministic tests.
- Centralize repository loading and conversion to domain inputs.
- Prevent UI callers from directly persisting a partial `SchedulingResult`.
- Add contract tests for commit, rollback, duplicate operation IDs, and typed
  failure mapping.

Rules:

- The application layer may depend on domain and repository interfaces, not
  Flutter widgets or MongoDB client APIs.
- One user command must have one operation ID and one atomic commit boundary.
- Expected failures return typed results and do not leak driver exceptions.
- Read-only queries must not create activities or increment statistics.
- Keep transport/JSON DTOs separate from domain models where they diverge.

Acceptance criteria:

- UI code can call one use case per user intent.
- A failed multi-record command leaves the in-memory repositories unchanged.
- Duplicate operation IDs are exactly-once.
- Result codes are stable and do not depend on English text.
- The application layer has no Flutter or MongoDB imports.

Completed implementation:

- Added `src/application_layer.dart` as a pure Dart application boundary above
  the existing domain services and repository interfaces.
- Added operation context, owner time-zone context, typed result/failure
  contracts, expected failure/persistence exception wrappers, owner settings,
  operation records, and unit-of-work repository contracts.
- Added an in-memory staged unit-of-work implementation that commits task,
  activity, project-statistics, settings, and operation-record changes
  atomically, rejects duplicate operation IDs, and rolls back on typed,
  validation, persistence, or unexpected failures.
- Added `ApplicationSchedulingLoader` so application commands can centralize
  repository loading into `SchedulingInput` instead of letting UI callers
  persist partial scheduler results.
- Added contract tests for successful commit, rollback on typed failure,
  rollback on persistence failure, duplicate operation IDs, typed validation
  mapping, and centralized scheduler input loading.

Verification:

- `dart format lib test`: passed, 0 files changed after final format
- `dart analyze`: passed, no issues found
- `dart test`: passed, 249 tests
- `git diff --check`: passed

BREAKPOINT: Stop here. Confirm `extra high` mode before building Today state and
command orchestration.

## Chunk 14.2 — Complete Today query/read model

Recommended Codex level: extra high

Status: Complete

Tasks:

- Add a `GetTodayState`-style query that loads the requested local day, app
  settings, relevant tasks, projects, locked rules, one-day overrides, and
  unacknowledged scheduling notices.
- Expand locked occurrences using the explicit time-zone context from Block 11.
- Produce one sorted UI-independent read model containing task cards, optional
  revealed locked overlays, Free Slots, status metadata, and structured actions.
- Include full-timeline and compact-mode projections from the same source data.
- Correct compact selection so the current flexible task cannot also occupy the
  “next flexible” slot after deduplication.
- Produce stable occurrence IDs that include the local date/occurrence identity,
  preventing cross-day UI-key collisions.
- Include current item, next required item, optional next flexible item, day
  boundaries, and pending rollover notice data.
- Keep hidden locked details absent unless reveal mode is requested.
- Add query tests for empty day, mixed task types, current boundaries, compact
  mode, reveal mode, DST day, and stable ordering.

Rules:

- Read-model construction must not mutate tasks or run rollover implicitly.
- The query accepts an explicit date and operation/read instant.
- Hidden locked time may influence availability while remaining absent from the
  default item list.
- Presentation text/localization is outside the read model; expose tokens/codes
  and raw domain values.
- Do not import Flutter.

Acceptance criteria:

- One query returns all data needed for the V1 Today and compact views.
- Current/next selections are correct and non-duplicated.
- Locked overlay identity is stable per occurrence/day.
- Read queries have no side effects.
- Today query tests cover all V1 task types and relevant lifecycle states.

Completed implementation:

- Added `src/today_state.dart` with `GetTodayStateQuery`, request/result
  objects, source-tagged timeline items, compact projection, and pending
  scheduling notice read models.
- Added a read-only application boundary through `ApplicationUnitOfWork.read`
  so queries do not create operation records, activities, statistics, or
  rollover changes.
- Loaded owner settings, project color tokens, scheduled tasks, locked blocks,
  one-day overrides, and stored scheduling snapshot notices for the requested
  local day.
- Expanded locked occurrences with the explicit `TimeZoneResolver` and
  owner time-zone context, including DST fixture coverage.
- Produced date-stable locked overlay IDs by passing the local date into
  `TimelineItemMapper.fromLockedOccurrence`.
- Built current, next required, optional next flexible, full timeline, and
  compact projections from the same sorted Today item list.
- Corrected compact next-flexible selection so the current flexible item is not
  duplicated as the next flexible item.
- Added tests for empty days, mixed V1 item types, current boundaries, compact
  mode, reveal mode, stable cross-day locked IDs, DST day expansion, and
  deterministic equal-start ordering.

Verification:

- `dart format lib test`: passed, 0 files changed after final format
- `dart analyze`: passed, no issues found
- `dart test`: passed, 257 tests
- `git diff --check`: passed

## Chunk 14.3 — Atomic V1 command use cases

Recommended Codex level: extra high

Status: Complete

Tasks:

Implement application commands for:

- quick capture to backlog
- quick capture to next available slot
- backlog item to next available slot
- flexible push to next available slot
- flexible push to tomorrow/top of queue
- flexible move to backlog
- flexible/required completion
- required miss, cancel, and no-longer-relevant
- surprise completed-task logging and flexible repair
- create/update/remove a protected Free Slot
- break up a task into child tasks
- complete parent/children through the V1 propagation rules

For each command:

- load the authoritative current state through repositories
- enforce expected revision/idempotency
- invoke domain rules
- persist all task/activity/stat/project/operation changes in one unit of work
- return structured changed entities, conflicts, notices, and refreshed read
  hints without requiring the UI to infer what changed

Rules:

- Do not expose a “save these scheduler results” method to UI callers.
- No command may partially commit a task movement without its statistics and
  operation record.
- Preserve flexible order and immovable time invariants.
- Use application-level typed failures for expected stale/not-found/no-slot
  conditions.
- Do not add batch V2 burnout recovery commands.

Acceptance criteria:

- Every V1 Today/Backlog user action has one application command.
- Each command is atomic and idempotent in the in-memory implementation.
- Statistics and activity records match resulting task state.
- Failure tests prove rollback.
- Command outputs are sufficient for a UI to refresh predictably.

Completed implementation:

- Added `src/application_commands.dart` with `V1ApplicationCommandUseCases`,
  stable `ApplicationCommandCode` values, child draft input, structured command
  results, and read refresh hints.
- Added atomic commands for quick capture to backlog, quick capture to next
  available slot, backlog item scheduling, flexible next-slot push, flexible
  tomorrow/top push, flexible move to backlog, flexible completion, required
  done/missed/cancel/no-longer-relevant actions, surprise logging with flexible
  repair, protected Free Slot create/update/remove, child task break-up, child
  completion, parent completion, and parent-from-child completion.
- Commands load authoritative repository state, expand locked intervals through
  the explicit owner time-zone context where scheduling or completion accounting
  needs it, and invoke the existing pure domain services.
- Commands enforce idempotency through the operation record boundary and use
  optional `expectedUpdatedAt` guards for V1 stale-write protection until Block
  15 adds explicit persisted revisions.
- Commands persist changed tasks, new activities, project aggregate updates, and
  operation records in one `ApplicationUnitOfWork.run` boundary.
- Command results include changed tasks, activities, project statistics, notices,
  scheduling changes/overlaps, child ids, protected-rest conflicts, and read
  hints so UI callers do not need to infer what changed.
- Added command tests for quick capture, backlog scheduling, stale revisions,
  commit rollback, flexible pushes, backlog movement, completion/project stats,
  surprise repair, Free Slot create/update/remove, child break-up, and
  parent/child completion propagation.

Verification:

- `dart format lib test`: passed, 0 files changed after final format
- `dart analyze`: passed, no issues found
- `dart test`: passed, 268 tests
- `git diff --check`: passed

BREAKPOINT: Stop here. Confirm `high` mode before adding management queries and
startup/rollover orchestration.

## Chunk 14.4 — Backlog, project, locked-time, and settings use cases

Recommended Codex level: high

Status: Complete

Tasks:

- Add a Backlog query using repository-side candidate loading plus the existing
  filter/sort/staleness policies.
- Add settings-backed configurable green/blue/purple backlog thresholds.
- Add project create/update/archive queries and commands for configured defaults,
  color token, and reminder profile.
- Return learned project suggestions separately from configured values.
- Add locked-block create/update/archive commands and date-scoped one-day
  add/remove/replace override commands.
- Add owner settings for time zone, day boundary/default planning window,
  compact-mode preference, and backlog thresholds where appropriate.
- Add explicit acknowledge/consume behavior for one-time notices.
- Add authorization-neutral owner-scope parameters without implementing user
  accounts.
- Add use-case contract examples that future Flutter state management can call.

Rules:

- Archiving a project must not orphan or silently delete its tasks.
- Removing a recurring locked block must not delete unrelated overrides without
  a documented explicit policy.
- Settings changes that reinterpret dates/time zones require a typed warning or
  migration path; do not silently shift existing instants.
- Backlog queries must not load an unbounded full history when repository filters
  can narrow candidates.
- Do not add report dashboards.

Acceptance criteria:

- Backlog filters/sorts and configurable staleness thresholds are available
  through one query contract.
- Project, locked-time, and settings changes use typed atomic commands.
- Learned suggestions remain distinguishable from configured defaults.
- Date-scoped override behavior is tested.
- No management command deletes task history implicitly.

Completed implementation:

- Added `src/application_management.dart` with
  `V1ApplicationManagementUseCases`, stable management command codes, backlog
  and project query contracts, typed project/locked/settings command inputs, and
  notice acknowledgement results.
- Added a backlog query that loads candidates with
  `TaskRepository.findByStatus(TaskStatus.backlog)` before applying the existing
  backlog filter, sort, and green/blue/purple staleness marker policies.
- Used owner settings as the source for configurable backlog staleness
  thresholds and added typed validation for invalid threshold updates.
- Added project create/update/archive commands plus a project defaults query
  that returns configured defaults and learned `ProjectSuggestionSet` values
  separately.
- Added `ProjectProfile.archivedAt` so archived projects disappear from normal
  project queries without deleting or orphaning task history.
- Added locked-block create/update/archive commands and date-scoped add, remove,
  and replace override commands.
- Added `LockedBlock.archivedAt` and updated locked-time expansion so archived
  base blocks no longer create occurrences while unrelated add overrides remain
  intact.
- Added settings updates for time zone, day boundary/default planning window,
  compact-mode preference, and backlog thresholds, with typed warnings for
  time-zone and planning-window reinterpretation.
- Added owner-scoped `NoticeAcknowledgementRecord` persistence, a unit-of-work
  repository for acknowledgements, stable notice IDs, and Today-state filtering
  for acknowledged one-time notices.
- Added management contract tests covering backlog thresholds, project
  suggestion separation, project archiving without task deletion, date-scoped
  locked overrides, locked-block archiving without override deletion, settings
  warnings, and notice acknowledgement.

Verification:

- `dart format lib test`: passed, 0 files changed after final format
- `dart analyze`: passed, no issues found
- `dart test`: passed, 274 tests
- `git diff --check`: passed

## Chunk 14.5 — Rollover and app-open recovery orchestration

Recommended Codex level: high

Status: Complete

Tasks:

- Add an explicit app-open/start-day use case that determines whether a source
  day needs V1 flexible-task rollover.
- Key rollover by owner scope and source local date so it runs at most once.
- Use an explicit source-day window and never pull future-day tasks into the
  rollover set.
- Preserve order among rolled-over tasks at the top of tomorrow’s flexible queue.
- Persist the rollover operation, task/stat/activity changes, and small notice
  atomically.
- Return the pending notice through Today state until it is acknowledged.
- Make retries and multiple app opens idempotent.
- Add end-to-end in-memory tests spanning capture, day close, next open, notice
  acknowledgement, and a second open.

Rules:

- Do not infer a burnout gap or enter a V2 recovery flow.
- Required, locked, Free Slot, completed, and future-day tasks must not be rolled
  as unfinished flexible work.
- The notice is informational and calm; application logic branches on a code and
  count, not text.
- Rollover must be an explicit command, not a side effect of reading Today.
- If no work needs rollover, record or return a deterministic no-op without
  creating duplicate notices.

Acceptance criteria:

- Rollover executes once per source local date.
- Future-day tasks are unaffected.
- Order and statistics are correct.
- Notice lifecycle is persisted and acknowledgeable.
- The full application facade contract suite passes in memory.

Completed implementation:

- Added `src/application_recovery.dart` with `V1AppOpenRecoveryUseCases`,
  explicit source-day/target-day request objects, deterministic recovery
  outcomes, and structured recovery results.
- Implemented app-open recovery as an explicit command that checks one
  owner/source-local-date key and never runs as a Today-read side effect.
- Keyed rollover idempotency by deterministic owner/source-date scheduling
  snapshot IDs, so retries and multiple app opens do not roll the same source
  day twice even with different operation IDs.
- Loaded source-day and target-day scheduled tasks through bounded repository
  window queries, preventing future-day tasks from being pulled into rollover.
- Used the existing pure scheduler rollover behavior to preserve source-day
  flexible order at the top of the target day while shifting target-day flexible
  tasks as needed.
- Persisted changed tasks, rollover movement activities, the deterministic
  scheduling snapshot, the calm aggregate notice, and the operation record in
  one unit-of-work transaction.
- Saved no-op source days with deterministic snapshots and no notice so repeated
  app opens remain idempotent without creating duplicate pending notices.
- Reused the Chunk 14.4 notice acknowledgement path so Today state surfaces the
  pending rollover notice until it is acknowledged.
- Added end-to-end in-memory recovery tests covering capture, next-day app open,
  target queue insertion, notice visibility, acknowledgement, second-open
  idempotency, no-op recording, and future-day exclusion.

Verification:

- `dart format lib test`: passed, 0 files changed after final format
- `dart analyze`: passed, no issues found
- `dart test`: passed, 277 tests
- `git diff --check`: passed

Commit suggestion:

```text
feat(app): add atomic v1 use cases and today read model
```
