Room database for cycle history, with entities, DAOs and a migration test #3

Closed
opened 2026-08-18 02:14:36 -05:00 by null · 0 comments
Owner

Nothing is persisted. domain/cycle defines PeriodRecord and SpottingRecord as plain Kotlin and nothing writes them anywhere, so every forecast the app can currently produce dies with the process.

What to build, in core/database (an Android library module that does not exist yet):

  • Room entities mirroring the shapes in PRODUCT_PLAN.md §10: PeriodRecord, SpottingRecord, PredictionRecord, NotYetObservation
  • DAOs for each, exposing Flow rather than one-shot reads
  • schema export switched on and the exported JSON committed, so a migration can be tested against the real previous schema rather than a remembered one
  • a migration test at version 1, which exists to prove the harness works before there is a migration that matters

Rules that are not negotiable here:

  • SpottingRecord must never be able to start or reset a cycle (§25)
  • PredictionRecord is a snapshot taken before the outcome is known and is never overwritten in place — it is the only thing that makes accuracy measurable (§16)
  • nothing in the data layer may write a PeriodRecord the user did not confirm. §14: never secretly modify health history

When this lands, add its row to the migration table in docs/architecture/README.md in the same commit. That document's Review trigger names a new Room migration specifically, because a migration table that lags is the failure the template records at length.

Verify: ./gradlew :core:database:test passes including the version-1 migration test, core/database/schemas/*.json is committed, and inserting a period record survives a force-stop and relaunch on a device.

Nothing is persisted. `domain/cycle` defines `PeriodRecord` and `SpottingRecord` as plain Kotlin and nothing writes them anywhere, so every forecast the app can currently produce dies with the process. What to build, in `core/database` (an Android library module that does not exist yet): - Room entities mirroring the shapes in PRODUCT_PLAN.md §10: `PeriodRecord`, `SpottingRecord`, `PredictionRecord`, `NotYetObservation` - DAOs for each, exposing `Flow` rather than one-shot reads - schema export switched on and the exported JSON **committed**, so a migration can be tested against the real previous schema rather than a remembered one - a migration test at version 1, which exists to prove the harness works before there is a migration that matters Rules that are not negotiable here: - `SpottingRecord` must never be able to start or reset a cycle (§25) - `PredictionRecord` is a snapshot taken **before** the outcome is known and is never overwritten in place — it is the only thing that makes accuracy measurable (§16) - nothing in the data layer may write a `PeriodRecord` the user did not confirm. §14: never secretly modify health history When this lands, add its row to the migration table in `docs/architecture/README.md` **in the same commit**. That document's Review trigger names a new Room migration specifically, because a migration table that lags is the failure the template records at length. Verify: `./gradlew :core:database:test` passes including the version-1 migration test, `core/database/schemas/*.json` is committed, and inserting a period record survives a force-stop and relaunch on a device.
null added this to the Batch 01 — Foundation milestone 2026-08-18 02:14:36 -05:00
null closed this issue 2026-08-18 02:32:11 -05:00
Sign in to join this conversation.
No Label
P0
P1
P2
release-blocker
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/Privacy-Period-Tracker#3
No description provided.