docs(17-02): complete server-side storage integration plan

- SUMMARY.md with 2 task commits documented
- STATE.md updated with progress and decision
- ROADMAP.md updated with plan progress
- REQUIREMENTS.md updated (IMG-01, IMG-03 complete)
This commit is contained in:
2026-04-05 12:24:17 +02:00
parent f5d79072f2
commit 2d31680072
4 changed files with 139 additions and 14 deletions

View File

@@ -0,0 +1,124 @@
---
phase: 17-object-storage
plan: 02
subsystem: api
tags: [s3, minio, image-upload, presigned-urls, object-storage]
requires:
- phase: 17-object-storage
provides: "S3 storage service (uploadImage, deleteImage, getImageUrl, withImageUrl, withImageUrls)"
provides:
- "All server image operations routed through S3 storage service"
- "API responses enriched with presigned imageUrl fields"
- "Static /uploads/* serving removed from server"
affects: [17-object-storage, client-image-display]
tech-stack:
added: []
patterns: ["withImageUrl/withImageUrls enrichment on API responses", "deleteImage in delete handlers"]
key-files:
created: []
modified:
- src/server/services/image.service.ts
- src/server/routes/images.ts
- src/server/routes/items.ts
- src/server/routes/threads.ts
- src/server/routes/setups.ts
- src/server/index.ts
- src/server/mcp/tools/items.ts
- src/server/mcp/tools/threads.ts
- src/server/mcp/tools/images.ts
- tests/services/image.service.test.ts
- tests/routes/images.test.ts
key-decisions:
- "Enrich responses at route level (not service level) to keep services storage-agnostic"
- "Setup items enriched via withImageUrls on GET /:id only (list doesn't include item images)"
patterns-established:
- "Image URL enrichment: wrap service results with withImageUrl/withImageUrls before returning JSON"
- "Image cleanup: call deleteImage() in try/catch on entity deletion (missing object = silent)"
requirements-completed: [IMG-01, IMG-03]
duration: 4min
completed: 2026-04-05
---
# Phase 17 Plan 02: Server-Side Storage Integration Summary
**Replaced all local filesystem image operations with S3 storage service calls across routes, services, and MCP tools**
## Performance
- **Duration:** 4 min
- **Started:** 2026-04-05T10:19:05Z
- **Completed:** 2026-04-05T10:22:45Z
- **Tasks:** 2
- **Files modified:** 11
## Accomplishments
- All image uploads (direct file and URL fetch) now go through S3 storage service
- All image deletions (item delete, candidate delete, thread delete) use deleteImage() instead of unlink()
- API responses for items, threads, setups, and MCP tools enriched with presigned imageUrl fields
- Static /uploads/* serving removed from server entry point
## Task Commits
Each task was committed atomically:
1. **Task 1: Refactor image service and routes to use storage service** - `5ce3f92` (feat)
2. **Task 2: Wire storage into all routes and MCP tools, remove static serving** - `f5d7907` (feat)
## Files Created/Modified
- `src/server/services/image.service.ts` - Replaced Bun.write/mkdir with uploadImage() call
- `src/server/routes/images.ts` - Replaced local write with uploadImage() for direct uploads
- `src/server/routes/items.ts` - deleteImage() on delete, withImageUrl(s) on GET responses
- `src/server/routes/threads.ts` - deleteImage() on delete, withImageUrls on GET thread candidates
- `src/server/routes/setups.ts` - withImageUrls on GET setup items
- `src/server/index.ts` - Removed /uploads/* static file serving line
- `src/server/mcp/tools/items.ts` - withImageUrl/withImageUrls on list and get tool responses
- `src/server/mcp/tools/threads.ts` - withImageUrls on get_thread candidate responses
- `src/server/mcp/tools/images.ts` - Updated description text (local -> storage)
- `tests/services/image.service.test.ts` - Mock storage service, verify uploadImage calls
- `tests/routes/images.test.ts` - Mock storage service, added upload test
## Decisions Made
- Enrichment happens at route/handler level, not service level, keeping services storage-agnostic
- Setup list endpoint not enriched (doesn't return item images), only setup detail GET /:id
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] Removed unused withImageUrl import from threads.ts**
- **Found during:** Task 2 (lint check)
- **Issue:** Imported withImageUrl but only used withImageUrls in threads route
- **Fix:** Removed unused import to pass lint
- **Files modified:** src/server/routes/threads.ts
- **Committed in:** f5d7907 (part of Task 2 commit)
---
**Total deviations:** 1 auto-fixed (1 bug/unused import)
**Impact on plan:** Trivial cleanup. No scope creep.
## Issues Encountered
None
## Known Stubs
None - all image operations fully wired to storage service.
## User Setup Required
None - no additional external service configuration required (MinIO setup was done in Plan 01).
## Next Phase Readiness
- Server-side storage integration complete
- Ready for Plan 03: client-side refactoring to use presigned imageUrl from API responses instead of /uploads/ paths
---
*Phase: 17-object-storage*
*Completed: 2026-04-05*
## Self-Check: PASSED