# V1 Block 15 — Persistence Schema, Codecs, and Repository Contracts

Status: Complete

Purpose: Turn the current persistence preparation into a complete, versioned,
MongoDB-document-friendly V1 data contract before introducing a database client.

## Chunk 15.1 — MongoDB document schema V1 decision record

Recommended Codex level: high

Status: Complete

Tasks:

- Define the V1 collection/document inventory for tasks, projects/project stats,
  locked blocks, locked overrides, internal activities, owner settings, notices,
  and idempotent operation records.
- Decide whether existing full scheduling snapshots remain a production entity,
  become bounded diagnostics, or are replaced by compact operation records;
  document migration and retention implications.
- Add `schemaVersion`, stable document ID, owner scope, revision, created time,
  and updated time conventions where applicable.
- Replace enum `.name` as a long-term schema contract with explicit stable codes
  and decode tables.
- Define civil-date, wall-time, time-zone ID, instant, interval, and optional-field
  encoding.
- Define archive/soft-delete behavior and retention for internal operation data.
- Define required indexes and uniqueness constraints without creating them yet.
- Define document size limits/guards for embedded lists such as child mutations
  or scheduling changes.
- Record privacy boundaries: hidden locked details, internal statistics, and no
  credentials/secrets in domain documents.

Rules:

- The schema must support every Block 14 use case without requiring relational
  joins or embedding unbounded history into a task document.
- Do not add alternative database assumptions.
- Do not encode date-only values as UTC midnight timestamps.
- Do not rely on Dart enum source names remaining unchanged forever.
- User accounts/authentication remain outside V1; owner scope is a data boundary,
  not an auth implementation.

Acceptance criteria:

- Every repository entity has an explicit collection/document home.
- Every document has a versioning and revision strategy.
- Stable code, time, null/clear, archive, and retention conventions are written.
- Required indexes are listed with the use cases they support.
- The decision on scheduling snapshots versus operation records is explicit.

Completed implementation:

- Added `V1_ADR_002_MongoDB_Document_Schema_V1.md` as the accepted Block 15.1
  schema decision record.
- Defined the V1 collection inventory for tasks, projects, project statistics,
  locked blocks, locked overrides, task activities, owner settings, notice
  acknowledgements, operation records, and bounded scheduling snapshots.
- Established common document conventions for `schemaVersion`, `_id`, `ownerId`,
  optimistic `revision`, `createdAt`, and `updatedAt`.
- Documented string encodings for instants, civil dates, wall times, time-zone
  IDs, intervals, optional null/clear fields, and unknown-field tolerance.
- Replaced long-term enum `.name` persistence with explicit stable code values
  and future decode-table requirements.
- Made scheduling snapshots bounded diagnostics and pending-notice carriers
  rather than authoritative task/project/locked state.
- Documented archive behavior, internal operation retention, hidden locked-time
  privacy boundaries, document-size guards, required indexes, and uniqueness
  constraints.

Verification:

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

BREAKPOINT: Stop here. Confirm `extra high` mode before implementing all codecs
and migrations.

## Chunk 15.2 — Complete document codecs for every repository entity

Recommended Codex level: extra high

Status: Complete

Tasks:

- Implement plain-Dart map codecs for every V1 persisted entity from Chunk 15.1.
- Include project profiles/statistics, locked recurrence, locked overrides,
  civil-date/wall-time values, settings, activities, notices, operation records,
  and any retained scheduling snapshot structures.
- Use explicit stable code maps for every enum/discriminator.
- Preserve intentional null/clear behavior through round trips.
- Decode into validated domain values and return typed mapping failures for
  malformed documents.
- Define unknown-field behavior so forward-compatible extra fields do not corrupt
  current reads.
- Keep BSON/client-specific classes outside the core mapping layer.
- Add exhaustive round-trip tests for minimum, maximum, and all-optional-field
  documents.
- Add negative tests for missing fields, unknown codes, invalid intervals,
  invalid revisions, and wrong primitive types.

Rules:

- A document may not bypass the invariants established in Block 11.
- Mapping errors must identify field/code categories without exposing secrets.
- Do not silently coerce ambiguous dates or times.
- Do not drop existing valid task/statistics fields during the codec refactor.
- Codecs must remain usable by in-memory fixtures without MongoDB installed.

Acceptance criteria:

- Every V1 repository entity round-trips through its document shape.
- Unknown/invalid enum codes are handled by the documented policy.
- Date-only and wall-time fields round-trip without time-zone drift.
- Nullable fields can be preserved and explicitly cleared.
- All codec tests pass without a database runtime.

Completed implementation:

- Replaced the partial document mapper with V1 map codecs for every Chunk 15.1
  persisted entity: tasks, task statistics, project profiles, project
  statistics, locked recurrence, locked blocks, locked overrides, task
  activities, owner settings, backlog staleness settings, notice
  acknowledgements, operation records, scheduling snapshots, windows,
  intervals, notices, changes, and overlaps.
