# Implementer — F-011 Product images ## Summary Implemented product image support inside the catalog module with a swappable storage boundary, PostgreSQL persistence, admin image endpoints, and product serialization that exposes ordered images with alt text. ## Code changes - Added image domain model and storage port: `project/src/modules/catalog/domain/image.ts`. - Added product image repository port: `project/src/modules/catalog/domain/ports.ts`. - Added use cases: `project/src/modules/catalog/application/image-use-cases.ts`. - Added local-first URL storage adapter: `project/src/modules/catalog/infrastructure/local-product-image-storage.ts`. - Added PostgreSQL image repository: `project/src/modules/catalog/infrastructure/pg-product-image-repository.ts`. - Added migration: `project/migrations/009_catalog_product_images.js`. - Extended catalog routes: `project/src/modules/catalog/api/catalog.routes.ts`. - Added unit coverage: `project/src/modules/catalog/tests/image-use-cases.test.ts`. ## API behavior - `GET /productos/:slug` now returns product-level `images`, ordered by repository ordering, with `url`, `altText`, `position`, and `role`. - `GET /products/:id/images` lists product-level images. - `POST /products/:id/images` attaches an image. Admin-only. Body: `url`, `altText`, `role`, optional `variantId`, optional `position`. - `DELETE /products/:id/images/:imageId` detaches an image. Admin-only. - `PATCH /products/:id/images/reorder` reorders images. Admin-only. ## Data rules - Images can belong to a product or a product variant. - Variant images must reference a variant that belongs to the same product. - One `main` image is allowed per product-level scope and per variant scope. - Images are ordered by `position`, then `created_at`, then `id`. ## Evidence - `cd project && npm run lint` — PASS. - `cd project && npm run typecheck` — PASS. - `cd project && npm test` — PASS: 17 files passed, 7 skipped; 64 passed, 33 skipped. - `./scripts/verify.sh` — PASS. ## Notes - No new npm dependencies. - No binary upload, CDN, resize/optimization pipeline, or external object-store SDK added. - Integration tests remain skipped without `TEST_DATABASE_URL`, consistent with prior features.