mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
feat(environment): add home effective-from and reserve a DEVICE location source
Add `User.homeSince` (nullable effective-from instant) and a `DEVICE` value to the location-source enum (migration 0219). `homeSince` records when the home location became effective so day resolution can attribute a past day to the home only on/after that instant, rather than to the current home for every past day. Existing accounts with a home get `homeSince` stamped to the migration instant; their deep past is filled by explicit location periods instead. `DEVICE` is reserved for a future client-supplied coarse per-day location: the enum value and the wire contract accept it now so the resolver can rank it later without rework. Nothing writes it server-side yet.
This commit is contained in:
1 parent
a27a1ee71d
commit
6aad4a465e
2 files changed
+56
-6
No files matched your search
@@ -0,0 +1,36 @@
|
||||
-- v1.25 (W-ENV) — conservative past-location handling for the environmental
|
||||
-- context module.
|
||||
--
|
||||
-- Adds `users.home_since` (effective-from instant for the home location) and a
|
||||
-- `DEVICE` value to the location-source enum. Day resolution attributes a past
|
||||
-- day to the home location ONLY when the day is on/after `home_since`; earlier
|
||||
-- days are skipped rather than fabricated from the current home. The deep past
|
||||
-- is filled by explicit dated location periods instead.
|
||||
--
|
||||
-- `DEVICE` is the reserved forward path for a future client-supplied coarse
|
||||
-- per-day location (iOS v2). The value exists so the resolver and the wire
|
||||
-- contract already accept it; nothing writes it server-side yet.
|
||||
--
|
||||
-- Backfill of existing accounts: any row that already has a home location gets
|
||||
-- `home_since` stamped to the migration instant. This is conservative — the
|
||||
-- exact day a pre-upgrade account moved into its home is unknown, so history
|
||||
-- before the upgrade is left to explicit location periods rather than guessed.
|
||||
--
|
||||
-- Additive; no existing weather row touched. Idempotent guards so reruns are
|
||||
-- safe on prod.
|
||||
--
|
||||
-- Reversibility (down):
|
||||
-- ALTER TABLE "users" DROP COLUMN IF EXISTS "home_since";
|
||||
-- -- (the `DEVICE` enum value cannot be dropped in place; it is inert until a
|
||||
-- -- future client writes it, so a roll-back leaves it harmless.)
|
||||
|
||||
-- AlterTable: effective-from instant for the home location (nullable).
|
||||
ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "home_since" TIMESTAMP(3);
|
||||
|
||||
-- Backfill: stamp existing home rows so they resolve from the upgrade forward.
|
||||
UPDATE "users"
|
||||
SET "home_since" = CURRENT_TIMESTAMP
|
||||
WHERE "home_lat" IS NOT NULL AND "home_since" IS NULL;
|
||||
|
||||
-- AlterEnum: reserve the DEVICE source for the iOS v2 forward path.
|
||||
ALTER TYPE "environment_location_source" ADD VALUE IF NOT EXISTS 'DEVICE';
|
||||
+20
-6
@@ -63,6 +63,12 @@ model User {
|
||||
homeLon Float? @map("home_lon")
|
||||
homeLabel String? @map("home_label")
|
||||
homeTimezone String? @map("home_timezone")
|
||||
// v1.25 — effective-from instant for the home location. Stamped the moment a
|
||||
// home is set/updated. Day resolution attributes a past day to home ONLY when
|
||||
// the day is on/after this instant; earlier days are skipped (never fabricated
|
||||
// from the current home). To fill the deep past the user adds an explicit
|
||||
// dated location period instead. Backfill defaults its start to this instant.
|
||||
homeSince DateTime? @map("home_since")
|
||||
|
||||
// Codex OAuth (ChatGPT subscription)
|
||||
codexAccessTokenEncrypted String? @map("codex_access_token_encrypted")
|
||||
@@ -811,11 +817,16 @@ model User {
|
||||
// ─── v1.25 (W-ENV) Environmental-context module ──────────────────────────────
|
||||
|
||||
/// How the location for an environment observation was resolved. HOME = the
|
||||
/// user's configured home location; TRAVEL = a manual date-range override.
|
||||
/// (iOS coarse device location is a v2 follow-up and not represented here.)
|
||||
/// user's configured home location; TRAVEL = an explicit dated location period
|
||||
/// (a past trip OR a corrected stretch of history) that overrides home for the
|
||||
/// days it covers; DEVICE = a future client-supplied coarse per-day location.
|
||||
/// DEVICE is the priority forward path for the iOS v2 client: the value exists
|
||||
/// so the resolver and the wire contract already accept it, but nothing writes
|
||||
/// it server-side yet.
|
||||
enum EnvironmentLocationSource {
|
||||
HOME
|
||||
TRAVEL
|
||||
DEVICE
|
||||
}
|
||||
|
||||
/// A per-day environmental observation (daily weather / daylight) for the
|
||||
@@ -876,10 +887,13 @@ model EnvironmentContext {
|
||||
@@map("environment_contexts")
|
||||
}
|
||||
|
||||
/// A manual travel override: for any day in `[startDate, endDate]` the weather
|
||||
/// fetch resolves against this location instead of the home location. Declared,
|
||||
/// not inferred — a stated trip dominates the home fallback so a winter week in
|
||||
/// a sunny locale is not mis-attributed to the home city. Coarse location only.
|
||||
/// An explicit dated LOCATION PERIOD: for any day in `[startDate, endDate]` the
|
||||
/// weather fetch resolves against this location instead of the home location.
|
||||
/// Declared, not inferred — it dominates the home fallback so a stretch spent
|
||||
/// elsewhere is not mis-attributed to the home city. Two uses share this one
|
||||
/// model: a discrete trip away from home, AND the mechanism to correct history
|
||||
/// (e.g. a whole-history home city for the years before the current home became
|
||||
/// effective). Coarse location only. (Stored under `source = TRAVEL`.)
|
||||
model EnvironmentTravelLocation {
|
||||
id String @id @default(cuid())
|
||||
userId String @map("user_id")
|
||||
|
||||
Reference in new issue
Block a user