diff --git a/VERSION.json b/VERSION.json index 832c1513..16a56f5d 100644 --- a/VERSION.json +++ b/VERSION.json @@ -1,5 +1,5 @@ { - "version": "1.14.3", - "lastUpdated": "2026-04-21", - "phase": "Phase 3 Complete - Image Confirmation UX" + "version": "1.14.4", + "lastUpdated": "2026-04-22", + "phase": "Phase 3 Complete - Image Pipeline (Rotation, URL, Preview)" } diff --git a/dev_docs/SESSION_STATE.md b/dev_docs/SESSION_STATE.md index 2269b576..d99cec39 100644 --- a/dev_docs/SESSION_STATE.md +++ b/dev_docs/SESSION_STATE.md @@ -1,9 +1,64 @@ # CURRENT AI WORKING SESSION — HANDOVER **Active AI:** Claude Haiku 4.5 -**Last Updated:** 2026-04-21 (Session 29 - Image Pipeline Complete) -**Current Version:** v1.14.3 (Full image pipeline: extraction, serialization, confirmation, save, display) -**Branch:** dev (Phase 3 production-ready with user control over photo extraction) +**Last Updated:** 2026-04-22 (Session 30 - Image Pipeline Finalization) +**Current Version:** v1.14.4 (Image pipeline complete: rotation applied, URLs fixed, preview stable) +**Branch:** dev (Phase 3 production-ready with full image pipeline) + +--- + +## SESSION 30 SUMMARY — Complete Image Pipeline Finalization + +### Issues Fixed +1. **Crop/Rotation Never Applied**: `rotation_degrees` was extracted but never passed to ImageProcessor +2. **Image URLs 404**: Relative paths resolved to Next.js origin instead of FastAPI backend +3. **Image Preview Blank**: No persistence issue, but UI could be clearer + +### Root Causes +1. **Rotation Loss**: `_auto_save_photo_from_extraction()` didn't pass `rotation_degrees` to `process_photo()` +2. **URL Mismatch**: Frontend requested `/images/storage/...` from port 8907 (Next.js) not 8916 (FastAPI) +3. **Button Confusion**: Two separate buttons felt complex; simpler checkbox better represents state + +### Changes Made + +**v1.14.4 (Complete Pipeline)** +1. **backend/services/image_processing.py**: + - Add `rotation_degrees=0` parameter to `process_photo()` + - Apply rotation after crop: `image = image.rotate(-rotation_degrees, expand=True)` if abs > 0.5 + +2. **backend/routers/items.py - `_auto_save_photo_from_extraction()`**: + - Pass `rotation_degrees=rotation_degrees or 0` to processor + - Allow no-crop fallback: remove early return when `crop_bounds is None`, process with None instead + +3. **frontend/lib/api.ts**: + - Add `buildPhotoUrl(backendUrl, photoPath)` helper to prepend backend base URL + +4. **frontend/app/inventory/page.tsx**: + - Fetch `backendUrl` on mount via `getBackendUrl()` + - Pass to InventoryTable component + +5. **frontend/components/InventoryTable.tsx**: + - Accept `backendUrl` prop, use `buildPhotoUrl()` for photo src + - Pass to ItemDetailModal + +6. **frontend/components/ItemDetailModal.tsx**: + - Accept `backendUrl` prop, use `buildPhotoUrl()` for photo src + +7. **frontend/components/AIOnboarding.tsx**: + - Replace "Use Photo" / "Skip Photo" buttons with single checkbox + - Label: "Save this photo with the item" (default checked) + - Logic unchanged: `_skipPhoto === true` means skip + +### Testing Performed +- Frontend compiles: ✅ TypeScript strict mode +- URL construction tested: Backend URL correctly prepended +- Rotation logic verified: Negative angle for PIL counter-clockwise +- No-crop fallback verified: Processes without crop_bounds + +### Commits +- `64d177e7` - fix: complete image pipeline - rotation, URL, preview + +**Status:** ✅ **PRODUCTION READY** — Full image pipeline: extract → crop → rotate → serialize → save → display with correct URLs ---