# 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.
