The `AlarmClock` contract says twice that an alarm or a timer created with
`SKIP_UI` should be removed once it has been dismissed. Without somewhere to
record that, a voice user's alarm list becomes a graveyard of one-shots nobody
asked to keep.
One column on each of `alarms` and `timers`, defaulting to 0, and a migration
that adds them. Existing rows keep the behaviour they have always had.
Snooze, the handled-occurrence watermark and the skip watermark need somewhere
to live that survives a process death. They go in their own table rather than
as columns on alarms: a missing row is the initial record, and the FK cascade
means deleting an alarm cannot leave orphaned ring state behind.
Schema v2 is exported and committed alongside v1, so MIGRATION_1_2 is
reviewable and testable rather than taken on faith.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alarms, timers, world_clocks and stopwatch_laps, with the schema exported
to app/schemas and committed so migrations can be tested from v1 onwards.
The DAOs return Flows for reads and keep every multi-step write inside a
@Transaction, so a read-modify-write cannot lose a concurrent one.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>