feat(dates): foundation for the true-instant date contract (#114)
Populate the new-contract date columns at ingest while keeping the legacy date_taken column byte-identical (ADR-0001): - camera_tz module: offset cascade (offset tag -> GPS zone -> server zone) as a pure, testable function; bundled offline TZF geometry for GPS -> IANA resolution; DST-correct offsets for the capture date; display-zone helpers (DEFAULT_DISPLAY_TZ, display_zone_for, display_zone_offset_minutes) for the read-side cutover. - EXIF branch: kamadak-exif now collects OffsetTime* tags paired with the winning date tag; resolve_date_taken takes an ExifPrior and emits (date_utc, camera_offset_minutes, date_taken_tz_source) per branch: exif -> cascade, exiftool/fs_time -> utc_direct, filename -> unclassified (pending #116). - Schema: migration adds image_exif.date_utc / camera_offset_minutes / date_taken_tz_source and user_ai_prefs.display_tz (all nullable; down.sql drops them). - DAO + ingest: backfill_date_taken persists the triple alongside the legacy pair; watcher, upload, and set_image_gps call sites feed the cascade. - Response surface: ExifMetadata and ExifSummary carry the triple so /image/metadata and /photos/exif expose it (null for unconverted rows); reel requests mirror display_tz into prefs. cargo build + clippy clean; 625 lib + 702 bin tests pass (the one failing doctest in utils.rs is pre-existing at the base commit).
This commit is contained in:
1 parent
ee773a34ef
commit
2f2107d4fa
20 files changed
+1039
-36
No files matched your search
@@ -1281,6 +1281,9 @@ pub async fn list_exif_summary(
|
||||
gps_latitude: r.gps_latitude.map(f64::from),
|
||||
gps_longitude: r.gps_longitude.map(f64::from),
|
||||
date_taken: r.date_taken,
|
||||
date_utc: r.date_utc,
|
||||
camera_offset_minutes: r.camera_offset_minutes,
|
||||
date_taken_tz_source: r.date_taken_tz_source,
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -1513,6 +1516,9 @@ mod tests {
|
||||
original_date_taken_source: None,
|
||||
clip_embedding: None,
|
||||
clip_model_version: None,
|
||||
date_utc: None,
|
||||
camera_offset_minutes: None,
|
||||
date_taken_tz_source: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1554,6 +1560,9 @@ mod tests {
|
||||
original_date_taken_source: None,
|
||||
clip_embedding: None,
|
||||
clip_model_version: None,
|
||||
date_utc: data.date_utc,
|
||||
camera_offset_minutes: data.camera_offset_minutes,
|
||||
date_taken_tz_source: data.date_taken_tz_source.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1602,6 +1611,9 @@ mod tests {
|
||||
original_date_taken_source: None,
|
||||
clip_embedding: None,
|
||||
clip_model_version: None,
|
||||
date_utc: data.date_utc,
|
||||
camera_offset_minutes: data.camera_offset_minutes,
|
||||
date_taken_tz_source: data.date_taken_tz_source.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1726,6 +1738,9 @@ mod tests {
|
||||
_rel_path: &str,
|
||||
_date_taken: i64,
|
||||
_source: &str,
|
||||
_date_utc: Option<i64>,
|
||||
_camera_offset_minutes: Option<i32>,
|
||||
_date_taken_tz_source: Option<&str>,
|
||||
) -> Result<(), DbError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user