- Added explicit stable encode/decode tables for all persisted enum/code values
  instead of relying on Dart enum `.name`.
- Added `DocumentMappingFailureCode`, `DocumentMappingException`, and
  `DocumentMetadata` so malformed V1 documents fail with typed mapping
  categories.
- Added common V1 metadata validation for `schemaVersion`, `_id`, `ownerId`,
  positive `revision`, `createdAt`, and `updatedAt`.
- Expanded persistence field-name contracts to include common metadata, archive
  fields, owner settings, notice acknowledgement, operation record, scheduling
  snapshot, notice-code, and retention fields.
- Preserved null/clear behavior for optional fields and validated required
  nullable V1 fields even when the current domain object does not carry that
  metadata directly.
- Added forward-compatible unknown-field tolerance by ignoring extra document
  fields during decoding.
- Added exhaustive codec tests for full and nullable task documents, configured
  projects, project statistics with applied activity IDs, locked time civil
  dates/wall times, settings, activities, acknowledgements, operation records,
  scheduling snapshots, stable code tables, and malformed document failures.

Verification:

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

## Chunk 15.3 — Legacy schema migration and fixture suite

Recommended Codex level: extra high

Status: Complete

Tasks:

- Treat the existing task/task-statistics mapping as legacy schema version 0.
- Implement an explicit version-by-version migration pipeline to schema V1.
- Add checked-in fixtures representing current minimum/full task documents,
  project/locked data that may have been manually produced, and malformed edge
  cases.
- Define a conservative migration for backlog age when only `createdAt` exists;
  label the provenance rather than pretending it is an exact backlog-entry time.
- Migrate enum `.name` values to stable codes.
- Migrate date-only locked overrides without introducing calendar-day shifts.
- Make migrations deterministic and idempotent.
- Add dry-run/report support at the adapter/service boundary so migration failures
  can be surfaced before writes.
- Add tests for V0→V1, already-V1 no-op, repeated migration, partial corruption,
  and unsupported future versions.

Rules:

- Never overwrite the only copy of an unreadable document without a recoverable
  error/report path.
- Do not guess ambiguous time zones silently.
- Migration code must not depend on Flutter.
- Unsupported future schema versions must fail closed, not be downgraded.
- Fixture data must contain no real secrets or personal content.

Acceptance criteria:

- Legacy task documents migrate to V1 without data loss under documented rules.
- Re-running migration is a no-op.
- Unsupported/corrupt documents produce actionable typed reports.
- Date/backlog approximations carry provenance.
- Migration fixtures are part of the automated suite.

Completed implementation:

- Added `document_migration.dart` with a pure Dart `V1DocumentMigrationService`
  for V0 task, project, locked block, and locked override documents.
- Treated missing `schemaVersion` as schema V0 and validated already-current V1
  documents through the V1 codecs without rewriting them.
- Added typed migration reports/results, non-fatal notes, and `shouldWrite`
  semantics so adapters can dry-run migrations and avoid overwriting unreadable
  source documents.
- Migrated legacy enum `.name` values to stable V1 codes for task, project, and
  locked-time fields.
- Added conservative backlog provenance: legacy backlog tasks set
  `backlogEnteredAt` from `createdAt` with
  `approximated_from_created_at`; non-backlog tasks keep the metadata null.
- Preserved date-only locked override values as civil-date strings and rejected
  ambiguous legacy date-time values rather than guessing a timezone.
- Added checked-in JSON fixtures for minimum/full V0 task documents, manually
  produced project/locked documents, corrupt/malformed V0 documents, and an
  unsupported future schema document.
- Added automated migration tests for V0→V1, already-V1 no-op, repeated
  migration idempotency, partial corruption, ambiguous date-times, and future
  schema failure.

Verification:

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

BREAKPOINT: Stop here. Confirm `high` mode before expanding repository/query
contracts and index specifications.

## Chunk 15.4 — Complete repository and concurrency contracts

Recommended Codex level: high

Status: Complete

Tasks:

Expand repository interfaces and in-memory implementations to support:

- tasks by ID, status, project, parent, owner, local day/window, and backlog
  candidate filters
- project lookup and archive state
- locked blocks and date-scoped overrides
- append/query of internal activities needed by use cases/statistics
- owner settings and notice acknowledgement
- operation lookup by idempotency key
- compare-and-set revision saves
- batch/unit-of-work writes
- explicit archive/delete behavior where V1 requires it

Also:

- Define expected ordering and pagination/cursor behavior for potentially growing
  queries.
- Add a reusable repository conformance suite that any adapter can run.
- Ensure in-memory reads return immutable copies/views and honor revisions.
- Map stale revisions and duplicate operation IDs to typed repository failures.

