replica(uhr): architecture and schema
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
-- Local SQLite schema (Room). No server, no accounts, no network: all data stays on the device.
|
||||
-- Instants are INTEGER epoch milliseconds UTC. Alarm times are wall-clock (hour, minute) in the device zone.
|
||||
|
||||
CREATE TABLE alarms (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
hour INTEGER NOT NULL CHECK (hour BETWEEN 0 AND 23),
|
||||
minute INTEGER NOT NULL CHECK (minute BETWEEN 0 AND 59),
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0,1)),
|
||||
days INTEGER NOT NULL DEFAULT 0 CHECK (days BETWEEN 0 AND 127), -- bit 0 = Monday … bit 6 = Sunday; 0 = once
|
||||
label TEXT NOT NULL DEFAULT '',
|
||||
ringtone_uri TEXT, -- NULL = default alarm sound, 'silent' = none
|
||||
vibrate INTEGER NOT NULL DEFAULT 1 CHECK (vibrate IN (0,1)),
|
||||
skip_until TEXT, -- ISO date: paused until (inclusive)
|
||||
is_bedtime_wake INTEGER NOT NULL DEFAULT 0 CHECK (is_bedtime_wake IN (0,1)),
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
CREATE INDEX alarms_time ON alarms(hour, minute);
|
||||
CREATE UNIQUE INDEX alarms_one_bedtime ON alarms(is_bedtime_wake) WHERE is_bedtime_wake = 1;
|
||||
|
||||
-- The next concrete ring of an alarm. Exactly one row per enabled alarm; rewritten after every change,
|
||||
-- reboot, time or time zone change. Snooze and "dismiss early" live here, not on the alarm.
|
||||
CREATE TABLE alarm_instances (
|
||||
alarm_id INTEGER PRIMARY KEY REFERENCES alarms(id) ON DELETE CASCADE,
|
||||
fire_at INTEGER NOT NULL,
|
||||
state TEXT NOT NULL DEFAULT 'scheduled'
|
||||
CHECK (state IN ('scheduled','snoozed','ringing','missed','dismissed')),
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
CREATE INDEX alarm_instances_fire ON alarm_instances(state, fire_at);
|
||||
|
||||
CREATE TABLE timers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
label TEXT NOT NULL DEFAULT '',
|
||||
duration_ms INTEGER NOT NULL CHECK (duration_ms > 0),
|
||||
remaining_ms INTEGER NOT NULL CHECK (remaining_ms >= 0), -- valid while paused/idle
|
||||
end_at INTEGER, -- set while running
|
||||
state TEXT NOT NULL DEFAULT 'running' CHECK (state IN ('running','paused','ringing','idle')),
|
||||
created_at INTEGER NOT NULL,
|
||||
CHECK ((state = 'running') = (end_at IS NOT NULL))
|
||||
);
|
||||
CREATE INDEX timers_state ON timers(state, end_at);
|
||||
|
||||
CREATE TABLE cities (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
zone_id TEXT NOT NULL UNIQUE, -- IANA, e.g. Europe/Paris
|
||||
name TEXT NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE INDEX cities_sort ON cities(sort_order);
|
||||
|
||||
-- Single stopwatch and bedtime schedule live in DataStore (one instance each, no relations):
|
||||
-- stopwatch: state (idle|running|stopped), started_at_elapsed, accumulated_ms, laps (json array of ms)
|
||||
-- bedtime: enabled, bed_hour, bed_minute, days, reminder_min, sunrise, sleep_sound
|
||||
-- settings: silence_after_min, snooze_min, alarm_volume, gradual_volume_s, volume_buttons,
|
||||
-- week_start, home_zone, auto_home_clock, clock_style, show_seconds,
|
||||
-- timer_sound, timer_vibrate, night_mode, theme
|
||||
Reference in New Issue
Block a user