From 5545d691c238264cc7506c836dc6c81b090287bb Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sun, 5 Apr 2026 12:17:19 +0200 Subject: [PATCH] docs(17-01): complete S3 storage service and MinIO infrastructure plan - Add 17-01-SUMMARY.md with execution results - Update STATE.md with decisions and session info - Mark IMG-01 and IMG-04 requirements complete --- .planning/REQUIREMENTS.md | 8 +- .planning/STATE.md | 23 +++-- .../phases/17-object-storage/17-01-SUMMARY.md | 99 +++++++++++++++++++ 3 files changed, 116 insertions(+), 14 deletions(-) create mode 100644 .planning/phases/17-object-storage/17-01-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 121fbd8..b472201 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -34,10 +34,10 @@ Requirements for this milestone. Each maps to roadmap phases. ### Image Storage -- [ ] **IMG-01**: Images are stored in MinIO (S3-compatible) instead of local filesystem +- [x] **IMG-01**: Images are stored in MinIO (S3-compatible) instead of local filesystem - [ ] **IMG-02**: Existing uploaded images are migrated to MinIO - [ ] **IMG-03**: Image upload and retrieval work through the new storage layer -- [ ] **IMG-04**: Docker Compose provides MinIO for local development +- [x] **IMG-04**: Docker Compose provides MinIO for local development ### Global Item Database @@ -132,10 +132,10 @@ Which phases cover which requirements. Updated during roadmap creation. | MULTI-04 | Phase 16 | Pending | | MULTI-05 | Phase 16 | Pending | | MULTI-06 | Phase 16 | Pending | -| IMG-01 | Phase 17 | Pending | +| IMG-01 | Phase 17 | Complete | | IMG-02 | Phase 17 | Pending | | IMG-03 | Phase 17 | Pending | -| IMG-04 | Phase 17 | Pending | +| IMG-04 | Phase 17 | Complete | | GLOB-01 | Phase 18 | Pending | | GLOB-02 | Phase 18 | Pending | | GLOB-03 | Phase 18 | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index d9a43f1..4575dae 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -1,16 +1,16 @@ --- gsd_state_version: 1.0 -milestone: v2.0 -milestone_name: Platform Foundation +milestone: v1.3 +milestone_name: Research & Decision Tools status: planning -stopped_at: null -last_updated: "2026-04-03" +stopped_at: Completed 17-01-PLAN.md +last_updated: "2026-04-05T10:17:07.581Z" last_activity: 2026-04-03 — v2.0 roadmap created (Phases 14-18) progress: - total_phases: 5 - completed_phases: 0 - total_plans: 0 - completed_plans: 0 + total_phases: 8 + completed_phases: 6 + total_plans: 12 + completed_plans: 11 percent: 0 --- @@ -35,6 +35,7 @@ Progress: [----------] 0% (v2.0 milestone) ## Performance Metrics **Velocity:** + - Total plans completed: 0 (v2.0 milestone) - Average duration: -- - Total execution time: -- @@ -46,12 +47,14 @@ Progress: [----------] 0% (v2.0 milestone) ### Decisions Key decisions made during v2.0 planning: + - Platform pivot: single-user to multi-user with discovery-first approach - External auth provider (self-hosted, open-source) — Logto vs Authentik OPEN decision - SQLite to Postgres migration — required by auth provider and multi-user concurrency - Structured UGC only — ratings and predefined fields, no freeform text until moderation - Separate globalItems table — not a flag on user items table - Single-user SQLite mode diverges at v2.0 boundary +- [Phase 17]: Private S3 bucket with presigned URLs (1h default), MinIO pinned to quay.io RELEASE.2025-09-07 ### Pending Todos @@ -64,6 +67,6 @@ None active. ## Session Continuity -Last session: 2026-04-03 -Stopped at: v2.0 roadmap created with 5 phases (14-18) covering 30 requirements +Last session: 2026-04-05T10:17:07.579Z +Stopped at: Completed 17-01-PLAN.md Resume file: None diff --git a/.planning/phases/17-object-storage/17-01-SUMMARY.md b/.planning/phases/17-object-storage/17-01-SUMMARY.md new file mode 100644 index 0000000..a179049 --- /dev/null +++ b/.planning/phases/17-object-storage/17-01-SUMMARY.md @@ -0,0 +1,99 @@ +--- +phase: 17-object-storage +plan: 01 +subsystem: infra +tags: [s3, minio, aws-sdk, object-storage, docker, presigned-urls] + +# Dependency graph +requires: [] +provides: + - "S3 storage service (uploadImage, deleteImage, getImageUrl, withImageUrl, withImageUrls)" + - "MinIO in Docker Compose (dev and prod) with automatic bucket creation" + - "S3 environment variable configuration" +affects: [17-02, 17-03, image-routes, image-service, mcp-tools] + +# Tech tracking +tech-stack: + added: ["@aws-sdk/client-s3@3.1024.0", "@aws-sdk/s3-request-presigner@3.1024.0", "MinIO (quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z)"] + patterns: ["S3Client singleton with forcePathStyle", "Presigned URL injection via withImageUrl/withImageUrls helpers", "Docker Compose init container for bucket creation"] + +key-files: + created: ["src/server/services/storage.service.ts", "tests/services/storage.service.test.ts"] + modified: ["docker-compose.yml", "docker-compose.dev.yml", ".env.example"] + +key-decisions: + - "Private bucket with presigned URLs (1h default, configurable via S3_PRESIGN_EXPIRY)" + - "MinIO pinned to quay.io RELEASE.2025-09-07T16-13-09Z (last stable before archival)" + - "No console port exposed in production compose" + +patterns-established: + - "S3 storage functions are pure async functions, no HTTP awareness" + - "withImageUrl/withImageUrls helpers enrich records with presigned imageUrl field" + - "Docker init container pattern using mc CLI for bucket setup" + +requirements-completed: [IMG-01, IMG-04] + +# Metrics +duration: 2min +completed: 2026-04-05 +--- + +# Phase 17 Plan 01: S3 Storage Service and MinIO Infrastructure Summary + +**S3 storage abstraction with uploadImage/deleteImage/getImageUrl using @aws-sdk/client-s3, plus MinIO in Docker Compose with automatic bucket creation** + +## Performance + +- **Duration:** 2 min +- **Started:** 2026-04-05T10:14:02Z +- **Completed:** 2026-04-05T10:16:24Z +- **Tasks:** 2 +- **Files modified:** 7 + +## Accomplishments +- Storage service wrapping @aws-sdk/client-s3 with forcePathStyle for MinIO compatibility +- Presigned URL helpers (withImageUrl, withImageUrls) for enriching API responses +- MinIO in both Docker Compose files with mc init container for automatic bucket creation +- S3 environment variable documentation in .env.example + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Install S3 SDK and create storage service** - `f845f87` (feat) +2. **Task 2: Add MinIO to Docker Compose and update env config** - `88f988c` (chore) + +## Files Created/Modified +- `src/server/services/storage.service.ts` - S3 storage abstraction with 5 exported functions +- `tests/services/storage.service.test.ts` - 8 unit tests with mocked S3Client +- `docker-compose.dev.yml` - Added MinIO + minio-init with fixed dev credentials +- `docker-compose.yml` - Added MinIO + minio-init with env var credentials, removed uploads volume +- `.env.example` - Added S3 configuration section +- `package.json` - Added @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner +- `bun.lock` - Updated lockfile + +## Decisions Made +- Private bucket with presigned URLs (no public-read) for security +- 1-hour presigned URL expiry default, configurable via S3_PRESIGN_EXPIRY env var +- No console port (9001) exposed in production compose, only API port (9000) +- Dev compose uses fixed minioadmin/minioadmin credentials for simplicity +- Production compose removed uploads volume (replaced by MinIO object storage) + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered +None + +## User Setup Required +None - no external service configuration required. MinIO starts automatically via Docker Compose. + +## Next Phase Readiness +- Storage service ready for Plan 02 (image route refactoring) to call uploadImage/deleteImage/getImageUrl +- withImageUrl/withImageUrls helpers ready for API response enrichment +- Docker Compose MinIO available for integration testing + +--- +*Phase: 17-object-storage* +*Completed: 2026-04-05*