From 81e14fbc633a7969af413cb1597a510348ae2190 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Tue, 14 Jul 2026 13:54:35 -0400 Subject: [PATCH] Jul 14 - Using CDN - Phase 4b --- CLAUDE.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 91ef03d..9035f83 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1389,11 +1389,11 @@ timeout = 30 - [x] Inspection detail payload (`api/inspections.py`) adds `form_media` = `{field_id: absolute_url}` for `uploads/...` image field values. Helper `_media()`. - These are additive — the iPad ignores them until 4b ships, and on `local` they're just absolute static URLs, so nothing breaks. -**4b — iOS: consume the URLs (do before new post-cutover photos appear):** -- [ ] Add `photoUrls` / `resultPhotoUrls` to `APIAssignedIssue`; `resultPhotoUrls` to `APIIssueDetail`; `formMedia` to the inspection detail model. -- [ ] Store parallel URL arrays on `LocalIssue` (`photoServerUrls`, `resultPhotoServerUrls`), mapped in `pullAssignedIssues` + `refreshStatusFromServer`. -- [ ] A resolver that prefers the absolute URL and falls back to `ServerConfig.current + "/static/" + path` (older server / empty URL). Wire the 4 display sites: `IssuesView` (evidence ×1, result ×1), `InspectionHistoryView` (form image; use `formMedia[fieldId]`). -- Grace period: local files are kept 30 days post-cutover, and the iPad caches downloaded photos, so old `/static/` URLs keep working during rollout; 4b must land before the 30-day local cleanup and before users need *new* post-cutover photos. +**4b — iOS: consume the URLs — ✅ delivered:** +- [x] `APIAssignedIssue` gains `photoUrls` + `resultPhotoUrls`; `APIIssueDetail` gains `resultPhotoUrls`; `APIInspectionSummary` gains `formMedia` ({fieldId: url}) + a derived `mediaURLByPath` ({path: url}). +- [x] `LocalIssue` stores parallel `photoServerUrls` / `resultPhotoServerUrls` (JSON-backed), mapped in `SyncManager.pullAssignedIssues` (both branches) and `IssuesView.refreshStatusFromServer`. +- [x] `ServerConfig.mediaURL(absolute:path:)` resolver — prefers the absolute URL, falls back to `current + "/static/" + path`. Wired at all display sites: `IssuesView` evidence + result (index-paired with the URL arrays), `InspectionHistoryView` `PhotoThumbnailView` (via a `mediaURLByPath` SwiftUI environment injected on the read-only grid — avoids threading field IDs through the grid). +- Backward-compatible: empty URL arrays (older server) → resolver builds the `/static/` URL as before. **Operator cutover runbook (after 4b ships + Phase 3 sync exits clean):** - [ ] Confirm `python scripts/migrate_photos_to_r2.py` prints "✅ SAFE" (0 mismatches) and verified count ≥ Phase 0 baseline present-count.