docs: reset plan around sqlite workflow
This commit is contained in:
parent
8b2ab6b64e
commit
ea45d635e4
35 changed files with 1145 additions and 854 deletions
206
AGENTS.md
206
AGENTS.md
|
|
@ -1,164 +1,114 @@
|
|||
# AGENTS.md — Codex Project Rules
|
||||
# AGENTS.md — Codex Project Rules (SQLite‑First, July 2026)
|
||||
|
||||
This file is persistent project guidance. Codex must treat it as standing instructions for this repository.
|
||||
This document supersedes all previous agent rule files. Treat it as the single source of truth.
|
||||
|
||||
## User and product context
|
||||
---
|
||||
|
||||
The product owner is a software engineer building a personal scheduling app for difficult ADHD/executive-dysfunction scheduling problems. The app must reduce planning friction, preserve task order, prevent forgotten tasks, and recover gracefully when the user misses work, burns out, or cannot manually reorganize a plan.
|
||||
## 0. Quick‑start for Codex
|
||||
|
||||
Design priorities:
|
||||
* Blocks live in `Codex Documentation/Current Software Plan/`.
|
||||
* Work strictly in numerical order (Block 19 → 20 … 29).
|
||||
* Each block contains numbered `XHIGH` / `HIGH` chunks.
|
||||
* Stop at every `BREAKPOINT` in a chunk; wait for confirmation before continuing.
|
||||
* Before coding, run `scripts/bootstrap_dev.sh` to set up the local dev DB.
|
||||
|
||||
1. Low-friction interactions.
|
||||
2. Reliable scheduling behavior.
|
||||
3. No shame, guilt, punishment, or productivity-slogan framing.
|
||||
4. Preserve flexible task order unless the user explicitly chooses otherwise.
|
||||
5. Never move locked or inflexible time during automatic rescheduling.
|
||||
6. Keep hidden locked time hidden by default.
|
||||
7. Make every scheduling rule testable.
|
||||
8. Prefer explicit state transitions over vague magic behavior.
|
||||
9. Do not add non-MVP features unless the active plan asks for them.
|
||||
10. Update documentation when behavior changes.
|
||||
---
|
||||
|
||||
The user prefers practical, concrete implementation work. Avoid broad redesigns unless the active plan calls for them.
|
||||
## 1. Persistence
|
||||
|
||||
## Documentation structure rules
|
||||
| Element | Rule |
|
||||
|---------|------|
|
||||
| Local storage | **SQLite via Drift**, schemaVersion 1 |
|
||||
| Abstraction | Domain‑only repository interfaces (`scheduler_persistence`) |
|
||||
| Swappable | New adapters must pass repository conformance tests |
|
||||
| Backup | AES‑256‑GCM encrypted SQLite file (`Backup library`, Block 24) |
|
||||
| Migrations | Drift migrations with tests (Block 20, Block 26) |
|
||||
|
||||
Human-facing design/product documentation belongs in:
|
||||
No MongoDB runtime in V1.
|
||||
|
||||
```text
|
||||
Human Documentation/
|
||||
```
|
||||
---
|
||||
|
||||
Codex execution planning belongs in:
|
||||
## 2. Repository & Adapter Rules
|
||||
|
||||
```text
|
||||
Codex Documentation/
|
||||
```
|
||||
1. Interfaces expose domain objects only.
|
||||
2. Optimistic `revision` on every mutable save.
|
||||
3. Owner scope parameter now for future multi‑user.
|
||||
4. Adapters implement compare‑and‑set; core never overwrites stale revision.
|
||||
|
||||
Current, active implementation plans belong in:
|
||||
---
|
||||
|
||||
```text
|
||||
Codex Documentation/Current Software Plan/
|
||||
```
|
||||
## 3. Notification Rules
|
||||
|
||||
Completed plans must be moved to:
|
||||
* Use `NotificationAdapter` (Block 21).
|
||||
* Desktop implementation (Block 22), fake adapter for tests.
|
||||
* Core never imports platform APIs directly.
|
||||
|
||||
```text
|
||||
Codex Documentation/Archived plans/
|
||||
```
|
||||
---
|
||||
|
||||
This is firm. New plans may be uploaded, generated, or pointed at from elsewhere, but once Codex completes a plan, it must move the completed plan document into `Codex Documentation/Archived plans/`. Do not leave completed plans in `Current Software Plan/`.
|
||||
## 4. Backup / Export Rules
|
||||
|
||||
* Backup: encrypted SQLite (`.sqlite.aes`) via Backup library.
|
||||
* Readable exports: JSON + CSV via `ExportController` (Block 23).
|
||||
|
||||
## Persistence target rules
|
||||
---
|
||||
|
||||
MongoDB is the committed persistence target for this project. Treat MongoDB document storage as the future database direction when designing repository interfaces, serialization helpers, and persistence boundaries.
|
||||
## 5. Testing Hierarchy
|
||||
|
||||
Rules:
|
||||
| Layer | Folder | Purpose |
|
||||
|-------|--------|---------|
|
||||
| Unit | `test/unit` | pure domain logic |
|
||||
| Contract | `test/contract` | repository conformance |
|
||||
| Migration | `test/migration` | Drift schema upgrades |
|
||||
| Integration | `test/integration` | full stack InMemory + SQLite + fake notifications |
|
||||
|
||||
- Do not introduce alternative database assumptions unless the user explicitly reverses this decision.
|
||||
- V1 planning may prepare MongoDB-friendly repository interfaces and document-shaped model mappings without adding a MongoDB driver yet.
|
||||
- Do not add MongoDB connection strings, Atlas/cloud setup, local server requirements, sync behavior, accounts, or network/background behavior unless an active plan explicitly calls for that implementation work.
|
||||
- Keep the scheduling core independent from MongoDB APIs; persistence adapters should sit behind repository interfaces.
|
||||
CI fails below **80 % line coverage**.
|
||||
|
||||
## Planning document execution rules
|
||||
---
|
||||
|
||||
Planning documents are organized into blocks, chunks, and optional stages.
|
||||
## 6. Dev Scripts (Block 27)
|
||||
|
||||
- Blocks are groups of related work.
|
||||
- Chunks are actionable pieces of work inside a block.
|
||||
- Stages may be used inside larger chunks when helpful.
|
||||
- Blocks do **not** receive a Codex thinking-level classification.
|
||||
- Chunks and stages must include one of these classifications:
|
||||
- `low`
|
||||
- `medium`
|
||||
- `high`
|
||||
- `extra high`
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| `bootstrap_dev.sh` | install deps, create dev DB |
|
||||
| `dev.sh` | hot‑reload desktop run |
|
||||
| `test.sh` | all tests + coverage |
|
||||
| `package_release.sh` | build OS binaries |
|
||||
|
||||
Codex should rely on the planning documents as much as possible to avoid excess token use. Before doing exploratory work, check whether the current plan already answers the question.
|
||||
Flutter UI work starts in Block 29 under `apps/focus_flow_flutter/`. Keep it
|
||||
out of the root Dart workspace until the Flutter toolchain gate is fully
|
||||
integrated.
|
||||
|
||||
## Break point rules
|
||||
---
|
||||
|
||||
Planning documents may contain `BREAKPOINT` markers.
|
||||
## 7. Branch, Commit & CI
|
||||
|
||||
When the user says to do the next chunk:
|
||||
* Start each new block from `main` on a block branch named
|
||||
`block-XX-simple-name` (for example, `block-20-sqlite-adapter`).
|
||||
* Keep all chunk work for that block on the block branch.
|
||||
* Commit every completed chunk before moving to the next chunk or breakpoint.
|
||||
* Use conventional commits (`feat`, `fix`, `docs`, `test`, `refactor`,
|
||||
`chore`, `ci`).
|
||||
* Do not leave completed chunk work only in the working tree.
|
||||
* When the block is complete and verified, merge the block branch back into
|
||||
`main`.
|
||||
* CI matrix: ubuntu‑latest, windows‑latest, macos‑latest.
|
||||
* `dart analyze` and `dart test` must pass.
|
||||
|
||||
1. Execute only the next permitted chunk or stage.
|
||||
2. Do not proceed past a `BREAKPOINT`.
|
||||
3. If the next chunk or stage has a different recommended thinking level, stop and tell the user the next required level.
|
||||
4. Wait for user confirmation that the mode has been switched before continuing.
|
||||
---
|
||||
|
||||
A breakpoint is a hard stop. Do not skip it because the next task seems small.
|
||||
## 8. MVP Boundaries
|
||||
|
||||
## Commit rules
|
||||
* Today + Backlog only.
|
||||
* Task types: flexible, inflexible, critical, locked, surprise, free slot.
|
||||
* No week/month views, sync, or shield in V1.
|
||||
|
||||
When finishing a work block or a clearly bounded chunk that leaves the project in a working state:
|
||||
---
|
||||
|
||||
1. Run relevant formatting/analyze/tests when possible.
|
||||
2. Commit the work.
|
||||
3. Use a descriptive conventional commit message.
|
||||
## 9. UX Language
|
||||
|
||||
Examples:
|
||||
* Use calm terms: missed, pushed, backlog, archived.
|
||||
* Avoid blame language.
|
||||
|
||||
```text
|
||||
feat(scheduling): add flexible task push behavior
|
||||
fix(backlog): preserve stale age marker after task update
|
||||
test(engine): cover locked block overlap rules
|
||||
docs(plan): archive completed foundation block
|
||||
```
|
||||
---
|
||||
|
||||
Do not make vague commits such as `update files`, `changes`, or `work`.
|
||||
|
||||
## Engineering rules
|
||||
|
||||
- Keep scheduling/domain logic separate from UI.
|
||||
- Start with pure Dart domain logic and tests.
|
||||
- Add Flutter UI only when the plan calls for it.
|
||||
- Avoid network/sync/background behavior unless explicitly planned.
|
||||
- Use MongoDB as the committed future persistence target; do not add alternative database assumptions.
|
||||
- Prefer immutable models or copy/update patterns.
|
||||
- Avoid hidden side effects in scheduling functions.
|
||||
- Every rule that changes task placement should have tests.
|
||||
- Use clear names over clever abstractions.
|
||||
- If a rule is ambiguous, add a TODO comment and a small safe default rather than inventing broad behavior.
|
||||
|
||||
## MVP boundaries
|
||||
|
||||
MVP includes:
|
||||
|
||||
- Today view data model.
|
||||
- Backlog/wishlist model.
|
||||
- Quick capture to backlog.
|
||||
- Optional quick-capture scheduling into next available flexible slot.
|
||||
- Flexible/inflexible/critical/locked/surprise task types.
|
||||
- Recurring locked blocks, hidden by default.
|
||||
- One-day overrides for locked blocks.
|
||||
- Flexible task push behavior.
|
||||
- Push options: next available slot, tomorrow/top of queue, backlog.
|
||||
- End-of-day rollover notice.
|
||||
- Manual compact mode state.
|
||||
- Task actions: done, push, backlog, break up.
|
||||
- Child task ownership and parent auto-completion logic.
|
||||
- Internal statistics needed for future reporting.
|
||||
|
||||
MVP excludes unless explicitly added:
|
||||
|
||||
- Week view.
|
||||
- Month view.
|
||||
- Weekly reports.
|
||||
- Overwhelm shield.
|
||||
- Drag-and-drop reordering.
|
||||
- Per-task history panel.
|
||||
- Task dependencies.
|
||||
- Context tags.
|
||||
- Full sync.
|
||||
- Long-running task auto-extension behavior.
|
||||
|
||||
## UX language rules
|
||||
|
||||
Use calm, non-punitive terminology:
|
||||
|
||||
- Prefer: `missed`, `pushed`, `moved to backlog`, `no longer relevant`, `cancelled`.
|
||||
- Avoid: `failed`, `late again`, `bad`, `unproductive`, `overdue pile`, `punishment`.
|
||||
|
||||
The app should treat disruption as expected, not exceptional.
|
||||
_Last updated: 2026-06-27_
|
||||
|
|
|
|||
|
|
@ -1,10 +1,66 @@
|
|||
# Archived plans
|
||||
# Current Software Plan
|
||||
|
||||
Completed Codex implementation plans go here.
|
||||
Blocks 01–12 are complete and remain historical records in
|
||||
`Codex Documentation/Archived plans/`. The active path resumes at Block 13.
|
||||
|
||||
Rules:
|
||||
The backend sequence is Blocks 11–17. Block 18 is a deliberately limited UI
|
||||
foundation block and is blocked until the backend completion gate in Chunk 17.4
|
||||
passes.
|
||||
|
||||
- Move completed plans here from `Codex Documentation/Current Software Plan/`.
|
||||
- Do not delete completed plans.
|
||||
- Commit the archive move with a conventional commit message.
|
||||
- If a completed plan later needs revision, create a new current plan rather than editing archived history unless the user explicitly asks.
|
||||
## Execution rules
|
||||
|
||||
1. Read `AGENTS.md` first.
|
||||
2. Read `V1_BACKEND_COMPLETION_GAP_MATRIX.md` before starting Block 11.
|
||||
3. Execute active block documents in numeric order.
|
||||
4. Execute only the next chunk or stage requested by the user.
|
||||
5. Respect every `BREAKPOINT` as a hard stop.
|
||||
6. When the next chunk changes recommended Codex level, stop and ask the user to
|
||||
confirm the mode switch before continuing.
|
||||
7. Run the relevant formatter, analyzer, unit tests, contract tests, and
|
||||
integration tests before claiming a chunk is complete.
|
||||
8. Commit completed bounded work with a descriptive conventional commit.
|
||||
9. Mark a completed plan `Complete`, move it to
|
||||
`Codex Documentation/Archived plans/`, and commit the archive move.
|
||||
10. Do not rewrite archived Blocks 01–10 to make new work appear previously
|
||||
complete. Add errata or new active work instead.
|
||||
|
||||
## Scope guardrails
|
||||
|
||||
Backend V1 includes the application-facing use cases, persistence schema,
|
||||
MongoDB adapter boundary, deterministic scheduling behavior, internal statistics,
|
||||
and UI-independent read models required by Today, Backlog, quick capture, locked
|
||||
time, rollover, surprise logging, child tasks, free slots, project defaults, and
|
||||
reminder policy decisions.
|
||||
|
||||
Backend V1 does not include week/month views, reports, overwhelm shield,
|
||||
burnout catch-up, drag-and-drop, a visible task-history panel, task dependencies,
|
||||
context tags, advanced sync, user accounts, production authentication, or
|
||||
flexible-task overrun behavior.
|
||||
|
||||
The UI must never receive a MongoDB connection string or database credentials.
|
||||
Block 16 must choose and document a trusted runtime boundary before adding a
|
||||
runtime database dependency.
|
||||
|
||||
## Active plan index
|
||||
|
||||
| Order | Plan | Status | Backend/UI |
|
||||
|---|---|---|---|
|
||||
| 11 | `../Archived plans/V1_BLOCK_11_Backend_Baseline_Domain_Contracts.md` | Complete, archived | Backend |
|
||||
| 12 | `../Archived plans/V1_BLOCK_12_Occupancy_Scheduling_Correctness.md` | Complete, archived | Backend |
|
||||
| 13 | `V1_BLOCK_13_Lifecycle_Statistics_Project_Reminders.md` | Planned | Backend |
|
||||
| 14 | `V1_BLOCK_14_Application_Use_Cases_Read_Models.md` | Planned | Backend |
|
||||
| 15 | `../Archived plans/V1_BLOCK_15_Persistence_Schema_Codecs_Repositories.md` | Complete, archived | Backend |
|
||||
| 16 | `V1_BLOCK_16_MongoDB_Runtime_Adapter.md` | In progress | Backend |
|
||||
| 17 | `V1_BLOCK_17_Backend_Acceptance_Handoff.md` | Planned | Backend gate |
|
||||
| 18 | `V1_BLOCK_18_UI_Foundation_Design_Spike.md` | Planned, blocked | UI foundation |
|
||||
|
||||
## Recommended mode labels
|
||||
|
||||
Chunks and stages use only:
|
||||
|
||||
- `low`
|
||||
- `medium`
|
||||
- `high`
|
||||
- `extra high`
|
||||
|
||||
Blocks do not receive a Codex thinking-level classification.
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
# Current Software Plan
|
||||
|
||||
Blocks 01–12 are complete and remain historical records in
|
||||
`Codex Documentation/Archived plans/`. The active path resumes at Block 13.
|
||||
|
||||
The backend sequence is Blocks 11–17. Block 18 is a deliberately limited UI
|
||||
foundation block and is blocked until the backend completion gate in Chunk 17.4
|
||||
passes.
|
||||
|
||||
## Execution rules
|
||||
|
||||
1. Read `AGENTS.md` first.
|
||||
2. Read `V1_BACKEND_COMPLETION_GAP_MATRIX.md` before starting Block 11.
|
||||
3. Execute active block documents in numeric order.
|
||||
4. Execute only the next chunk or stage requested by the user.
|
||||
5. Respect every `BREAKPOINT` as a hard stop.
|
||||
6. When the next chunk changes recommended Codex level, stop and ask the user to
|
||||
confirm the mode switch before continuing.
|
||||
7. Run the relevant formatter, analyzer, unit tests, contract tests, and
|
||||
integration tests before claiming a chunk is complete.
|
||||
8. Commit completed bounded work with a descriptive conventional commit.
|
||||
9. Mark a completed plan `Complete`, move it to
|
||||
`Codex Documentation/Archived plans/`, and commit the archive move.
|
||||
10. Do not rewrite archived Blocks 01–10 to make new work appear previously
|
||||
complete. Add errata or new active work instead.
|
||||
|
||||
## Scope guardrails
|
||||
|
||||
Backend V1 includes the application-facing use cases, persistence schema,
|
||||
MongoDB adapter boundary, deterministic scheduling behavior, internal statistics,
|
||||
and UI-independent read models required by Today, Backlog, quick capture, locked
|
||||
time, rollover, surprise logging, child tasks, free slots, project defaults, and
|
||||
reminder policy decisions.
|
||||
|
||||
Backend V1 does not include week/month views, reports, overwhelm shield,
|
||||
burnout catch-up, drag-and-drop, a visible task-history panel, task dependencies,
|
||||
context tags, advanced sync, user accounts, production authentication, or
|
||||
flexible-task overrun behavior.
|
||||
|
||||
The UI must never receive a MongoDB connection string or database credentials.
|
||||
Block 16 must choose and document a trusted runtime boundary before adding a
|
||||
runtime database dependency.
|
||||
|
||||
## Active plan index
|
||||
|
||||
| Order | Plan | Status | Backend/UI |
|
||||
|---|---|---|---|
|
||||
| 11 | `../Archived plans/V1_BLOCK_11_Backend_Baseline_Domain_Contracts.md` | Complete, archived | Backend |
|
||||
| 12 | `../Archived plans/V1_BLOCK_12_Occupancy_Scheduling_Correctness.md` | Complete, archived | Backend |
|
||||
| 13 | `V1_BLOCK_13_Lifecycle_Statistics_Project_Reminders.md` | Planned | Backend |
|
||||
| 14 | `V1_BLOCK_14_Application_Use_Cases_Read_Models.md` | Planned | Backend |
|
||||
| 15 | `../Archived plans/V1_BLOCK_15_Persistence_Schema_Codecs_Repositories.md` | Complete, archived | Backend |
|
||||
| 16 | `V1_BLOCK_16_MongoDB_Runtime_Adapter.md` | In progress | Backend |
|
||||
| 17 | `V1_BLOCK_17_Backend_Acceptance_Handoff.md` | Planned | Backend gate |
|
||||
| 18 | `V1_BLOCK_18_UI_Foundation_Design_Spike.md` | Planned, blocked | UI foundation |
|
||||
|
||||
## Recommended mode labels
|
||||
|
||||
Chunks and stages use only:
|
||||
|
||||
- `low`
|
||||
- `medium`
|
||||
- `high`
|
||||
- `extra high`
|
||||
|
||||
Blocks do not receive a Codex thinking-level classification.
|
||||
|
|
@ -1,366 +0,0 @@
|
|||
# V1 ADR 002: MongoDB Document Schema V1
|
||||
|
||||
Status: Accepted during Block 15.1
|
||||
|
||||
Date: 2026-06-25
|
||||
|
||||
## Context
|
||||
|
||||
MongoDB is the committed persistence target for this project. Blocks 11-14 added
|
||||
the pure Dart domain model, repository boundaries, application unit of work,
|
||||
Today/Backlog read models, management commands, notice acknowledgement, and
|
||||
app-open rollover recovery.
|
||||
|
||||
Block 15 needs one versioned document contract before codecs, migrations, or a
|
||||
runtime MongoDB adapter are implemented. This ADR defines that contract without
|
||||
adding a database client, connection string, sync behavior, accounts, or
|
||||
background services.
|
||||
|
||||
## Decision
|
||||
|
||||
V1 stores application data in MongoDB-friendly documents behind repository
|
||||
interfaces. The core scheduling logic remains independent from MongoDB APIs.
|
||||
|
||||
Every top-level document uses:
|
||||
|
||||
- `schemaVersion`: integer, `1` for this contract.
|
||||
- `_id`: stable document id, unique within its collection.
|
||||
- `ownerId`: authorization-neutral owner scope. This is a data boundary, not an
|
||||
account/auth implementation.
|
||||
- `revision`: positive integer for mutable authoritative documents. Starts at
|
||||
`1` and increments on compare-and-set saves. Append-only documents use
|
||||
`revision: 1`.
|
||||
- `createdAt`: UTC instant string.
|
||||
- `updatedAt`: UTC instant string. Append-only documents set this equal to
|
||||
`createdAt`.
|
||||
|
||||
The adapter may use BSON dates internally later, but the core V1 codec contract
|
||||
uses the existing string conventions:
|
||||
|
||||
- Instant: UTC ISO-8601 string from `DateTime.toUtc().toIso8601String()`.
|
||||
- Civil date: `YYYY-MM-DD` string with no timezone conversion.
|
||||
- Wall time: `HH:MM` string with no date or timezone conversion.
|
||||
- Time zone: IANA-style string chosen by the application boundary.
|
||||
- Interval: embedded object `{start, end, label?}` where `start` and `end` are
|
||||
UTC instant strings.
|
||||
- Optional fields: V1 writers include known optional fields with `null` when
|
||||
cleared. Decoders tolerate unknown extra fields and ignore them.
|
||||
|
||||
## Collections
|
||||
|
||||
### `tasks`
|
||||
|
||||
Authoritative task documents.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields
|
||||
- `title`
|
||||
- `projectId`
|
||||
- `type`
|
||||
- `status`
|
||||
- `priority`
|
||||
- `reward`
|
||||
- `difficulty`
|
||||
- `durationMinutes`
|
||||
- `scheduledStart`
|
||||
- `scheduledEnd`
|
||||
- `actualStart`
|
||||
- `actualEnd`
|
||||
- `completedAt`
|
||||
- `parentTaskId`
|
||||
- `backlogTags`
|
||||
- `reminderOverride`
|
||||
- `stats`
|
||||
- `backlogEnteredAt`
|
||||
- `backlogEnteredAtProvenance`
|
||||
|
||||
`backlogEnteredAt` is nullable in V1. V0 migration may set it from `createdAt`
|
||||
with provenance `approximated_from_created_at`; new V1 backlog transitions should
|
||||
set provenance `recorded`.
|
||||
|
||||
Task documents do not embed history, children, scheduling changes, or notice
|
||||
lists. Child ownership is represented by `parentTaskId`.
|
||||
|
||||
### `projects`
|
||||
|
||||
Authoritative project configuration documents.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields
|
||||
- `name`
|
||||
- `colorKey`
|
||||
- `defaultPriority`
|
||||
- `defaultReward`
|
||||
- `defaultDifficulty`
|
||||
- `defaultReminderProfile`
|
||||
- `defaultDurationMinutes`
|
||||
- `archivedAt`
|
||||
|
||||
Archiving a project sets `archivedAt` and increments `revision`. It never deletes
|
||||
or rewrites task history.
|
||||
|
||||
### `project_statistics`
|
||||
|
||||
Project-level aggregate documents derived from internal activities.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields
|
||||
- `projectId`
|
||||
- `completedTaskCount`
|
||||
- `durationMinuteCounts`
|
||||
- `completionTimeBucketCounts`
|
||||
- `totalPushesBeforeCompletion`
|
||||
- `completedAfterPushCount`
|
||||
- `rewardCounts`
|
||||
- `difficultyCounts`
|
||||
- `reminderProfileCounts`
|
||||
- `appliedActivityIds`
|
||||
|
||||
`appliedActivityIds` is bounded by compaction policy in future adapter work. It
|
||||
prevents double-application of completion activities.
|
||||
|
||||
### `locked_blocks`
|
||||
|
||||
Authoritative recurring or one-off locked-time definitions.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields
|
||||
- `name`
|
||||
- `startTime`
|
||||
- `endTime`
|
||||
- `date`
|
||||
- `recurrence`
|
||||
- `hiddenByDefault`
|
||||
- `projectId`
|
||||
- `archivedAt`
|
||||
|
||||
Archiving a locked block sets `archivedAt`, increments `revision`, and stops base
|
||||
occurrence expansion. It does not delete one-day overrides.
|
||||
|
||||
### `locked_overrides`
|
||||
|
||||
Date-scoped locked-time override documents.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields
|
||||
- `lockedBlockId`
|
||||
- `date`
|
||||
- `type`
|
||||
- `name`
|
||||
- `startTime`
|
||||
- `endTime`
|
||||
- `hiddenByDefault`
|
||||
- `projectId`
|
||||
|
||||
Override `type` is one of `remove`, `replace`, or `add`. Overrides are
|
||||
append/update records, not edits to the recurring block.
|
||||
|
||||
### `task_activities`
|
||||
|
||||
Append-only internal activity facts.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields with `revision: 1`
|
||||
- `operationId`
|
||||
- `code`
|
||||
- `taskId`
|
||||
- `projectId`
|
||||
- `occurredAt`
|
||||
- `metadata`
|
||||
|
||||
Activities are internal application data. They are not a visible per-task history
|
||||
panel in V1.
|
||||
|
||||
### `owner_settings`
|
||||
|
||||
One owner settings document per owner.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields
|
||||
- `timeZoneId`
|
||||
- `dayStart`
|
||||
- `dayEnd`
|
||||
- `compactModeEnabled`
|
||||
- `backlogStaleness`
|
||||
|
||||
Changing `timeZoneId`, `dayStart`, or `dayEnd` can reinterpret local dates. The
|
||||
application layer must return typed warnings or run an explicit migration path;
|
||||
codecs must not silently shift existing instants.
|
||||
|
||||
### `notice_acknowledgements`
|
||||
|
||||
Owner-scoped consumed-notice records.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields with `revision: 1`
|
||||
- `noticeId`
|
||||
- `acknowledgedAt`
|
||||
|
||||
The unique key is `(ownerId, noticeId)`. Acknowledgement hides a notice from
|
||||
Today state without mutating the original operation/snapshot record.
|
||||
|
||||
### `operation_records`
|
||||
|
||||
Exactly-once operation records.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields with `revision: 1`
|
||||
- `operationId`
|
||||
- `operationName`
|
||||
- `committedAt`
|
||||
|
||||
The unique key is `(ownerId, operationId)`. These records support application
|
||||
idempotency and are not a replacement for task/activity facts.
|
||||
|
||||
### `scheduling_snapshots`
|
||||
|
||||
Bounded diagnostics and pending-notice carrier documents.
|
||||
|
||||
Required fields:
|
||||
|
||||
- common fields with `revision: 1`
|
||||
- `operationName`
|
||||
- `sourceDate`
|
||||
- `targetDate`
|
||||
- `window`
|
||||
- `tasks`
|
||||
- `lockedIntervals`
|
||||
- `requiredVisibleIntervals`
|
||||
- `notices`
|
||||
- `changes`
|
||||
- `overlaps`
|
||||
- `retentionExpiresAt`
|
||||
|
||||
Full scheduling snapshots remain in V1 as bounded diagnostics and as the carrier
|
||||
for pending rollover notices. They are not the authoritative source of task
|
||||
state, project state, locked-time definitions, or activity/statistics facts.
|
||||
|
||||
Production adapters should keep snapshots compact:
|
||||
|
||||
- retain no more than 100 embedded tasks per snapshot;
|
||||
- retain no more than 100 changes or overlaps per snapshot;
|
||||
- retain no more than 20 notices per snapshot;
|
||||
- omit or redact hidden locked names from `lockedIntervals`;
|
||||
- set `retentionExpiresAt` after all notices are acknowledged or after the
|
||||
configured diagnostic retention window.
|
||||
|
||||
If an operation needs more diagnostic data than these bounds allow, it should
|
||||
store the authoritative entity changes and a truncated snapshot with a typed
|
||||
`truncated: true` marker.
|
||||
|
||||
## Stable Codes
|
||||
|
||||
V1 documents must not depend on Dart enum source `.name` values. Codecs will use
|
||||
explicit encode/decode tables. Unknown codes fail closed with typed mapping
|
||||
errors.
|
||||
|
||||
Initial code values:
|
||||
|
||||
| Domain enum | Codes |
|
||||
|---|---|
|
||||
| `TaskType` | `flexible`, `inflexible`, `critical`, `locked`, `surprise`, `free_slot` |
|
||||
| `TaskStatus` | `planned`, `active`, `completed`, `missed`, `cancelled`, `no_longer_relevant`, `backlog` |
|
||||
| `PriorityLevel` | `very_low`, `low`, `medium`, `high`, `very_high` |
|
||||
| `RewardLevel` | `not_set`, `very_low`, `low`, `medium`, `high`, `very_high` |
|
||||
| `DifficultyLevel` | `not_set`, `very_easy`, `easy`, `medium`, `hard`, `very_hard` |
|
||||
| `ReminderProfile` | `silent`, `gentle`, `persistent`, `strict` |
|
||||
| `BacklogTag` | `wishlist` |
|
||||
| `LockedWeekday` | `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday` |
|
||||
| `LockedBlockOverrideType` | `remove`, `replace`, `add` |
|
||||
| `TaskActivityCode` | `completed`, `missed`, `cancelled`, `no_longer_relevant`, `manually_pushed`, `automatically_pushed`, `moved_to_backlog`, `restored_from_backlog`, `activated` |
|
||||
| `SchedulingNoticeType` | `info`, `moved`, `overlap`, `no_fit`, `overflow` |
|
||||
| `SchedulingIssueCode` | `task_not_found`, `invalid_task_state`, `missing_duration`, `missing_scheduled_slot`, `non_positive_duration`, `no_available_slot`, `unfinished_tasks_could_not_fit`, `no_unfinished_flexible_tasks`, `duplicate_surprise_log` |
|
||||
| `SchedulingMovementCode` | `backlog_task_inserted`, `flexible_task_moved_to_make_room`, `flexible_task_pushed_to_next_available_slot`, `flexible_task_moved_to_tomorrow`, `unfinished_flexible_tasks_rolled_over`, `flexible_task_moved_to_backlog`, `required_commitment_scheduled` |
|
||||
| `SchedulingConflictCode` | `flexible_task_overlaps_blocked_time`, `surprise_task_overlaps_required_visible_time`, `required_commitment_overlaps_protected_free_slot` |
|
||||
| `ProjectCompletionTimeBucket` | `overnight`, `morning`, `afternoon`, `evening`, `night` |
|
||||
|
||||
Codec tables may add newer codes in later schema versions. They must not remap
|
||||
an existing code to a different semantic meaning.
|
||||
|
||||
## Indexes And Uniqueness
|
||||
|
||||
Required index specifications are adapter-neutral in V1 and are created in
|
||||
Block 16.
|
||||
|
||||
| Collection | Index | Purpose |
|
||||
|---|---|---|
|
||||
| all collections | unique `(_id)` | Stable document identity |
|
||||
| all owner-scoped collections | `(ownerId, _id)` | Owner boundary lookup |
|
||||
| `tasks` | `(ownerId, status, scheduledStart, scheduledEnd)` | Today/window and lifecycle queries |
|
||||
| `tasks` | `(ownerId, status, projectId)` | backlog/project filters |
|
||||
| `tasks` | `(ownerId, parentTaskId)` | child task lookup |
|
||||
| `tasks` | `(ownerId, status, backlogEnteredAt, createdAt)` | backlog candidate ordering |
|
||||
| `projects` | `(ownerId, archivedAt, name)` | active project pickers |
|
||||
| `project_statistics` | unique `(ownerId, projectId)` | aggregate lookup |
|
||||
| `locked_blocks` | `(ownerId, archivedAt, date)` | one-off locked expansion |
|
||||
| `locked_blocks` | `(ownerId, archivedAt, recurrence.weekdays)` | recurring locked expansion |
|
||||
| `locked_overrides` | `(ownerId, date, lockedBlockId, type)` | date-scoped override expansion |
|
||||
| `task_activities` | unique `(ownerId, _id)` | append-only activity identity |
|
||||
| `task_activities` | `(ownerId, operationId)` | command idempotency/debug lookup |
|
||||
| `task_activities` | `(ownerId, taskId, occurredAt)` | task activity loading |
|
||||
| `task_activities` | `(ownerId, projectId, code, occurredAt)` | project-stat aggregation |
|
||||
| `owner_settings` | unique `(ownerId)` | one settings document per owner |
|
||||
| `notice_acknowledgements` | unique `(ownerId, noticeId)` | notice consume idempotency |
|
||||
| `operation_records` | unique `(ownerId, operationId)` | exactly-once command boundary |
|
||||
| `scheduling_snapshots` | unique `(ownerId, sourceDate, operationName)` for rollover-style operations | source-day idempotency |
|
||||
| `scheduling_snapshots` | `(ownerId, window.start, window.end)` | Today pending notice lookup |
|
||||
| `scheduling_snapshots` | `(retentionExpiresAt)` | bounded diagnostic cleanup |
|
||||
|
||||
Partial indexes should prefer active records where applicable, such as
|
||||
`archivedAt: null` for project and locked-block picker/expansion queries.
|
||||
|
||||
## Archive, Delete, And Retention
|
||||
|
||||
Normal user-facing removal uses lifecycle state or archive fields:
|
||||
|
||||
- Tasks are not hard-deleted by automatic scheduling. `cancelled`,
|
||||
`no_longer_relevant`, and `backlog` preserve history.
|
||||
- Projects use `archivedAt`; task `projectId` values remain unchanged.
|
||||
- Locked blocks use `archivedAt`; overrides remain independent.
|
||||
- Scheduling snapshots are bounded diagnostics and may expire after retention
|
||||
rules once they are no longer carrying pending notices.
|
||||
|
||||
Hard delete is reserved for explicit adapter/admin operations outside the normal
|
||||
V1 app flow.
|
||||
|
||||
Operation records and task activities are internal operation data. V1 retains
|
||||
them long enough to preserve idempotency, statistics, and migration safety.
|
||||
Adapter-level pruning must not remove authoritative task/project/locked state or
|
||||
break exactly-once guarantees for active retry windows.
|
||||
|
||||
## Privacy Boundaries
|
||||
|
||||
Documents must not contain credentials, database connection strings, OAuth
|
||||
tokens, sync tokens, or platform-notification secrets.
|
||||
|
||||
Hidden locked-time details are sensitive. They may live in the owner-scoped
|
||||
`locked_blocks` and `locked_overrides` documents, but they should not be copied
|
||||
into denormalized notices, public summaries, or unnecessary snapshot labels.
|
||||
When snapshots need locked intervals for diagnostics, hidden labels should be
|
||||
redacted or replaced with source IDs and `hiddenByDefault: true`.
|
||||
|
||||
Internal statistics and activity records are implementation data for future
|
||||
reports and scheduling correctness. They should remain behind repository/use-case
|
||||
boundaries and should not become a visible task-history UI in V1.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Chunk 15.2 must replace the current enum `.name` mapping helpers with explicit
|
||||
stable code tables.
|
||||
- Chunk 15.2 must add codecs for every collection listed above, including
|
||||
owner-scoped notices and bounded scheduling snapshots.
|
||||
- Chunk 15.3 must migrate V0 task documents to V1 with explicit provenance for
|
||||
approximated backlog entry time.
|
||||
- Chunk 15.4 must expand repository contracts so Block 14 use cases can use
|
||||
owner-scoped, indexed query methods instead of broad `findAll()` loading.
|
||||
- Chunk 15.5 must turn the index table in this ADR into tested adapter-neutral
|
||||
index specifications.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# V1 ADR 002: SQLite Document Schema V1
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
## Context
|
||||
The project pivoted from MongoDB to **SQLite‑first** persistence.
|
||||
We need a stable, versioned relational schema that maps cleanly to the domain
|
||||
objects while staying behind the repository abstraction. Drift will manage
|
||||
migrations.
|
||||
|
||||
## Decision
|
||||
* **Database file**: `adhd_scheduler.sqlite` in the user data directory.
|
||||
* **Schema version**: `1` (managed by Drift).
|
||||
* **Tables**
|
||||
|
||||
| Table | Purpose | Key fields |
|
||||
|-------|---------|------------|
|
||||
| `tasks` | Authoritative task rows | `id TEXT PRIMARY KEY`, `owner_id TEXT`, `project_id`, `parent_id`, `type`, `status`, `priority`, `reward`, `difficulty`, `scheduled_start_utc`, `scheduled_end_utc`, `actual_start_utc`, `actual_end_utc`, `completed_at_utc`, `revision INT`, `created_at_utc`, `updated_at_utc`, `backlog_entered_at_utc`, `backlog_entered_provenance TEXT` |
|
||||
| `projects` | Project configuration | `id TEXT PRIMARY KEY`, `owner_id`, `name`, `color_key`, config defaults …, `archived_at_utc`, `revision` |
|
||||
| `locked_blocks` | Recurring / one‑off locked time | `id TEXT PRIMARY KEY`, `owner_id`, `name`, `date TEXT`, `start_time TEXT`, `end_time TEXT`, `recurrence_json`, `hidden_by_default INT`, `archived_at_utc`, `revision` |
|
||||
| `locked_overrides` | Date‑scoped overrides | `id TEXT PRIMARY KEY`, `owner_id`, `locked_block_id`, `date TEXT`, `type`, JSON fields |
|
||||
| `settings` | One row per owner | `owner_id TEXT PRIMARY KEY`, `timezone_id`, `day_start_minutes`, `day_end_minutes`, `compact_mode INT`, `revision` |
|
||||
| `activities` | Append‑only internal events | `id TEXT PRIMARY KEY`, `owner_id`, `task_id`, `code`, `occurred_at_utc`, `metadata_json` |
|
||||
| `snapshots` | Bounded diagnostic schedule snapshots | `id TEXT PRIMARY KEY`, `owner_id`, `operation_name`, `source_date TEXT`, `window_json`, `notice_json`, `changes_json`, `retention_expires_utc` |
|
||||
|
||||
* All timestamps are stored as **UTC**.
|
||||
* Optimistic concurrency: every mutable row carries `revision`. Updates must
|
||||
include `WHERE revision = :expected` and increment on success.
|
||||
* Drift migrations are generated and tested; downgrades are not supported.
|
||||
|
||||
## Consequences
|
||||
* Domain objects remain unchanged; adapters translate.
|
||||
* Backup library (Block 24) can copy and encrypt this single file.
|
||||
* Repository contract tests assert schema integrity via Drift introspection.
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
# V1 ADR 003: MongoDB Runtime Topology
|
||||
|
||||
Status: Accepted during Block 16.1
|
||||
|
||||
Date: 2026-06-25
|
||||
|
||||
## Context
|
||||
|
||||
MongoDB is the committed persistence target for V1, but the Flutter UI and pure
|
||||
Dart scheduling core must not own production database credentials. Block 15
|
||||
completed the adapter-neutral document schema, codecs, repository contracts,
|
||||
index catalog, payload limits, and migration contracts.
|
||||
|
||||
Before adding a MongoDB dependency, Block 16 needs a runtime decision that keeps
|
||||
credentials inside a trusted boundary, supports transactions, and avoids
|
||||
deprecated MongoDB client-access products.
|
||||
|
||||
Sources checked on 2026-06-25:
|
||||
|
||||
- MongoDB official client libraries list:
|
||||
`https://www.mongodb.com/docs/drivers/`
|
||||
- MongoDB Node.js driver docs:
|
||||
`https://www.mongodb.com/docs/drivers/node/current/`
|
||||
- MongoDB Node.js transaction docs:
|
||||
`https://www.mongodb.com/docs/drivers/node/current/crud/transactions/`
|
||||
- MongoDB transaction manual:
|
||||
`https://www.mongodb.com/docs/manual/core/transactions/`
|
||||
- MongoDB Atlas App Services EOL notice:
|
||||
`https://www.mongodb.com/docs/api/doc/atlas-app-services-admin-api-v3/`
|
||||
- Deprecated Atlas Data API docs:
|
||||
`https://www.mongodb.com/docs/api/doc/atlas-data-api-v1/`
|
||||
- Dart package checks:
|
||||
`https://pub.dev/packages/mongo_dart` and
|
||||
`https://pub.dev/packages/mongo_db_driver`
|
||||
|
||||
## Decision
|
||||
|
||||
V1 selects a trusted service boundary for MongoDB persistence.
|
||||
|
||||
The MongoDB-owning runtime is a separate Node.js/TypeScript service using the
|
||||
official MongoDB Node.js driver. This service owns:
|
||||
|
||||
- MongoDB connection strings and credentials;
|
||||
- TLS/SRV driver configuration;
|
||||
- client lifecycle and health checks;
|
||||
- index bootstrap from the Block 15 index catalog;
|
||||
- document reads/writes against the V1 collection contract;
|
||||
- sessions and transactions for multi-record scheduling writes;
|
||||
- redacted diagnostics and failure mapping.
|
||||
|
||||
The Flutter UI never connects directly to MongoDB and never receives connection
|
||||
strings, database credentials, raw MongoDB documents, driver clients,
|
||||
collections, sessions, or cursors.
|
||||
|
||||
The pure Dart package remains dependency-free with respect to MongoDB. Dart
|
||||
domain and application code continue to use repository interfaces and typed use
|
||||
case results. The trusted service exposes a narrow versioned application API
|
||||
that maps to the Block 14 use cases and Block 15 document contract.
|
||||
|
||||
During the UI foundation/design spike, the first Flutter UI should use the
|
||||
existing in-memory application composition by default. Persisted development
|
||||
flows may use a local trusted service process, but that process remains outside
|
||||
the Flutter binary and reads secrets only from runtime configuration.
|
||||
|
||||
## Rejected Options
|
||||
|
||||
### Direct MongoDB from Flutter or mobile Dart
|
||||
|
||||
Rejected. It would place database credentials in an untrusted binary and force
|
||||
the UI to own network/database failure modes. It also couples the UI to driver
|
||||
types and makes owner-scope/security mistakes harder to contain.
|
||||
|
||||
### Pure Dart MongoDB adapter as the production V1 foundation
|
||||
|
||||
Rejected for now. MongoDB's official client library list does not include Dart.
|
||||
`mongo_dart` is active and useful for experiments, but it is community-supported
|
||||
rather than an official MongoDB driver. `mongo_db_driver` advertises sessions and
|
||||
transactions, but its package page explicitly identifies it as pre-alpha and not
|
||||
suitable for production. Neither should become the V1 persistence foundation
|
||||
without a later ADR reversing this decision.
|
||||
|
||||
### Atlas Data API, Atlas Device SDKs, App Services, GraphQL, Functions, or
|
||||
Custom HTTPS Endpoints
|
||||
|
||||
Rejected. MongoDB's App Services notice says these paths reached end-of-life on
|
||||
September 30, 2025, with database triggers remaining available. They are not a
|
||||
stable V1 foundation.
|
||||
|
||||
### SQLite or another local fallback
|
||||
|
||||
Rejected. MongoDB remains the committed persistence target. A disconnected
|
||||
fallback would add an unplanned sync/reconciliation problem and violate the
|
||||
current persistence target rules.
|
||||
|
||||
## Driver and Deployment Requirements
|
||||
|
||||
The selected service must use the official MongoDB Node.js driver current major
|
||||
line at implementation time.
|
||||
|
||||
Mandatory capabilities:
|
||||
|
||||
- `mongodb+srv://` and TLS-capable connections for Atlas;
|
||||
- BSON fidelity at the adapter edge;
|
||||
- sessions and multi-document transactions;
|
||||
- explicit transaction retry handling for documented retryable categories;
|
||||
- bounded connection and operation timeouts;
|
||||
- graceful startup/shutdown and health checks;
|
||||
- idempotent index creation;
|
||||
- redacted logging;
|
||||
- no raw driver values in public service DTOs.
|
||||
|
||||
MongoDB deployment requirements:
|
||||
|
||||
- Multi-document scheduling writes require MongoDB Server 4.0 or later.
|
||||
- Transaction acceptance requires a transaction-capable deployment. V1 local and
|
||||
CI testing must use a replica set or supported sharded deployment, not a
|
||||
standalone server.
|
||||
- If the service cannot verify transaction capability at startup for a
|
||||
production Mongo-backed configuration, it must fail closed instead of falling
|
||||
back to untracked in-memory writes.
|
||||
|
||||
## Configuration Boundary
|
||||
|
||||
Development configuration:
|
||||
|
||||
- Uses environment variables or a local secret file excluded from git.
|
||||
- May point to a disposable local replica set or scoped Atlas development
|
||||
database.
|
||||
- Must use a database name or prefix that is safe for destructive test cleanup.
|
||||
|
||||
Test configuration:
|
||||
|
||||
- Uses uniquely named disposable databases/collections.
|
||||
- Fails if the configured target does not match the expected test scope.
|
||||
- Redacts connection strings and credentials from test output.
|
||||
|
||||
Production configuration:
|
||||
|
||||
- Secrets come from deployment secret storage.
|
||||
- The Flutter/mobile app receives only service endpoint configuration and
|
||||
application-layer auth/session material once that future work is explicitly
|
||||
planned.
|
||||
- Production authentication, account management, cross-device sync, Atlas
|
||||
provisioning, network allowlists, and cluster creation remain out of scope for
|
||||
this block.
|
||||
|
||||
## Threat and Safety Checklist
|
||||
|
||||
- No MongoDB connection string is committed to source control.
|
||||
- No MongoDB credential is embedded in Flutter, mobile, desktop, or web UI
|
||||
assets.
|
||||
- Normal logs do not include task titles, hidden locked-block names, full
|
||||
documents, connection strings, or credential fragments.
|
||||
- Every repository query and write includes owner scope.
|
||||
- Hidden locked-time details remain hidden by default in service responses.
|
||||
- Duplicate operation IDs are enforced by a unique owner-operation index.
|
||||
- Revision predicates are required for authoritative updates.
|
||||
- Transaction retries are bounded and observable.
|
||||
- A production Mongo connection failure fails closed.
|
||||
- In-memory composition remains available only as explicit local/design-spike
|
||||
wiring, not as a silent production persistence fallback.
|
||||
|
||||
## Consequences
|
||||
|
||||
Block 16.2 must add any MongoDB dependency only in the trusted service/runtime
|
||||
module, not in the pure Dart core package.
|
||||
|
||||
The implementation path should provide two composition roots:
|
||||
|
||||
- in-memory Dart application wiring for tests and UI design work;
|
||||
- trusted service-backed persistence for MongoDB-backed development and future
|
||||
deployment.
|
||||
|
||||
If a later chunk cannot implement the selected service boundary without
|
||||
duplicating scheduling rules unsafely, it must stop and record the blocker
|
||||
rather than embedding credentials in Flutter or adopting an unmaintained driver
|
||||
as a shortcut.
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# V1 ADR 003: Embedded Local Runtime Topology
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
## Context
|
||||
With SQLite as the local persistence engine, V1 no longer requires a separate
|
||||
service process. The entire stack can run inside a single Flutter/Dart desktop
|
||||
binary.
|
||||
|
||||
## Decision
|
||||
* **Embedded DB** – The application opens an on‑disk SQLite file via Drift.
|
||||
* **No background daemon** – starting the desktop app is enough; automated tests
|
||||
use an in‑memory or temporary‑file database.
|
||||
* **Dev hot‑reload** – `scripts/dev.sh` launches Flutter desktop and watches
|
||||
Drift files.
|
||||
* **Pluggable adapters** – A future remote/sync adapter will satisfy the same
|
||||
repository interfaces; switching happens at composition root.
|
||||
|
||||
## Rejected
|
||||
* Running a local Node.js or Go service to host SQLite – unnecessary complexity.
|
||||
* Direct file writes bypassing Drift – loses migration guarantees.
|
||||
|
||||
## Consequences
|
||||
* Deployment simplifies to one executable per platform.
|
||||
* CI can run integration tests without Docker or external DB.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# V1 ADR 004: Repository & Domain Boundary
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
Repository interfaces (`packages/scheduler_persistence`) expose **domain objects only**.
|
||||
Adapters must implement optimistic revision, immutable returns, and pass the Repository Conformance Suite (Block 26).
|
||||
|
||||
No open questions remain.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# V1 ADR 005: Export & Backup Boundary
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
* **Backup** – passphrase‑encrypted SQLite copy (`.sqlite.aes` via AES‑256‑GCM, PBKDF2 200 k rounds).
|
||||
* **Readable export** – JSON and CSV via `ExportController`.
|
||||
|
||||
No open questions remain.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# V1 ADR 006: Schedule Snapshot Policy
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
Persist committed diagnostic snapshots only; bounded retention 30 days or until notices acknowledged.
|
||||
|
||||
No open questions remain.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# V1 ADR 007: Test Strategy
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
Four layers: Unit, Contract, Migration, Integration. CI fails below 80 % line coverage.
|
||||
|
||||
No open questions remain.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# V1 ADR 008: Notification Abstraction
|
||||
|
||||
Status: **Accepted**
|
||||
Date: 2026-06-26
|
||||
|
||||
`NotificationAdapter` interface abstracts scheduling/cancellation and feedback stream. Desktop implementation in `scheduler_notifications_desktop`; Fake adapter for tests.
|
||||
|
||||
No open questions remain.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# V1 Block 19 — Repository & Persistence Abstraction
|
||||
|
||||
**Purpose**: Define repository interfaces and memory adapter.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 19.1 — Define repository interfaces
|
||||
Recommended level: **XHIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Create Dart library **`packages/scheduler_persistence/lib/persistence.dart`** and declare abstract classes `TaskRepository`, `ProjectRepository`, `LockedBlockRepository`, `SettingsRepository`, `ScheduleSnapshotRepository`.
|
||||
2. Each repository must expose **only** domain objects from `packages/scheduler_core` (import that package).
|
||||
3. Add shared value objects in `scheduler_core` if missing (e.g., `Revision`, `OwnerId`, `PageRequest`, `Page<T>`).
|
||||
4. Document every method with triple‑slash Dart doc.
|
||||
5. Publish typedef `RepoResult<T>` = `Either<RepositoryFailure,T>` (use sealed class).
|
||||
|
||||
### Acceptance criteria
|
||||
1. `dart analyze` shows 0 hints in `scheduler_persistence`.
|
||||
2. Running `dart test` passes new autogenerated stub tests in `packages/scheduler_persistence/test/repo_contract_smoke_test.dart`.
|
||||
|
||||
### Completed implementation
|
||||
1. Rehomed the core package to `packages/scheduler_core` with package name `scheduler_core`.
|
||||
2. Added shared repository value objects in `scheduler_core`: `OwnerId`, `Revision`, `PageRequest`, and `Page<T>`.
|
||||
3. Added package `packages/scheduler_persistence` with domain-only repository contracts for tasks, projects, locked blocks, settings, and schedule snapshots.
|
||||
4. Added sealed repository failure types, sealed `Either<L,R>`, and `RepoResult<T>`.
|
||||
5. Added `packages/scheduler_persistence/test/repo_contract_smoke_test.dart`.
|
||||
|
||||
### Verification
|
||||
1. `dart format test/scheduler_core_test.dart packages/scheduler_core packages/scheduler_persistence`: passed.
|
||||
2. `dart analyze`: passed, no issues found.
|
||||
3. `cd packages/scheduler_persistence && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_persistence && dart test`: passed, 3 tests.
|
||||
5. `cd packages/scheduler_core && dart test`: passed, 298 tests.
|
||||
6. `dart test`: passed, 301 tests.
|
||||
|
||||
---
|
||||
|
||||
## Chunk 19.2 — Memory adapter & conformance tests
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Implement **`packages/scheduler_persistence_memory`** with class `InMemoryTaskRepository` etc. They must implement optimistic revision (increment int).
|
||||
2. Add conformance test suite in `scheduler_persistence/test/repo_conformance.dart` with shared `runRepositoryComplianceTests()`.
|
||||
3. Ensure cloning (deep copy) on return values using `jsonEncode/jsonDecode` for simplicity.
|
||||
|
||||
### Acceptance criteria
|
||||
1. In‑memory adapter passes conformance suite covering CRUD, paging, optimistic revision conflict.
|
||||
2. 100% statement coverage > 80% lines in this package.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_persistence_memory` and workspace wiring.
|
||||
2. Added in-memory implementations for task, project, locked block, settings, and schedule snapshot repository contracts.
|
||||
3. Implemented owner scoping, duplicate-id checks, compare-and-set saves/deletes/archives, stale-revision failures, and deterministic offset paging.
|
||||
4. Added JSON round-trip defensive cloning through the existing core document mappers.
|
||||
5. Added shared conformance suite `packages/scheduler_persistence/test/repo_conformance.dart`.
|
||||
6. Added `packages/scheduler_persistence_memory/test/memory_repository_conformance_test.dart` and root test wrapper wiring.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_persistence/test/repo_conformance.dart packages/scheduler_persistence_memory`: passed.
|
||||
3. `dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_persistence && dart analyze`: passed, no issues found.
|
||||
5. `cd packages/scheduler_persistence_memory && dart analyze`: passed, no issues found.
|
||||
6. `cd packages/scheduler_persistence && dart test`: passed, 3 tests.
|
||||
7. `cd packages/scheduler_persistence_memory && dart test`: passed, 7 tests.
|
||||
8. `cd packages/scheduler_core && dart test`: passed, 298 tests.
|
||||
9. `dart test`: passed, 308 tests.
|
||||
10. `cd packages/scheduler_persistence_memory && dart test --coverage=coverage`: passed; generated LCOV line coverage is 93.79% (302/322).
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# V1 Block 20 — SQLite Persistence Adapter Package
|
||||
|
||||
**Purpose**: Implement Drift-based SQLite storage backend.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 20.1 — SQLite schema & Drift setup
|
||||
Recommended level: **XHIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Create new Dart package **`packages/scheduler_persistence_sqlite`** with Drift as dependency.
|
||||
2. Define Drift database `SchedulerDb` with tables: `tasks`, `projects`, `locked_blocks`, `settings`, `snapshots`.
|
||||
3. Fields: follow domain model; include `revision INT`, `owner_id TEXT`.
|
||||
4. Add drift migrations using drift_dev build runner; start at schemaVersion=1.
|
||||
5. Generate DAO classes via build_runner.
|
||||
|
||||
### Acceptance criteria
|
||||
1. `dart run build_runner build --delete-conflicting-outputs` completes with zero errors.
|
||||
2. Generated drift files checked in.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_persistence_sqlite` with Drift, `drift_dev`, and `build_runner` wiring.
|
||||
2. Added `SchedulerDb` in `lib/src/scheduler_db.dart` with `schemaVersion = 1` and `MigrationStrategy(onCreate: createAll)`.
|
||||
3. Added tables for `tasks`, `projects`, `locked_blocks`, `locked_overrides`, `settings`, and `snapshots`.
|
||||
4. Included owner scope and optimistic revision columns on mutable rows.
|
||||
5. Added generated Drift data classes/accessor mixins in `lib/src/scheduler_db.g.dart`.
|
||||
6. Added a schema smoke test that opens an in-memory Drift database and checks the expected table names.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `cd packages/scheduler_persistence_sqlite && dart run build_runner build --delete-conflicting-outputs`: passed, exit 0; current build_runner warned that the option is ignored.
|
||||
3. `dart format packages/scheduler_persistence_sqlite`: passed.
|
||||
4. `cd packages/scheduler_persistence_sqlite && dart analyze`: passed, no issues found.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `cd packages/scheduler_persistence_sqlite && dart test`: passed, 1 test.
|
||||
7. `dart test`: passed, 308 tests.
|
||||
|
||||
---
|
||||
|
||||
## Chunk 20.2 — SQLite adapter implementation & tests
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Implement `SqliteTaskRepository` etc mapping domain objects to Drift rows with explicit converters.
|
||||
2. Use transaction for multi‑record save; ensure optimistic revision by `WHERE revision = ?` clause.
|
||||
3. Add repository conformance tests reused from block19 suite pointed at SQLite adapter (use `sqflite_ffi` in tests).
|
||||
|
||||
### Acceptance criteria
|
||||
1. SQLite adapter passes full conformance suite with `sqflite_ffi` on Linux/Windows/mac.
|
||||
2. Average write latency in test ≤50ms.
|
||||
|
||||
### Completed implementation
|
||||
1. Added `SqliteTaskRepository`, `SqliteProjectRepository`, `SqliteLockedBlockRepository`, `SqliteSettingsRepository`, and `SqliteScheduleSnapshotRepository`.
|
||||
2. Mapped Drift rows to domain objects through the existing core document mappers and explicit row/JSON converters.
|
||||
3. Implemented duplicate-id checks, owner isolation, deterministic paging, archive behavior, snapshot retention deletion, and typed repository failures.
|
||||
4. Implemented optimistic compare-and-set writes/deletes/archives with `WHERE revision = expected` clauses.
|
||||
5. Added SQLite conformance tests using the Block 19 shared suite and an in-memory Drift SQLite executor.
|
||||
6. Added a write-latency test for task inserts and wired SQLite tests into the root test wrapper.
|
||||
|
||||
### Notes
|
||||
1. Tests use Drift `NativeDatabase.memory()` instead of `sqflite_ffi`. A sqflite-backed Drift executor would require `drift_sqflite`, which pulls Flutter SDK dependencies into this pure Dart adapter package.
|
||||
2. The current repository contracts expose single-record writes. No multi-record repository save method exists yet; future multi-record SQLite writes should use `SchedulerDb.transaction`.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_persistence_sqlite`: passed.
|
||||
3. `cd packages/scheduler_persistence_sqlite && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_persistence_sqlite && dart test`: passed, 9 tests.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed, 316 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# V1 Block 21 — Notification Abstraction Layer
|
||||
|
||||
**Purpose**: Define NotificationAdapter contract.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 21.1 — NotificationAdapter contract
|
||||
Recommended level: **XHIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Add package **`packages/scheduler_notifications`**.
|
||||
2. Declare sealed class `NotificationRequest` with fields: `id`, `title`, `body`, `scheduledDateTimeUtc`, `payloadJson`.
|
||||
3. Declare enum `NotificationFeedbackType` (clicked,dismissed,action).
|
||||
4. Define abstract `NotificationAdapter` with methods `Future<void> schedule(NotificationRequest)`, `Future<void> cancel(String id)`, `Stream<NotificationFeedback>`.
|
||||
5. Add stub `FakeNotificationAdapter` for tests emitting events via StreamController.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Package compiles and `dart test` passes stub test `fake_adapter_test.dart`.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_notifications` with public entry points `notifications.dart` and `scheduler_notifications.dart`.
|
||||
2. Added sealed `NotificationRequest` with factory construction and fields `id`, `title`, `body`, `scheduledDateTimeUtc`, and `payloadJson`.
|
||||
3. Added `NotificationFeedbackType` with `clicked`, `dismissed`, and `action`.
|
||||
4. Added `NotificationFeedback` event model.
|
||||
5. Added abstract `NotificationAdapter` with `schedule`, `cancel`, and `feedback`.
|
||||
6. Added `FakeNotificationAdapter` backed by a broadcast `StreamController`.
|
||||
7. Wired fake adapter tests into the root test wrapper.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_notifications`: passed.
|
||||
3. `cd packages/scheduler_notifications && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_notifications && dart test`: passed, 2 tests.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed, 318 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# V1 Block 22 — OS-Notification Package
|
||||
|
||||
**Purpose**: Desktop notification implementation.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 22.1 — Desktop notification adapter
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Create package **`packages/scheduler_notifications_desktop`**.
|
||||
2. Implement adapters per platform with conditional import using `dart:io` Platform.
|
||||
3. For Linux use `notify-send` via `Process.run`; for macOS use `osascript`; for Windows use `win32` Toast via `windows_notification` package.
|
||||
4. Implement fallback to write to stdout if unsupported.
|
||||
5. Add adapter factory `DesktopNotificationAdapter.defaultInstance()`.
|
||||
6. Write integration test using `FakeNotificationAdapter` mocks to assert scheduling logic; skip on CI if platform not supported.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Desktop adapter compiles on all OS; tests skip rather than fail on unsupported.
|
||||
2. Adapter passes NotificationAdapter contract tests.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_notifications_desktop` with public entry points `desktop_notifications.dart` and `scheduler_notifications_desktop.dart`.
|
||||
2. Added `DesktopNotificationAdapter.defaultInstance()` and injectable backend support.
|
||||
3. Added conditional export for IO vs non-IO environments.
|
||||
4. Added Linux `notify-send` backend via `Process.run`.
|
||||
5. Added macOS `osascript` backend via `Process.run`.
|
||||
6. Added stdout/log fallback backend for unsupported platforms and Windows.
|
||||
7. Added desktop adapter tests covering delegation, Linux/macOS command selection, fallback behavior, fake-adapter scheduling workflow, and default adapter construction.
|
||||
8. Wired desktop adapter tests into the root test wrapper.
|
||||
|
||||
### Notes
|
||||
1. Windows currently uses the stdout fallback. Adding `windows_notification` would pull Flutter SDK dependencies into this pure Dart package; a true Windows toast adapter should be revisited if the desktop packaging layer already depends on Flutter.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_notifications_desktop`: passed.
|
||||
3. `cd packages/scheduler_notifications_desktop && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_notifications_desktop && dart test`: passed, 6 tests.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed, 324 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# V1 Block 23 — Export Abstraction Layer
|
||||
|
||||
**Purpose**: Define Export controller and writer interface.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 23.1 — Export controller contract
|
||||
Recommended level: **XHIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Add package **`packages/scheduler_export`**.
|
||||
2. Define abstract class `ExportWriter` with `Future<void> begin(ExportContext)`, `Future<void> writeTask(Task)`, `Future<void> end()`, plus factory registry.
|
||||
3. Define `ExportController` orchestrating repository queries and writer.
|
||||
4. Provide context object with `ownerId`, `timezone`, `version`.
|
||||
|
||||
### Acceptance criteria
|
||||
1. JSONWriter and CSVWriter stubs compile and implement interface.
|
||||
2. Unit test writes small set and verifies output.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_export` with public entry points `export.dart` and `scheduler_export.dart`.
|
||||
2. Added `ExportContext` carrying `ownerId`, `timezone`, and `version`.
|
||||
3. Added `ExportWriter`, `ExportWriterFactory`, and `ExportWriterRegistry` with default `json` and `csv` mappings.
|
||||
4. Added `ExportController` that reads owner-scoped paged tasks through `TaskRepository` and streams them to a writer.
|
||||
5. Added compiling `JsonExportWriter` and `CsvExportWriter` implementations backed by `StringSink`.
|
||||
6. Added unit tests for owner-scoped JSON export, CSV output, and custom writer factory registration.
|
||||
7. Wired export tests into the root test wrapper.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_export`: passed.
|
||||
3. `cd packages/scheduler_export && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_export && dart test`: passed, 3 tests.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed, 327 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
# V1 Block 24 — Backup & Export Library Package
|
||||
|
||||
**Purpose**: Encrypted backup and readable exports.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 24.1 — Encrypted backup implementation
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Within `packages/scheduler_backup`, implement function `Future<File> createEncryptedBackup({required String passphrase})` which copies SQLite file then AES-256 encrypts with `encrypt` package.
|
||||
2. Implement `Future<void> restoreEncryptedBackup(File backup, String passphrase)`.
|
||||
3. Store backup in `~/ADHD_Scheduler/backups/yyyymmdd_hhmm.db.enc`.
|
||||
4. Add CLI script `bin/backup.dart` for manual backups.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Round‑trip backup/restore integration test passes using temp directory.
|
||||
2. Wrong passphrase throws `BackupDecryptionException`.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_backup` with public entry points `backup.dart` and `scheduler_backup.dart`.
|
||||
2. Added `createEncryptedBackup({required String passphrase})` with optional test-path overrides.
|
||||
3. Added `restoreEncryptedBackup(File backup, String passphrase)` with optional target-file override.
|
||||
4. Added default source path `~/ADHD_Scheduler/scheduler.sqlite` and default backup directory `~/ADHD_Scheduler/backups/`.
|
||||
5. Added backup naming as `yyyymmdd_hhmm.db.enc`, with collision suffixes when needed.
|
||||
6. Added authenticated encrypted backup envelope using PBKDF2-HMAC-SHA256 with 200,000 iterations and AES-256-GCM.
|
||||
7. Added `BackupDecryptionException` and `BackupException`.
|
||||
8. Added CLI script `bin/backup.dart` for manual encrypted backups.
|
||||
9. Added temp-directory round-trip and wrong-passphrase tests.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format .` in `packages/scheduler_backup`: passed.
|
||||
3. `cd packages/scheduler_backup && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_backup && dart test`: passed, 2 tests.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed after Chunk 24.2, 332 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
||||
## Chunk 24.2 — Readable export writers
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Implement `JsonExportWriter` and `CsvExportWriter` in `scheduler_export_json` package.
|
||||
2. Hook into `ExportController` factory mapping.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Export command `bin/export.dart --json` outputs valid JSON verified by jsonDecode.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_export_json` with public entry points `export_json.dart` and `scheduler_export_json.dart`.
|
||||
2. Added concrete `JsonExportWriter` and `CsvExportWriter` implementations.
|
||||
3. Added `readableExportWriterRegistry()` that maps `json` and `csv` writer factories for `ExportController`.
|
||||
4. Added CLI script `bin/export.dart` supporting `--json`, `--csv`, `--owner`, and `--timezone`.
|
||||
5. Added tests for JSON export, CSV quoting, and `bin/export.dart --json` output validated with `jsonDecode`.
|
||||
6. Wired export-json tests into the root test wrapper.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_export_json`: passed.
|
||||
3. `cd packages/scheduler_export_json && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_export_json && dart test`: passed, 3 tests.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed, 332 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# V1 Block 25 — Scheduler Integration Tests
|
||||
|
||||
**Purpose**: End‑to‑end tests.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 25.1 — Integration test harness
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Add test file `integration/scheduler_flow_test.dart` in `packages/scheduler_integration_tests`.
|
||||
2. Spin up InMemory repos, schedule engine, fake notification adapter.
|
||||
3. Create tasks, invoke scheduler, assert placements, save via SQLite adapter, reload and assert persistence.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Test passes on CI in < 2s runtime.
|
||||
|
||||
### Completed implementation
|
||||
1. Added package `packages/scheduler_integration_tests`.
|
||||
2. Added required integration test file `integration/scheduler_flow_test.dart`.
|
||||
3. Added test wrapper `test/scheduler_flow_test.dart` so package-level `dart test` runs the integration flow.
|
||||
4. Integration flow seeds `InMemoryTaskRepository`, invokes `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot`, asserts task placement, schedules through `FakeNotificationAdapter`, saves through `SqliteTaskRepository`, reloads, and asserts persisted schedule/status.
|
||||
5. Added an in-test runtime guard asserting the flow completes in under 2 seconds.
|
||||
6. Wired integration test into the root test wrapper.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format test/scheduler_core_test.dart packages/scheduler_integration_tests`: passed.
|
||||
3. `cd packages/scheduler_integration_tests && dart analyze`: passed, no issues found.
|
||||
4. `cd packages/scheduler_integration_tests && dart test`: passed, 1 test.
|
||||
5. `dart analyze`: passed, no issues found.
|
||||
6. `dart test`: passed, 333 tests.
|
||||
7. `scripts/test.sh`: not present or not executable.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# V1 Block 26 — Verification & Contract Test Suite
|
||||
|
||||
**Purpose**: Repository contract tests.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 26.1 — Coverage & adapter verification
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Extend repo conformance tests to compute coverage report using `dart run coverage`.
|
||||
2. Fail CI if coverage < 80%.
|
||||
3. Ensure desktop notification adapter passes mock contract tests.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Coverage report generated in CI artifacts; threshold met.
|
||||
|
||||
### Completed implementation
|
||||
1. Added root dev dependency `coverage`.
|
||||
2. Added executable `scripts/test.sh` running `dart analyze`, `dart test`, `dart run coverage:test_with_coverage`, and an 80% coverage threshold check.
|
||||
3. Added `tool/check_coverage.dart` to parse `coverage/lcov.info`, scope coverage to package `lib/` code, exclude generated `.g.dart`, and fail below threshold.
|
||||
4. Added shared notification adapter contract test helper `packages/scheduler_notifications/test/notification_adapter_contract.dart`.
|
||||
5. Ran the contract against `FakeNotificationAdapter`.
|
||||
6. Ran the same contract against `DesktopNotificationAdapter` using a recording backend.
|
||||
7. Normalized desktop adapter cancellation ids before passing them to the backend.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format ...`: passed for touched Dart files.
|
||||
3. `cd packages/scheduler_notifications && dart analyze && dart test`: passed, 4 tests.
|
||||
4. `cd packages/scheduler_notifications_desktop && dart analyze && dart test`: passed, 8 tests.
|
||||
5. `scripts/test.sh`: passed.
|
||||
6. Coverage result: 83.31% package `lib/` line coverage, above the 80% threshold.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# V1 Block 27 — Deployment & Dev Experience
|
||||
|
||||
**Purpose**: Dev scripts and packaging.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 27.1 — Dev/test scripts & CI
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Create `scripts/dev.dart` which executes `dart run build_runner watch` and launches Flutter desktop with hot reload pointing to local SQLite file.
|
||||
2. Create `scripts/test.dart` running `dart pub global activate coverage`, `dart test --coverage=coverage`, then combine reports.
|
||||
3. GitHub Actions YAML to run tests matrix {ubuntu-latest, windows-latest, macos-latest}.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Running `dart run scripts/dev.dart` starts app and prints sqlite path.
|
||||
2. CI green on all platforms.
|
||||
|
||||
### Completed implementation
|
||||
1. Added `scripts/dev.dart` that prints the SQLite path, starts `dart run build_runner watch --delete-conflicting-outputs`, and launches `flutter run` for the current/selected desktop device with `SCHEDULER_SQLITE_PATH`.
|
||||
2. Added `scripts/test.dart` that runs `dart pub global activate coverage`, `dart test --coverage=coverage`, combines LCOV with `coverage:format_coverage`, and enforces the 80% threshold.
|
||||
3. Updated `scripts/test.sh` to run analyzer plus `scripts/test.dart`.
|
||||
4. Added GitHub Actions workflow `.github/workflows/ci.yml` with test matrix `ubuntu-latest`, `windows-latest`, and `macos-latest`.
|
||||
5. Added `scripts/bootstrap_dev.sh` and `scripts/dev.sh` wrappers so the
|
||||
agent rule file has concrete shell entry points for setup and development.
|
||||
|
||||
### Verification
|
||||
1. `dart pub get`: passed.
|
||||
2. `dart format scripts/dev.dart scripts/test.dart`: passed.
|
||||
3. `dart analyze`: passed, no issues found.
|
||||
4. `dart run scripts/test.dart`: passed, coverage 83.27%.
|
||||
5. `bash -n scripts/bootstrap_dev.sh scripts/dev.sh`: passed.
|
||||
6. `scripts/test.sh`: passed.
|
||||
7. `dart run scripts/dev.dart` and `scripts/dev.sh`: not executed locally because they launch a long-running Flutter desktop session and require the Flutter app/toolchain.
|
||||
|
||||
---
|
||||
|
||||
## Chunk 27.2 — Packaging scripts
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Add `scripts/build.dart` building Flutter macOS .app, Windows .exe + msix, Linux AppImage.
|
||||
2. Document prerequisites in README.
|
||||
|
||||
### Acceptance criteria
|
||||
1. Artifacts upload step in CI produces release binaries.
|
||||
|
||||
### Completed implementation
|
||||
1. Added `scripts/build.dart` with platform targets `current`, `macos`, `windows`, and `linux`.
|
||||
2. macOS target runs `flutter build macos --release` and copies `.app` artifacts.
|
||||
3. Windows target runs `flutter build windows --release`, copies the release bundle, and runs `dart run msix:create`.
|
||||
4. Linux target runs `flutter build linux --release` and `appimage-builder --recipe AppImageBuilder.yml --skip-test`.
|
||||
5. Added tagged CI packaging job with matrix `linux`, `windows`, and `macos`, plus artifact upload from `build/releases/`.
|
||||
6. Replaced README with workspace test, development, packaging, and prerequisite instructions.
|
||||
7. Added `scripts/package_release.sh` wrapper for the release packaging runner
|
||||
named in the agent rule file.
|
||||
|
||||
### Verification
|
||||
1. `dart format scripts/build.dart`: passed.
|
||||
2. `dart analyze`: passed, no issues found.
|
||||
3. `bash -n scripts/package_release.sh`: passed.
|
||||
4. `scripts/test.sh`: passed.
|
||||
5. Packaging commands were not executed locally because they require Flutter desktop toolchains, platform-specific packaging tools, and app packaging config.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# V1 Block 28 — Project‑wide Documentation Sweep
|
||||
|
||||
**Purpose**: JavaDoc-style commenting.
|
||||
|
||||
> **Note for Codex**: Follow tasks exactly; avoid exploratory calls when tasks specify names/files/tests.
|
||||
|
||||
## Chunk 28.1 — Documentation sweep
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Enable `dart doc` in CI; fail build if undocumented public members.
|
||||
2. Add docs to all public symbols across packages using triple‑slash style.
|
||||
3. Document build scripts and CI YAML with comments at top describing purpose.
|
||||
|
||||
### Acceptance criteria
|
||||
1. `dart doc` generates site without warnings.
|
||||
2. CI passes doc coverage gate.
|
||||
|
||||
### Completed implementation
|
||||
1. Added `tool/check_docs.dart` to generate docs for every package with a `lib/` directory under `doc/api/packages/`.
|
||||
2. The doc gate fails on any `dart doc` warning or nonzero doc generation exit.
|
||||
3. Added doc generation to `scripts/test.dart`, so `scripts/test.sh` and CI run the docs gate.
|
||||
4. Updated CI artifact upload to include generated docs under `doc/api/`.
|
||||
5. Added `.gitignore` entry for generated `doc/api/` output.
|
||||
6. Fixed unresolved documentation references in `scheduler_core`, `scheduler_export`, and `scheduler_export_json`.
|
||||
7. Added top-of-file purpose comments to `scripts/dev.dart`, `scripts/test.dart`, `scripts/build.dart`, `tool/check_coverage.dart`, `tool/check_docs.dart`, and `.github/workflows/ci.yml`.
|
||||
|
||||
### Verification
|
||||
1. `dart run tool/check_docs.dart`: passed; docs generated for all public-library packages with 0 warnings and 0 errors.
|
||||
2. `dart analyze`: passed, no issues found.
|
||||
3. `scripts/test.sh`: passed.
|
||||
4. Coverage result in final gate: 83.27% package `lib/` line coverage, above the 80% threshold.
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
# V1 Block 29 — Flutter UI Foundation
|
||||
|
||||
**Purpose**: Restart the V1 Flutter UI foundation after the SQLite-first backend
|
||||
refresh, without moving scheduling or persistence rules into widgets.
|
||||
|
||||
> **Note for Codex**: Keep the scheduler core Flutter-free. UI code may depend
|
||||
> on public package APIs and read models only.
|
||||
|
||||
## Chunk 29.1 — Flutter app shell and in-memory composition
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Add `apps/focus_flow_flutter` as a Flutter application outside the root Dart
|
||||
workspace for now.
|
||||
2. Wire a minimal in-memory composition root using public scheduler packages.
|
||||
3. Render provisional Today and Backlog shells from application/read-model data.
|
||||
4. Add app startup, theme/token placeholders, and a widget test harness.
|
||||
5. Document UI-specific analyze/test commands without changing `scripts/test.sh`
|
||||
until Flutter CI gating is intentionally added.
|
||||
|
||||
### Acceptance criteria
|
||||
1. `cd apps/focus_flow_flutter && flutter analyze` passes.
|
||||
2. `cd apps/focus_flow_flutter && flutter test` passes.
|
||||
3. Core packages remain Flutter-free and `scripts/test.sh` still passes.
|
||||
4. UI code does not import Drift, SQLite, platform notification APIs, or core
|
||||
`lib/src/` paths directly.
|
||||
5. Today and Backlog screens render from read-model objects, not duplicated
|
||||
scheduling rules.
|
||||
|
||||
BREAKPOINT: Stop here. Confirm `high` before adding navigation/controllers and
|
||||
component contracts.
|
||||
|
||||
### Completed implementation
|
||||
1. Added `apps/focus_flow_flutter` as a Flutter desktop app outside the root
|
||||
Dart workspace.
|
||||
2. Added a local path dependency on `packages/scheduler_core`.
|
||||
3. Replaced the starter counter template with `FocusFlowApp`, a seeded
|
||||
`DemoSchedulerComposition`, and Today/Backlog tabs rendered from
|
||||
`TodayState` and `BacklogQueryResult`.
|
||||
4. Added a widget test that verifies Today and Backlog read-model data renders
|
||||
through the Flutter shell.
|
||||
5. Documented app-local Flutter analyze/test commands in the README.
|
||||
|
||||
### Verification
|
||||
1. `flutter pub get` in `apps/focus_flow_flutter`: passed.
|
||||
2. `dart format apps/focus_flow_flutter/lib/main.dart apps/focus_flow_flutter/test/widget_test.dart`: passed.
|
||||
3. `cd apps/focus_flow_flutter && flutter analyze`: passed, no issues found.
|
||||
4. `cd apps/focus_flow_flutter && flutter test`: passed, 1 widget test.
|
||||
|
||||
---
|
||||
|
||||
## Chunk 29.2 — UI controllers and component contracts
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Complete on 2026-06-26.
|
||||
|
||||
### Tasks
|
||||
1. Split seeded composition, read controllers, and widgets into focused files
|
||||
under `apps/focus_flow_flutter/lib/`.
|
||||
2. Add controller states for loading, empty, typed failure, and retry paths for
|
||||
Today and Backlog.
|
||||
3. Add provisional component contracts for timeline rows, compact panels,
|
||||
backlog rows, notice banners, and staleness markers.
|
||||
4. Centralize token-to-visual mapping for project color, task type background,
|
||||
reward icon, and difficulty icon.
|
||||
5. Add widget tests for compact rendering, backlog empty state, and typed failure
|
||||
state.
|
||||
|
||||
### Acceptance criteria
|
||||
1. `cd apps/focus_flow_flutter && flutter analyze` passes.
|
||||
2. `cd apps/focus_flow_flutter && flutter test` passes.
|
||||
3. `scripts/test.sh` still passes.
|
||||
4. Widgets import app controllers/read models, not persistence adapters or
|
||||
scheduler internals.
|
||||
5. Component contracts satisfy the remaining MVP-AC-05 token-mapping gap without
|
||||
locking final visual design.
|
||||
|
||||
BREAKPOINT: Stop here. Confirm `high` before adding command flows and a vertical
|
||||
quick-capture smoke slice.
|
||||
|
||||
### Completed implementation
|
||||
1. Split `lib/main.dart` into app shell, seeded composition, read controllers,
|
||||
visual-token mapping, and focused widgets under `apps/focus_flow_flutter/lib/`.
|
||||
2. Added `UiReadController<T>` and `ApplicationReadController<T>` with loading,
|
||||
data, empty, typed-failure, and retry states.
|
||||
3. Added provisional component contracts for compact panels, timeline rows,
|
||||
backlog rows, notice banners, staleness markers, empty state, and failure
|
||||
state.
|
||||
4. Centralized project color, task-type background, reward icon, difficulty
|
||||
icon, and staleness-marker visual mapping in `SchedulerVisualTokens`.
|
||||
5. Added widget tests for seeded Today/Backlog rendering, compact rendering,
|
||||
Backlog empty state, and typed failure retry.
|
||||
|
||||
### Verification
|
||||
1. `dart format lib test` in `apps/focus_flow_flutter`: passed.
|
||||
2. `cd apps/focus_flow_flutter && flutter analyze`: passed, no issues found.
|
||||
3. `cd apps/focus_flow_flutter && flutter test`: passed, 4 widget tests.
|
||||
4. Forbidden-import scan for app `lib/` and `test/`: no persistence adapters,
|
||||
scheduler `src/` imports, Drift, or SQLite imports found.
|
||||
|
||||
---
|
||||
|
||||
## Chunk 29.3 — Command flows and vertical quick-capture slice
|
||||
Recommended level: **HIGH**
|
||||
|
||||
Status: Open.
|
||||
|
||||
### Tasks
|
||||
1. Add UI controllers for quick capture, schedule-from-backlog, and mark-done
|
||||
commands using public application command use cases.
|
||||
2. Add forms/actions for title-only quick capture, duration entry, and done.
|
||||
3. Refresh Today and Backlog controllers after successful commands.
|
||||
4. Add typed conflict/failure states for command attempts.
|
||||
5. Add a widget/integration smoke test for quick capture → Backlog → schedule →
|
||||
Today → done using in-memory composition.
|
||||
|
||||
### Acceptance criteria
|
||||
1. `cd apps/focus_flow_flutter && flutter analyze` passes.
|
||||
2. `cd apps/focus_flow_flutter && flutter test` passes.
|
||||
3. `scripts/test.sh` still passes.
|
||||
4. Widgets continue to call public app controllers/use cases only.
|
||||
5. No scheduling rules are implemented in Flutter widgets.
|
||||
|
||||
BREAKPOINT: Stop here. Confirm `high` before adding persistent SQLite-backed UI
|
||||
composition or broader screen expansion.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
|
@ -7,7 +7,7 @@ Starting commit: `775c2ed406f03a73a9b0ca621dea5b4482468616`
|
|||
Public import:
|
||||
|
||||
```dart
|
||||
import 'package:adhd_scheduler_core/scheduler_core.dart';
|
||||
import 'package:scheduler_core/scheduler_core.dart';
|
||||
```
|
||||
|
||||
The public library entry point is `lib/scheduler_core.dart`. It exports the
|
||||
|
|
@ -398,23 +398,185 @@ Chunk 15.5 intentionally changed the public API:
|
|||
`PersistencePayloadGuard`.
|
||||
- Added repository integrity failure codes for invalid revisions and owner
|
||||
mismatches.
|
||||
- Added `V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md` for MongoDB adapter
|
||||
implementation prerequisites.
|
||||
- Added `V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md` for the former document
|
||||
adapter implementation prerequisites, archived after the SQLite-first pivot.
|
||||
|
||||
Chunk 19.1 intentionally changed the public/package API:
|
||||
|
||||
- Rehomed the core library under `packages/scheduler_core` with public import
|
||||
`package:scheduler_core/scheduler_core.dart`.
|
||||
- Added shared repository value objects exported from `scheduler_core`:
|
||||
`OwnerId`, `Revision`, `PageRequest`, and `Page<T>`.
|
||||
- Added `packages/scheduler_persistence` with domain-only repository
|
||||
interfaces for tasks, projects, locked blocks, settings, and schedule
|
||||
snapshots.
|
||||
- Added `RepositoryFailure` variants, sealed `Either<L, R>`, and
|
||||
`RepoResult<T>` for expected repository success/failure paths.
|
||||
|
||||
Chunk 19.2 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_persistence_memory` with
|
||||
`InMemoryTaskRepository`, `InMemoryProjectRepository`,
|
||||
`InMemoryLockedBlockRepository`, `InMemorySettingsRepository`, and
|
||||
`InMemoryScheduleSnapshotRepository`.
|
||||
- Added package entry points
|
||||
`package:scheduler_persistence_memory/persistence_memory.dart` and
|
||||
`package:scheduler_persistence_memory/memory.dart`.
|
||||
- Added shared adapter conformance test surface
|
||||
`runRepositoryComplianceTests()` and `RepositoryComplianceFactories` under
|
||||
`packages/scheduler_persistence/test/repo_conformance.dart`.
|
||||
|
||||
Chunk 20.1 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_persistence_sqlite` with Drift-backed schema
|
||||
package entry point `package:scheduler_persistence_sqlite/sqlite.dart`.
|
||||
- Added `SchedulerDb` with schema version 1 and generated Drift table/data
|
||||
classes for `tasks`, `projects`, `locked_blocks`, `locked_overrides`,
|
||||
`settings`, and `snapshots`.
|
||||
- Added generated accessor classes: `TaskDao`, `ProjectDao`, `LockedBlockDao`,
|
||||
`SettingsDao`, and `SnapshotDao`.
|
||||
|
||||
Chunk 20.2 intentionally changed the public/package API:
|
||||
|
||||
- Added SQLite repository implementations exported from
|
||||
`package:scheduler_persistence_sqlite/sqlite.dart`:
|
||||
`SqliteTaskRepository`, `SqliteProjectRepository`,
|
||||
`SqliteLockedBlockRepository`, `SqliteSettingsRepository`, and
|
||||
`SqliteScheduleSnapshotRepository`.
|
||||
- Added SQLite adapter conformance and write-latency tests under
|
||||
`packages/scheduler_persistence_sqlite/test/`.
|
||||
|
||||
Chunk 21.1 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_notifications` with package entry points
|
||||
`package:scheduler_notifications/notifications.dart` and
|
||||
`package:scheduler_notifications/scheduler_notifications.dart`.
|
||||
- Added notification abstraction types: `NotificationRequest`,
|
||||
`NotificationFeedbackType`, `NotificationFeedback`, `NotificationAdapter`,
|
||||
and `FakeNotificationAdapter`.
|
||||
|
||||
Chunk 22.1 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_notifications_desktop` with package entry points
|
||||
`package:scheduler_notifications_desktop/desktop_notifications.dart` and
|
||||
`package:scheduler_notifications_desktop/scheduler_notifications_desktop.dart`.
|
||||
- Added desktop notification types: `DesktopNotificationPlatform`,
|
||||
`DesktopNotificationBackend`, `DesktopNotificationAdapter`,
|
||||
`StdoutNotificationBackend`, and the IO backends for Linux/macOS.
|
||||
|
||||
Chunk 23.1 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_export` with package entry points
|
||||
`package:scheduler_export/export.dart` and
|
||||
`package:scheduler_export/scheduler_export.dart`.
|
||||
- Added readable export contracts and orchestration types: `ExportContext`,
|
||||
`ExportWriter`, `ExportWriterFactory`, `ExportWriterRegistry`,
|
||||
`ExportController`, `ExportException`, and `ExportRepositoryException`.
|
||||
- Added sink-backed writer implementations `JsonExportWriter` and
|
||||
`CsvExportWriter`.
|
||||
|
||||
Chunk 24.1 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_backup` with package entry points
|
||||
`package:scheduler_backup/backup.dart` and
|
||||
`package:scheduler_backup/scheduler_backup.dart`.
|
||||
- Added encrypted backup functions `createEncryptedBackup`,
|
||||
`restoreEncryptedBackup`, `defaultSchedulerSqliteFile`, and
|
||||
`defaultSchedulerBackupDirectory`.
|
||||
- Added backup constants `defaultSchedulerDirectoryName`,
|
||||
`defaultSchedulerDatabaseFileName`, and
|
||||
`defaultSchedulerBackupDirectoryName`.
|
||||
- Added backup exceptions `BackupException` and
|
||||
`BackupDecryptionException`.
|
||||
|
||||
Chunk 24.2 intentionally changed the public/package API:
|
||||
|
||||
- Added `packages/scheduler_export_json` with package entry points
|
||||
`package:scheduler_export_json/export_json.dart` and
|
||||
`package:scheduler_export_json/scheduler_export_json.dart`.
|
||||
- Added readable writer factory `readableExportWriterRegistry`.
|
||||
- Added concrete readable export writers `JsonExportWriter` and
|
||||
`CsvExportWriter`.
|
||||
- Added CLI export command `bin/export.dart`.
|
||||
|
||||
Chunk 25.1 intentionally changed the workspace test surface:
|
||||
|
||||
- Added test-only package `packages/scheduler_integration_tests`.
|
||||
- Added integration harness `integration/scheduler_flow_test.dart` covering
|
||||
scheduler placement, fake notification scheduling, SQLite save, and reload.
|
||||
|
||||
Chunk 26.1 intentionally changed the verification surface:
|
||||
|
||||
- Added executable `scripts/test.sh` as the required analyze/test/coverage gate.
|
||||
- Added `tool/check_coverage.dart` for LCOV threshold enforcement.
|
||||
- Added shared notification adapter contract test helper
|
||||
`packages/scheduler_notifications/test/notification_adapter_contract.dart`.
|
||||
- Desktop notification adapter cancellation now normalizes ids before backend
|
||||
cancellation.
|
||||
|
||||
Chunk 27.1 intentionally changed the dev/CI surface:
|
||||
|
||||
- Added `scripts/dev.dart` for local build-runner watch plus Flutter desktop
|
||||
launch with a SQLite path define.
|
||||
- Added `scripts/test.dart` for cross-platform coverage collection and LCOV
|
||||
combination.
|
||||
- Added `scripts/bootstrap_dev.sh` and `scripts/dev.sh` shell entry points for
|
||||
agent-compatible setup and desktop development.
|
||||
- Added GitHub Actions test matrix in `.github/workflows/ci.yml`.
|
||||
|
||||
Chunk 27.2 intentionally changed the packaging surface:
|
||||
|
||||
- Added `scripts/build.dart` for platform-specific Flutter desktop packaging.
|
||||
- Added `scripts/package_release.sh` shell entry point for release packaging.
|
||||
- Added tagged CI release artifact upload steps.
|
||||
- Replaced README content with workspace test, dev, packaging, and prerequisite
|
||||
instructions.
|
||||
|
||||
Chunk 28.1 intentionally changed the documentation verification surface:
|
||||
|
||||
- Added `tool/check_docs.dart` to generate package docs and fail on warnings.
|
||||
- Added generated docs upload under the CI artifact step.
|
||||
- Added generated `doc/api/` output to `.gitignore`.
|
||||
- Fixed unresolved public API documentation references in core and export
|
||||
packages.
|
||||
|
||||
Chunk 29.1 intentionally changed the UI surface:
|
||||
|
||||
- Added provisional Flutter app `apps/focus_flow_flutter` outside the root Dart
|
||||
workspace.
|
||||
- Added app-local path dependency on `packages/scheduler_core`.
|
||||
- Added `FocusFlowApp`, `DemoSchedulerComposition`, `SchedulerHome`,
|
||||
`TodayPane`, and `BacklogPane` in the Flutter app.
|
||||
- Added widget test coverage for rendering Today and Backlog read-model data.
|
||||
|
||||
Chunk 29.2 intentionally changed the UI surface:
|
||||
|
||||
- Split the Flutter shell into `app.dart`, `composition/`, `controllers/`,
|
||||
`theme/`, and `widgets/`.
|
||||
- Added `UiReadController<T>`, `ApplicationReadController<T>`, and
|
||||
`SchedulerReadState<T>` variants for loading, data, empty, and typed failure
|
||||
states.
|
||||
- Added `SchedulerVisualTokens` for centralized project/task/reward/difficulty
|
||||
and staleness visual mappings.
|
||||
- Added component widgets for Today, Backlog, compact panels, timeline rows,
|
||||
backlog rows, notice banners, empty states, and failure retry states.
|
||||
- Expanded Flutter widget coverage to 4 tests.
|
||||
|
||||
## Repository contracts
|
||||
|
||||
The current repository surface is pure Dart and in-memory only:
|
||||
The current repository surface is pure Dart and adapter-backed:
|
||||
|
||||
- Task repository behavior is represented by `InMemoryTaskRepository`.
|
||||
- Project repository behavior is represented by `InMemoryProjectRepository`.
|
||||
- Locked block repository behavior is represented by
|
||||
`InMemoryLockedBlockRepository`.
|
||||
- Snapshot repository behavior is represented by
|
||||
`InMemorySchedulingSnapshotRepository`.
|
||||
- Core legacy repository fakes remain in `scheduler_core` for existing domain
|
||||
services and tests.
|
||||
- The Block 19 repository abstraction lives in `scheduler_persistence`.
|
||||
- The Block 19 conformance-tested memory adapter lives in
|
||||
`scheduler_persistence_memory`.
|
||||
- The Block 20 conformance-tested SQLite adapter lives in
|
||||
`scheduler_persistence_sqlite`.
|
||||
- Application transaction behavior is represented by
|
||||
`InMemoryApplicationUnitOfWork`.
|
||||
- Application read-query behavior uses `ApplicationUnitOfWork.read`, which
|
||||
stages repository access without committing operation records.
|
||||
|
||||
Future MongoDB adapter work must remain behind repository interfaces and must
|
||||
not import MongoDB APIs into the scheduling core.
|
||||
Future SQLite adapter work must remain behind repository interfaces and must not
|
||||
import storage APIs into the scheduling core.
|
||||
|
|
|
|||
|
|
@ -99,19 +99,19 @@ Status values:
|
|||
| ID | Acceptance criterion | Production API surface | Representative tests | Status | Active-plan reference or issue |
|
||||
|---|---|---|---|---|---|
|
||||
| MVP-AC-01 | Create a task through quick capture with only a title. | `V1ApplicationCommandUseCases.quickCaptureToBacklog`, `Task.quickCapture`, `QuickCaptureRequest`, `QuickCaptureService.capture` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds the atomic application command boundary. |
|
||||
| MVP-AC-02 | Store quick-capture tasks in Backlog with neutral defaults. | `Task.quickCapture`, `QuickCaptureService.capture`, `TaskStatus.backlog`, `PriorityLevel.medium`, `RewardLevel.notSet`, inbox project default | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | complete | Backlog-entered timestamp remains incomplete; see Blocks 11 and 15. |
|
||||
| MVP-AC-02 | Store quick-capture tasks in Backlog with neutral defaults. | `Task.quickCapture`, `QuickCaptureService.capture`, `TaskStatus.backlog`, `PriorityLevel.medium`, `RewardLevel.notSet`, inbox project default, `TaskDocumentFields.backlogEnteredAt` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/document_mapping_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart` | complete | Backlog-entered timestamp fields are covered by document mapping and SQLite persistence. |
|
||||
| MVP-AC-03 | Optionally schedule a quick-capture task into the next available slot after entering duration. | `V1ApplicationCommandUseCases.quickCaptureToNextAvailableSlot`, `QuickCaptureRequest.scheduleImmediately`, `QuickCaptureService.capture`, `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/scheduling_invariants_test.dart`, `test/application_commands_test.dart` | complete | Block 12 covers scheduling rules; Chunk 14.3 adds the atomic application command boundary. |
|
||||
| MVP-AC-04 | Create recurring hidden locked blocks and one-day overrides. | `LockedBlock`, `LockedBlockRecurrence.weekly`, `LockedBlockOverride.remove`, `LockedBlockOverride.replace`, `LockedBlockOverride.add`, `expandLockedBlocksForDay` | `test/scheduling_engine_test.dart`, `test/timeline_state_test.dart`, `test/edge_case_regression_test.dart` | complete | Date-only/time-zone hardening remains in Chunk 11.4 and Block 15. |
|
||||
| MVP-AC-05 | Render Today as a timeline with project border, task-type background, task name, reward icon, and difficulty icon. | `GetTodayStateQuery`, `TodayState`, `TodayTimelineItem`, `TimelineItemMapper`, `TimelineItem`, timeline token enums | `test/timeline_state_test.dart`, `test/today_state_test.dart` | incomplete | Backend Today read model and tokens are complete; actual Flutter rendering is Block 18. |
|
||||
| MVP-AC-06 | Use compact Today mode manually. | `GetTodayStateQuery`, `TodayCompactState`, `TimelineItemMapper.compactStateForTasks`, `CompactTimelineState` | `test/timeline_state_test.dart`, `test/today_state_test.dart` | complete | Complete at backend/read-model level, including current/next deduplication; Flutter UI remains Block 18. |
|
||||
| MVP-AC-05 | Render Today as a timeline with project border, task-type background, task name, reward icon, and difficulty icon. | `GetTodayStateQuery`, `TodayState`, `TodayTimelineItem`, `TimelineItemMapper`, `TimelineItem`, timeline token enums, `TodayPane`, `TimelineRow`, `SchedulerVisualTokens` | `test/timeline_state_test.dart`, `test/today_state_test.dart`, `apps/focus_flow_flutter/test/widget_test.dart` | complete | Backend Today read model and provisional Flutter token-driven rendering are complete through Block 29.2; final visual design remains intentionally open. |
|
||||
| MVP-AC-06 | Use compact Today mode manually. | `GetTodayStateQuery`, `TodayCompactState`, `TimelineItemMapper.compactStateForTasks`, `CompactTimelineState`, `CompactPanel` | `test/timeline_state_test.dart`, `test/today_state_test.dart`, `test/application_management_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart`, `apps/focus_flow_flutter/test/widget_test.dart` | complete | Complete at backend/read-model and settings-persistence level, including current/next deduplication; Block 29.2 renders compact state through a component contract, while a user-facing toggle remains a later UI command/control task. |
|
||||
| MVP-AC-07 | Push flexible tasks to next available slot, tomorrow, or backlog. | `V1ApplicationCommandUseCases.pushFlexibleToNextAvailableSlot`, `V1ApplicationCommandUseCases.pushFlexibleToTomorrowTopOfQueue`, `V1ApplicationCommandUseCases.moveFlexibleToBacklog`, `FlexibleTaskActionService.applyPushDestination`, `SchedulingEngine` push methods, `TaskActivityCode` | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/task_lifecycle_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic application commands with persisted activities and operation records. |
|
||||
| MVP-AC-08 | Move backlog items into the soonest flexible slot where they fit and shift later flexible tasks. | `V1ApplicationCommandUseCases.scheduleBacklogItemToNextAvailableSlot`, `SchedulingEngine.insertBacklogTaskIntoNextAvailableSlot` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/occupancy_policy_test.dart`, `test/free_slots_test.dart`, `test/scheduling_invariants_test.dart`, `test/application_commands_test.dart` | complete | Block 12 covers scheduling rules; Chunk 14.3 adds the atomic application command boundary. |
|
||||
| MVP-AC-09 | Automatically roll unfinished flexible tasks to tomorrow/top of queue with a small notice. | `SchedulingEngine.rolloverUnfinishedFlexibleTasks`, `SchedulingNotice`, `TodayPendingNotice`, `GetTodayStateQuery` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/scheduling_invariants_test.dart`, `test/today_state_test.dart` | incomplete | Domain movement, structured rollover notices, and Today pending-notice read model exist; explicit durable app-open rollover orchestration remains in Chunk 14.5. |
|
||||
| MVP-AC-09 | Automatically roll unfinished flexible tasks to tomorrow/top of queue with a small notice. | `SchedulingEngine.rolloverUnfinishedFlexibleTasks`, `SchedulingNotice`, `TodayPendingNotice`, `GetTodayStateQuery`, `V1AppOpenRecoveryUseCases` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/scheduling_invariants_test.dart`, `test/today_state_test.dart`, `test/application_recovery_test.dart` | complete | Domain movement, durable app-open recovery orchestration, scheduling snapshots, and Today pending-notice lifecycle are complete. |
|
||||
| MVP-AC-10 | Log unplanned completed tasks and push overlapping flexible tasks normally. | `V1ApplicationCommandUseCases.logSurpriseTask`, `SurpriseTaskLogRequest`, `SurpriseTaskLogService.log`, `SurpriseTaskLogResult`, `Task.completedAt` | `test/surprise_task_logging_test.dart`, `test/scheduling_invariants_test.dart`, `test/task_lifecycle_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic surprise logging use case with flexible repair, activity persistence, project stats, and operation records. |
|
||||
| MVP-AC-11 | Break a large task into child tasks with row-level priority, reward, and duration. | `V1ApplicationCommandUseCases.breakUpTask`, `ApplicationChildTaskDraft`, `ChildTaskEntry`, `ChildTaskBreakUpRequest`, `ChildTaskBreakUpResult`, `ChildTaskBreakUpService`, `ChildTaskView` | `test/child_tasks_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic child break-up command wiring. |
|
||||
| MVP-AC-12 | Auto-complete parent tasks when all children are done and allow force-completing all children from the parent or a child. | `V1ApplicationCommandUseCases.completeChildTask`, `V1ApplicationCommandUseCases.completeParentTask`, `V1ApplicationCommandUseCases.completeParentFromChild`, `ChildTaskCompletionService`, `ChildTaskCompletionResult`, parent-child helpers, `TaskActivity` | `test/child_tasks_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic parent/child completion command wiring. |
|
||||
| MVP-AC-13 | Display backlog staleness icons without per-task stale prompts. | `BacklogStalenessMarker`, `BacklogStalenessSettings`, `BacklogView` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart` | incomplete | Backend marker exists; settings persistence and UI display remain in Blocks 14, 15, and 18. |
|
||||
| MVP-AC-14 | Track baseline internal statistics needed for later reports and filtering. | `TaskStatistics`, `ProjectStatistics`, `TaskActivity`, `TaskActivityApplicationResult`, `TaskActivityAccountingService`, `ProjectStatisticsAggregationService`, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, selected action services | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/document_mapping_test.dart`, `test/task_lifecycle_test.dart`, `test/child_tasks_test.dart`, `test/project_statistics_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | complete | Chunks 13.1-13.4 add canonical statistics/accounting; Chunk 14.3 persists command activities and project aggregate updates atomically in memory. MongoDB adapter persistence remains tracked separately under MVP-SUP-07. |
|
||||
| MVP-AC-13 | Display backlog staleness icons without per-task stale prompts. | `BacklogStalenessMarker`, `BacklogStalenessSettings`, `BacklogView`, `OwnerSettings`, `BacklogPane` | `test/scheduling_engine_test.dart`, `test/edge_case_regression_test.dart`, `test/application_management_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart`, `apps/focus_flow_flutter/test/widget_test.dart` | complete | Backend marker, settings persistence, and provisional Flutter backlog icon rendering are complete without per-task stale prompts. |
|
||||
| MVP-AC-14 | Track baseline internal statistics needed for later reports and filtering. | `TaskStatistics`, `ProjectStatistics`, `TaskActivity`, `TaskActivityApplicationResult`, `TaskActivityAccountingService`, `ProjectStatisticsAggregationService`, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, selected action services | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/document_mapping_test.dart`, `test/task_lifecycle_test.dart`, `test/child_tasks_test.dart`, `test/project_statistics_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | complete | Chunks 13.1-13.4 add canonical statistics/accounting; Chunk 14.3 persists command activities and project aggregate updates atomically in memory. Blocks 19-20 add repository contracts and SQLite adapter conformance. |
|
||||
|
||||
## Additional MVP backend requirements
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ Status values:
|
|||
| MVP-SUP-04 | Cancelled and no-longer-relevant are separate calm lifecycle outcomes. | `TaskStatus.cancelled`, `TaskStatus.noLongerRelevant`, `RequiredTaskAction`, `TaskActivityCode` | `test/required_task_actions_test.dart`, `test/task_lifecycle_test.dart` | complete | Chunk 13.1 centralizes both transitions and emits distinct activity codes. |
|
||||
| MVP-SUP-05 | Free Slot is intentional rest that blocks normal flexible placement and suppresses normal flexible reminders. | `V1ApplicationCommandUseCases.createProtectedFreeSlot`, `V1ApplicationCommandUseCases.updateProtectedFreeSlot`, `V1ApplicationCommandUseCases.removeProtectedFreeSlot`, `TaskType.freeSlot`, `OccupancyPolicy`, `FreeSlotService`, `ReminderPolicyService`, timeline tokens | `test/timeline_state_test.dart`, `test/occupancy_policy_test.dart`, `test/free_slots_test.dart`, `test/scheduling_invariants_test.dart`, `test/reminder_policy_test.dart`, `test/application_commands_test.dart` | complete | Blocks 12 and 13 cover scheduling/reminder policy; Chunk 14.3 adds atomic protected Free Slot commands. |
|
||||
| MVP-SUP-06 | Project defaults apply, learned suggestions stay optional, and task reminder overrides are possible. | `ProjectProfile`, `ProjectStatistics`, `ProjectSuggestionService`, `ProjectDefaultResolution`, `ReminderPolicyService`, `Task.reminderOverride`, `ReminderProfile` | `test/scheduling_engine_test.dart`, `test/domain_invariants_test.dart`, `test/project_statistics_test.dart`, `test/reminder_policy_test.dart` | complete | Chunk 13.5 adds effective reminder resolution without using learned suggestions as silent configuration. |
|
||||
| MVP-SUP-07 | Repository boundaries prepare for MongoDB without coupling the scheduler to MongoDB APIs. | Repository interfaces, in-memory repositories, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, document mapping helpers | `test/repositories_test.dart`, `test/document_mapping_test.dart`, `test/persistence_edge_cases_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | incomplete | Chunks 14.1-14.3 add pure Dart transaction/read/command contracts; complete codecs, durable revisions, and runtime adapter remain in Blocks 15 and 16. |
|
||||
| MVP-SUP-07 | Repository boundaries prepare for swappable persistence without coupling the scheduler to database APIs. | Repository interfaces, in-memory repositories, SQLite repositories, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, document mapping helpers | `test/repositories_test.dart`, `test/document_mapping_test.dart`, `test/persistence_edge_cases_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart`, `packages/scheduler_persistence_memory/test/memory_repository_conformance_test.dart`, `packages/scheduler_persistence_sqlite/test/sqlite_repository_conformance_test.dart` | complete | Blocks 19-20 add domain-only repository contracts, in-memory conformance, SQLite adapter conformance, durable revisions, and compare-and-set saves. |
|
||||
| MVP-SUP-08 | Hidden locked time remains hidden by default, with explicit reveal as an overlay. | `LockedBlockOccurrence.hiddenByDefault`, `TimelineItemMapper.fromLockedOccurrence`, `GetTodayStateQuery`, `TodayTimelineItem` | `test/timeline_state_test.dart`, `test/edge_case_regression_test.dart`, `test/today_state_test.dart` | complete | Chunk 14.2 adds hidden-by-default Today omission, explicit reveal mode, and date-stable locked overlay IDs. |
|
||||
| MVP-SUP-09 | Push/backlog/restore movement should be activity/stat data, not shame language. | `TaskStatistics`, `ProjectStatistics`, `TaskActivity`, `TaskActivityCode`, `SchedulingChange`, `SchedulingMovementCode`, `ApplicationUnitOfWork`, `V1ApplicationCommandUseCases`, action result objects | `test/scheduling_engine_test.dart`, `test/required_task_actions_test.dart`, `test/scheduling_invariants_test.dart`, `test/task_lifecycle_test.dart`, `test/project_statistics_test.dart`, `test/application_layer_test.dart`, `test/application_commands_test.dart` | complete | Chunk 14.3 adds atomic command persistence for movement activities, task stats, project stats, and operation records. |
|
||||
| MVP-SUP-10 | The human spec lists `pushed` and `skipped` as statuses. | `TaskStatus` excludes both; movement and burnout compatibility are modeled as activity/stat metadata. | `test/domain_contracts_test.dart` | contradictory | Resolved by `V1_ADR_001_Lifecycle_Metadata_Reminder_Semantics.md`; the contradiction is kept visible so later chunks do not add movement labels as statuses. |
|
||||
|
|
|
|||
151
README.md
151
README.md
|
|
@ -1,106 +1,75 @@
|
|||
# ADHD Scheduling App Core
|
||||
# ADHD Scheduler Workspace
|
||||
|
||||
This is a pure Dart scheduling-core project for an ADHD-focused scheduling
|
||||
application.
|
||||
SQLite-first Dart workspace for the ADHD scheduler backend, persistence
|
||||
adapters, notifications, exports, backups, integration tests, and CI scripts.
|
||||
|
||||
The repository intentionally keeps the scheduling core **pure Dart** before
|
||||
adding a full Flutter UI. The hardest part of the product is the scheduling
|
||||
behavior: flexible task shifting, locked time, backlog recovery, recurring
|
||||
availability blocks, and task-state correctness. Keeping that logic independent
|
||||
makes it easier to test and safer to hand off to Codex.
|
||||
## Test
|
||||
|
||||
## Current V1 core status
|
||||
|
||||
- Implemented V1 core: Today timeline view models, backlog/wishlist behavior,
|
||||
quick capture, flexible task insertion/pushing, recurring hidden locked blocks,
|
||||
one-day locked-block overrides, required task state transitions, surprise task
|
||||
logging, child task ownership/completion, internal statistics, and
|
||||
persistence-preparation helpers.
|
||||
- V2.0: Week/month views, reports, overwhelm shield, drag-and-drop, task history panels.
|
||||
- Persistence direction: MongoDB is the committed database target. Current V1
|
||||
work prepares repository interfaces and document-shaped mappings only; it does
|
||||
not add a MongoDB adapter, connection string, Atlas setup, local server
|
||||
requirement, accounts, sync, or background service.
|
||||
- Wishlist/future: Dependencies, context tags, advanced sync, actual MongoDB
|
||||
adapter/runtime setup, long-running task behavior decisions.
|
||||
|
||||
## Repository layout
|
||||
|
||||
```text
|
||||
.
|
||||
├── AGENTS.md
|
||||
├── README.md
|
||||
├── pubspec.yaml
|
||||
├── analysis_options.yaml
|
||||
├── lib/
|
||||
│ ├── scheduler_core.dart
|
||||
│ └── src/
|
||||
│ ├── backlog.dart
|
||||
│ ├── child_tasks.dart
|
||||
│ ├── document_mapping.dart
|
||||
│ ├── locked_time.dart
|
||||
│ ├── models.dart
|
||||
│ ├── persistence_contract.dart
|
||||
│ ├── quick_capture.dart
|
||||
│ ├── repositories.dart
|
||||
│ ├── scheduling_engine.dart
|
||||
│ ├── task_actions.dart
|
||||
│ ├── task_statistics.dart
|
||||
│ └── timeline_state.dart
|
||||
├── test/
|
||||
│ ├── child_tasks_test.dart
|
||||
│ ├── document_mapping_test.dart
|
||||
│ ├── edge_case_regression_test.dart
|
||||
│ ├── persistence_edge_cases_test.dart
|
||||
│ ├── repositories_test.dart
|
||||
│ ├── required_task_actions_test.dart
|
||||
│ ├── scheduling_engine_test.dart
|
||||
│ ├── surprise_task_logging_test.dart
|
||||
│ └── timeline_state_test.dart
|
||||
├── Human Documentation/
|
||||
│ ├── Original Chat-Compiled Design Spec.md
|
||||
│ ├── Overall App Design Spec.docx
|
||||
│ ├── Starter Architecture Notes.md
|
||||
│ └── Unified Product Design Summary.md
|
||||
└── Codex Documentation/
|
||||
├── README.md
|
||||
├── Current Software Plan/
|
||||
└── Archived plans/
|
||||
```sh
|
||||
scripts/test.sh
|
||||
```
|
||||
|
||||
## Basic commands
|
||||
The test gate runs analyzer, tests with coverage, combines LCOV output, and
|
||||
fails below 80% package `lib/` coverage.
|
||||
|
||||
Install a Dart SDK that satisfies `pubspec.yaml` first. This is a pure Dart
|
||||
package, so Flutter is not required for the current core/test loop. MongoDB is
|
||||
the planned persistence target, but no MongoDB service, Atlas account,
|
||||
connection string, network access, or sync/background process is required for the
|
||||
current in-memory domain/test loop.
|
||||
## Development
|
||||
|
||||
```bash
|
||||
dart pub get
|
||||
dart format lib test
|
||||
dart analyze
|
||||
dart test
|
||||
git diff --check
|
||||
```sh
|
||||
scripts/bootstrap_dev.sh
|
||||
scripts/dev.sh
|
||||
```
|
||||
|
||||
Run these before committing changes whenever the local environment has Dart
|
||||
available.
|
||||
The shell scripts prepare the default SQLite path and delegate to the Dart
|
||||
development runner.
|
||||
|
||||
## Documentation
|
||||
```sh
|
||||
dart run scripts/dev.dart
|
||||
```
|
||||
|
||||
Product and design context belongs in `Human Documentation/`. Codex execution
|
||||
plans belong in `Codex Documentation/`, with active work under
|
||||
`Codex Documentation/Current Software Plan/` and finished plans moved to
|
||||
`Codex Documentation/Archived plans/`.
|
||||
The dev script prints the SQLite path, starts `dart run build_runner watch`, and
|
||||
launches Flutter desktop with `SCHEDULER_SQLITE_PATH` passed as a dart define.
|
||||
|
||||
## Codex handoff
|
||||
Prerequisites:
|
||||
|
||||
Codex should begin by reading:
|
||||
- Dart stable SDK
|
||||
- Flutter stable SDK with desktop support enabled
|
||||
- platform desktop toolchain: Xcode for macOS, Visual Studio Build Tools for
|
||||
Windows, and Linux desktop build dependencies for Linux
|
||||
|
||||
1. `AGENTS.md`
|
||||
2. `Human Documentation/Overall App Design Spec.docx` or the Markdown companion
|
||||
3. `Codex Documentation/Current Software Plan/README.md`
|
||||
4. The next numbered block document in `Codex Documentation/Current Software Plan/`
|
||||
Optional flags:
|
||||
|
||||
Each completed work block should be committed with a conventional commit message.
|
||||
```sh
|
||||
dart run scripts/dev.dart --device linux --sqlite /tmp/scheduler.sqlite
|
||||
```
|
||||
|
||||
## Flutter UI
|
||||
|
||||
The provisional UI app lives outside the root Dart workspace at
|
||||
`apps/focus_flow_flutter` so backend package gates can stay Dart-only while the
|
||||
Flutter foundation settles.
|
||||
|
||||
```sh
|
||||
cd apps/focus_flow_flutter
|
||||
flutter analyze
|
||||
flutter test
|
||||
```
|
||||
|
||||
## Packaging
|
||||
|
||||
```sh
|
||||
scripts/package_release.sh --platform current --output build/releases
|
||||
```
|
||||
|
||||
```sh
|
||||
dart run scripts/build.dart --platform current --output build/releases
|
||||
```
|
||||
|
||||
Packaging prerequisites:
|
||||
|
||||
- macOS: Flutter desktop support and Xcode; produces a `.app`
|
||||
- Windows: Flutter desktop support, Visual Studio Build Tools, and `msix`
|
||||
package configuration available to `dart run msix:create`
|
||||
- Linux: Flutter desktop support plus `appimage-builder` and
|
||||
`AppImageBuilder.yml`; produces an AppImage
|
||||
|
||||
Tagged CI runs upload release artifacts from `build/releases/`.
|
||||
|
|
|
|||
Binary file not shown.
BIN
archive/Codex Documentation.7z
Normal file
BIN
archive/Codex Documentation.7z
Normal file
Binary file not shown.
BIN
archive/adhd_scheduling_starter_project.7z
Normal file
BIN
archive/adhd_scheduling_starter_project.7z
Normal file
Binary file not shown.
Loading…
Reference in a new issue