# Starter Architecture Notes

## Initial architecture decision

Start as a pure Dart scheduling-core package. Do not begin with UI. The scheduling rules are the hardest and most important part of the product, and they should be testable without a Flutter app running.

## Future shape

```text
Flutter UI
  ↓
View/application state
  ↓
Pure Dart scheduling core
  ↓
Repository interfaces
  ↓
MongoDB persistence adapter (planned later)
  ↓
Future sync layer, if explicitly planned
```

## Why pure Dart first

- Easier to test scheduling rules.
- Less UI noise for Codex.
- Cleaner migration into Flutter later.
- Avoids premature sync/background complexity.

## Key invariant

The scheduling core must never move locked or inflexible blocks during automatic rescheduling.

Flexible end-of-day rollover should use an explicit source-day window when
available. That prevents planned flexible tasks from future days from being
pulled into tomorrow during recovery.

Backlog staleness in the current V1 domain model uses task creation age for both
the stale filter and green/blue/purple marker. A later MongoDB-backed
persistence pass may add a separate backlog-entered timestamp, but the current
core keeps the timestamp semantics consistent and database-independent.

Surprise task logging is a domain action, not UI behavior. A logged surprise task
is completed immediately. If it has a time interval, overlapping flexible tasks
are pushed by the normal scheduler, required visible overlaps are reported, and
locked overlaps are tracked as hidden data rather than rendered as normal tasks.

Child tasks are direct parent-owned tasks, not dependency graph nodes. Completing
all direct children can complete the parent, and explicitly completing a parent
can force-complete its direct children. Scheduling still treats child ownership
as metadata and does not block placement based on parent/child state.

V1 treats task lifecycle status and movement history as separate concepts.
Durable task statuses are planned, active, completed, missed, cancelled, no
longer relevant, and backlog. Pushes, restores from backlog, and burnout skips
are activity/stat metadata rather than durable statuses. This preserves the
product language from the design spec while keeping scheduling state
deterministic and testable. The detailed backend decision is recorded in
`Codex Documentation/Archived plans/V1_ADR_001_Lifecycle_Metadata_Reminder_Semantics.md`.

`updatedAt` means last domain-level modification only. It should not be used as
a proxy for completion time, actual work time, missed time, or backlog-entry
time. Blocks 12, 13, and 15 add those fields explicitly where the product needs
them.

Recurring locked time uses civil dates and wall-clock times, not implicit local
`DateTime` values. The scheduling core converts a civil date plus wall time into
an instant only through an explicit time-zone resolver supplied by the
application boundary. Daylight-saving behavior is deterministic: nonexistent
local times shift forward by default, repeated local times choose the earlier
instant by default, and callers may request rejection or the later repeated
instant. Overnight locked rules are rejected instead of silently split or
normalized.

Persistence should keep these concepts separate. Instants are stored as UTC
ISO-8601 strings, civil dates as `YYYY-MM-DD`, and wall times as `HH:MM`; date
and wall-time fields must not be converted through UTC in a way that can shift
the user's intended local day.

## Persistence direction

MongoDB is the committed persistence target. The V1 scheduling core should still
remain persistence-independent and testable without a running database. Repository
interfaces should be designed so a later MongoDB adapter can persist document-shaped
models without importing MongoDB APIs into scheduling logic.

Current V1 persistence preparation includes pure Dart repository interfaces,
in-memory fakes for tests, UTC DateTime conventions, civil-date and wall-time
string conventions, stable enum names, and MongoDB-friendly document-shaped map
helpers. It does not include a MongoDB driver, adapter implementation,
connection string, Atlas/cloud setup, local MongoDB server requirement, user
accounts, network sync, background sync, or mobile background reconciliation.

Sync remains future work and should only be added if an active plan explicitly
asks for it. The core should continue to operate in-memory for tests and local
domain behavior until a later MongoDB adapter plan is approved.

Do not add alternative database assumptions to this project unless
the product owner explicitly changes the persistence decision.
