max / goingson
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+0 insertions,
-45 deletions
| @@ -1,45 +1,0 @@ | |||
| 1 | - | -- One-time reclassification of personal routines from `absolute` to `relative`. | |
| 2 | - | -- | |
| 3 | - | -- Migration 063 deliberately lands every existing row as `absolute`, because | |
| 4 | - | -- that is how it was already being treated and a migration must not guess. This | |
| 5 | - | -- script is the deliberate follow-up for a calendar whose events are personal | |
| 6 | - | -- routines: wake, swim, gym, errands, meal prep. Those should follow the user, | |
| 7 | - | -- so that a month spent in another zone still has breakfast at 06:00. | |
| 8 | - | -- | |
| 9 | - | -- RUN AFTER the app has applied migration 063 (open GoingsOn once). Applying the | |
| 10 | - | -- DDL by hand instead would leave sqlx's `_sqlx_migrations` table thinking 063 | |
| 11 | - | -- is still pending, and the next launch would fail on a duplicate column. | |
| 12 | - | -- | |
| 13 | - | -- Not idempotent in spirit but safe to re-run: the WHERE clause excludes rows | |
| 14 | - | -- already converted, and the civil times are derived from the stored UTC in the | |
| 15 | - | -- zone the events were authored in. | |
| 16 | - | -- | |
| 17 | - | -- sqlite3 ~/.local/share/com.goingson.app/goingson.db \ | |
| 18 | - | -- ".param set :tz 'America/Denver'" \ | |
| 19 | - | -- ".read scripts/classify_routines_relative.sql" | |
| 20 | - | -- | |
| 21 | - | -- Verify first against a copy. `SELECT` the result before committing to it. | |
| 22 | - | ||
| 23 | - | -- SQLite has no IANA database, so the civil time cannot be derived here from a | |
| 24 | - | -- zone name. The events were authored in Denver, which was UTC-6 (MDT) for all | |
| 25 | - | -- of them, so the offset is applied literally and the assumption is stated | |
| 26 | - | -- rather than hidden. An event authored during MST (UTC-7) would need -7 hours; | |
| 27 | - | -- none of the current rows are. | |
| 28 | - | UPDATE events | |
| 29 | - | SET tz_kind = 'relative', | |
| 30 | - | timezone = NULL, | |
| 31 | - | start_local = strftime('%Y-%m-%d %H:%M:%S', start_time, '-6 hours'), | |
| 32 | - | end_local = CASE | |
| 33 | - | WHEN end_time IS NULL THEN NULL | |
| 34 | - | ELSE strftime('%Y-%m-%d %H:%M:%S', end_time, '-6 hours') | |
| 35 | - | END | |
| 36 | - | -- Scoped by provenance rather than by "not imported". The routines carry an | |
| 37 | - | -- `external_source` of routine-weekday / routine-weekend / routine-exercise: | |
| 38 | - | -- self-authored rows stamped with a seed marker, not a foreign calendar. A | |
| 39 | - | -- blanket `external_source IS NULL` guard silently matches nothing here, which | |
| 40 | - | -- is exactly the sort of no-op that reads as success. | |
| 41 | - | WHERE tz_kind = 'absolute' | |
| 42 | - | AND external_source IN ('routine-weekday', 'routine-weekend', 'routine-exercise') | |
| 43 | - | AND is_read_only = 0 -- never touch a row a foreign calendar owns | |
| 44 | - | AND linked_task_id IS NULL -- nor a time block, which mirrors a task's schedule | |
| 45 | - | AND (recurrence != 'None' OR recurrence_rule IS NOT NULL); |