Files
suaveplan/openspec/archive/2026-05-22-migrate-image/proposal.md
2026-05-27 23:29:53 +01:00

75 lines
4.7 KiB
Markdown

# Migrate @suaveplan/image to genesis
**Package**: `@suaveplan/image`
**Status**: PROPOSED
**Type**: spec-conformance
## Why
`@suaveplan/image` exists upstream (`../suaveplan/packages/universal/image`) but has not been migrated to genesis. It provides image format detection, metadata extraction, resize math, crop validation, and transform pipeline planning — primitives consumed by `compress-image` and downstream UI packages. Migrating it unblocks full enterprise-quality parity and brings the package into compliance with genesis conventions: `defineCodes`, Zod boundaries, OTel instrumentation, explicit barrels, and 100% coverage.
## What changes
- ADDED: `IMAGE_CODES` — stable `defineCodes("IMAGE", [...])` registry replacing upstream `ErrorCodes.registerMany` side effect.
- ADDED: `ImageError` — extends `SuaveplanError<ImageCode>` with typed `ImageErrorContext`.
- ADDED: Zod schemas for every public boundary (`ImageProcessorConfigSchema`, `CropRegionSchema`, `ResizeOptionsSchema`, `TransformOpSchema`, `TransformPipelineSchema`, `ImageMetadataSchema`).
- ADDED: OTel counters (`image.metadata.extracted_total`, `image.transform.planned_total`) and histograms (`image.metadata.extract_duration_ms`, `image.transform.plan_duration_ms`) emitted from production paths.
- ADDED: `ImageProcessor` spans for `extractMetadata` and `planTransform`.
- ADDED: `AbortSignal` support on `extractMetadata` and `planTransform` (pre-abort short-circuit).
- MODIFIED: `ImageProcessor` constructor now validates config via Zod and accepts optional `tracer` / `meter` from `@opentelemetry/api`.
- MODIFIED: `PipelineBuilder` quality setter now clamps to `[1, 100]` and throws `IMAGE_CODES.DIMENSIONS_INVALID` on bad input.
- REMOVED: Side-effect import `import "./error-codes.js"` — package is now `sideEffects: false`.
- REMOVED: `@deprecated` JSDoc aliases (`unknownFormat`, `invalidDimensions`, `invalidCrop`, `metadataParseFailed`, `invalidTransform`) — replaced by prose-only backward-compat re-exports.
## Out of scope
- Actual pixel buffer encoding/decoding — `compress-image` and `exif` already cover compression and metadata I/O. This package remains a metadata + transform-planning library.
- Browser-specific APIs (`HTMLImageElement`, `CanvasRenderingContext2D`) — the package is universal-tier.
- Network fetch helpers — callers supply `Uint8Array` directly.
## Source mapping
This change derives from `../suaveplan/enterprise/image.md`.
| Requirement | Source lines | Notes |
|---|---|---|
| Zero browser / Node / React dependencies | L37 | verbatim |
| Zod schemas for public types | L38-L39 | extended: wired at every boundary |
| OpenTelemetry instrumentation | L41-L42 | extended: counters + histograms + spans |
| Structured errors via `@suaveplan/error` | L42 | extended: `defineCodes` + `SuaveplanError` |
| `AbortSignal` propagation | L43 | extended: pre-abort on sync entrypoints |
| Test coverage ≥ 95% | L50 | extended: genesis requires 100% |
| No mocks | L53 | verbatim |
| `sideEffects: false` | L55 | verbatim |
| Biome clean | L58 | verbatim |
| Error hierarchy | L61 | verbatim |
### Requirements with no source line
| Requirement | Justification |
|---|---|
| Explicit named barrel exports (no `export *`) | Genesis-wide policy per openspec/AGENTS.md §6a |
| Test imports from `@suaveplan/testing/runner` | Genesis-wide policy per openspec/AGENTS.md §7 |
| Sibling `.md` for every `.ts` | Genesis-wide docs policy per openspec/AGENTS.md §4 |
| Subpath exports per feature module | Genesis-wide tree-shaking policy per openspec/AGENTS.md §6 |
## Verification approach
- `src/error-codes/error-codes.test.ts` — covers code registry, type assertions.
- `src/errors/errors.test.ts` — covers `ImageError` construction, context, cause, legacy alias round-trips.
- `src/types/image-types.test.ts` — covers format detection, aspect ratio, resize math, crop validation, MIME mapping.
- `src/processor/processor.test.ts` — covers metadata extraction, dimension parsing, size limits, transform planning, pipeline builder chaining, event emission.
- `src/processor/processor.spec-conformance.test.ts` — pins OTel instrument emission, Zod boundary rejection, strict-mode behaviors, AbortSignal pre-abort.
- `tests/dep-graph.test.ts` — pins zero non-catalog external deps.
- `tests/tree-shake.test.ts` — pins `sideEffects: false`.
## Migration impact
`@suaveplan/image` has zero current consumers in genesis (it does not yet exist). Downstream packages that will consume it (`compress-image`, future `react-image`) will adopt the new API in follow-up changes. No existing code is affected.
## Impact
### Affected dependents
No dependents (verified by `bunx turbo ls --filter=...@suaveplan/image` — package does not exist on disk yet).