Rules:

- Repository methods expose use-case-oriented queries, not arbitrary driver
  handles or raw query documents.
- Do not let callers bypass the application unit of work for multi-record
  mutations.
- Hard delete must be explicit and rare; normal task removal uses lifecycle or
  archive semantics.
- Query contracts must include owner scope even before account/auth work exists.
- Keep MongoDB types out of interfaces.

Acceptance criteria:

- Block 14 use cases no longer need `findAll()` as their normal loading strategy.
- Optimistic revision conflicts are reproducible in memory.
- The conformance suite covers query semantics, archive behavior, revisions,
  idempotency, and immutability.
- Existing in-memory tests are migrated and pass.
- Interfaces remain persistence-client-independent.

Completed implementation:

- Added adapter-neutral repository mutation/result contracts:
  `RepositoryFailureCode`, `RepositoryFailure`, `RepositoryMutationResult`,
  `RepositoryRecord`, `RepositoryPageRequest`, `RepositoryPage`, and
  `BacklogCandidateQuery`.
- Expanded task repository contracts and in-memory implementations for owner,
  project, parent, backlog-candidate, local-day/window, record/revision,
  insert, and compare-and-set save behavior.
- Expanded project and locked-time repositories with owner-scoped paged queries,
  revision records, compare-and-set saves, duplicate insert failures, archive
  behavior, and date-scoped locked override queries.
- Expanded application-layer repositories for task activity append/query,
  project statistics/settings revision saves, notice acknowledgement insert and
  paging, and idempotent operation lookup/insert.
- Updated the in-memory application unit of work to stage/copy owner and
  revision metadata across transactions.
- Shifted Today, project-default, recovery, and planning-state loading to
  owner/date-scoped repository queries where those paths do not need wider task
  family context.
- Added reusable core repository conformance tests covering query semantics,
  deterministic pagination, archive behavior, optimistic revisions, duplicate
  IDs, and immutable result pages.
- Added application unit-of-work contract tests for activity append conflicts,
  owner settings stale revisions, notice duplicate inserts, and duplicate
  operation IDs.

Verification:

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

## Chunk 15.5 — Index and data-integrity contract tests

Recommended Codex level: high

Status: Complete

Tasks:

- Represent required MongoDB indexes as declarative adapter-neutral
  specifications or documented constants.
- Include uniqueness for owner/document IDs and idempotent operation keys.
- Include query-supporting indexes for Today windows, backlog/status/project,
  parent ownership, locked override dates, unacknowledged notices, and activity
  aggregation where required.
- Define partial/compound index expectations for archived records.
- Add tests that every repository query in Block 14 has a matching index plan.
- Add document-size and bounded-retention guards for operation/activity payloads.
- Add schema-integrity tests that reject duplicate IDs, invalid revisions, and
  mismatched owner scope at the repository boundary.
- Publish a repository adapter checklist for Block 16.

Rules:

- Do not optimize speculative V2 report queries.
- Index names and key order must be stable enough for idempotent bootstrap.
- Retention must not delete authoritative task/project state.
- Hidden locked data must not be copied into unnecessary denormalized documents.
- Tests remain runnable without MongoDB; actual index creation is Block 16.

Acceptance criteria:

- Every V1 repository query has a documented/index-tested access path.
- Uniqueness and revision integrity constraints are explicit.
- Unbounded embedded growth has a prevention/retention policy.
- Block 16 can create indexes from the published contract.
- All persistence and repository tests pass.

Completed implementation:

- Added adapter-neutral V1 collection names, index-field specs, index specs, and
  repository query names in `persistence_contract.dart`.
- Added `PersistenceIndexCatalog.all` with stable names, key order, uniqueness,
  partial-filter expectations, archive-aware indexes, and supported query
  coverage.
- Added indexes for owner/document uniqueness, idempotent operations, Today
  windows, backlog/status/project lookups, parent ownership, date-scoped locked
  overrides, notice acknowledgement lookup, activity aggregation, and bounded
  scheduling snapshots.
- Added bounded payload and retention contracts through
  `PersistencePayloadLimits`, `PersistenceGuardResult`, and
  `PersistencePayloadGuard`.
- Added schema-integrity repository tests for duplicate IDs, invalid revisions,
  stale revisions, and mismatched owner scopes at the repository boundary.
- Added index contract tests that verify every V1 repository query has a
  declared access path, stable index names/key order, explicit uniqueness,
  archive/partial-index coverage, and bounded payload rejection.
- Published `V1_BLOCK_16_REPOSITORY_ADAPTER_CHECKLIST.md` for the future MongoDB
  adapter implementation.

Verification:

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

BREAKPOINT: Stop here. Confirm `extra high` mode before selecting and implementing
the MongoDB runtime boundary.

Commit suggestion:

```text
feat(data): complete versioned v1 persistence contracts
```
