Files
suaveplan/openspec/changes/enterprise-server-caddy-imgproxy/tasks.md
2026-05-27 23:29:53 +01:00

4.2 KiB

Tasks: enterprise-server-caddy-imgproxy

Change ID: enterprise-server-caddy-imgproxy Package: @suaveplan/caddy-imgproxy Target path: server/infra/caddy-imgproxy Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/crypto


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal.md.
  • package.json at 0.1.0, "sideEffects": false, exports "." + builder + utils/path-encoder.
  • Deps: @suaveplan/error workspace:^, @suaveplan/types workspace:^, @suaveplan/crypto workspace:^, zod catalog:forms, @opentelemetry/api catalog:observability, tslib catalog:build.
  • DevDeps: vitest catalog:testing, @vitest/coverage-istanbul catalog:testing, @suaveplan/testing workspace:^.
  • tsconfig.json extending library.json; vitest.config.ts with createTestConfig().
  • Scripts: lint, typecheck, test, test:coverage, build, docs:check.

2. Types and errors

  • Define all option interfaces and Zod schemas in src/types/imgproxy.types.ts.
  • Write imgproxy.types.md (≥200 words, both examples, API reference).
  • src/error-codes.ts: three codes; registerImgproxyErrorCodes(); eager call.

3. Path encoder utility

  • Implement src/utils/path-encoder.ts:
    • encodeSourceUrl(url: string): string — URL-safe base64 encode of source URL; throw IMGPROXY_INVALID_SOURCE_URL on empty/invalid input.
    • buildProcessingPath(opts: ImgproxyTransformOptions): string — assemble the imgproxy processing chain string (e.g. rs:fit:800:600/q:80/f:webp/...).
  • Write path-encoder.test.ts: each processing option produces correct segment; empty source throws; combined options produce correct path.
  • Write path-encoder.md (≥200 words).

4. URL builder

  • Implement ImgproxyUrlBuilder in src/builder/imgproxy-url-builder/imgproxy-url-builder.ts:
    • build(opts): validate via ImgproxyTransformOptionsSchema; call buildProcessingPath; encode source; return ${baseUrl}/insecure/${processingPath}/${encodedSource}.
    • buildSigned(opts): same path; compute HMAC-SHA256 signature using @suaveplan/crypto with key/salt; return ${baseUrl}/${signature}/${processingPath}/${encodedSource}. Throw IMGPROXY_SIGN_FAILED if key/salt not configured.
    • OTel counter imgproxy.urls_built_total with signed attribute.
  • Export createImgproxyUrlBuilder(options).
  • Write imgproxy-url-builder.types.ts.
  • Write imgproxy-url-builder.test.ts (≤500 lines): unsigned URL format, signed URL HMAC verification against known test vector from imgproxy docs, all transform options produce correct segments, invalid options throw typed error.
  • Write imgproxy-url-builder.md (≥200 words, simple + advanced, API reference).

5. Integration tests

  • tests/integration.test.ts: build several real URLs and verify they match known imgproxy signature test vectors; verify path encoding round-trips; signed vs unsigned URL format diff.

6. Docs + verify + publish

  • Root README.md: docker-compose Caddy + imgproxy example, quick-start URL building, API table, signing setup.
  • bunx turbo lint --filter=@suaveplan/caddy-imgproxy — zero errors.
  • bunx turbo typecheck --filter=@suaveplan/caddy-imgproxy — zero errors.
  • bunx turbo test --filter=@suaveplan/caddy-imgproxy — all pass.
  • bunx turbo test:coverage --filter=@suaveplan/caddy-imgproxy — 100%.
  • bun scripts/publish.ts --package @suaveplan/caddy-imgproxy.
  • Update CLAUDE.md; archive to openspec/archive/2026-04-24-enterprise-server-caddy-imgproxy/.