4.2 KiB
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 statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin 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.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree per
proposal.md. package.jsonat0.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.jsonextendinglibrary.json;vitest.config.tswithcreateTestConfig().- 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; throwIMGPROXY_INVALID_SOURCE_URLon 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
ImgproxyUrlBuilderinsrc/builder/imgproxy-url-builder/imgproxy-url-builder.ts:build(opts): validate viaImgproxyTransformOptionsSchema; callbuildProcessingPath; encode source; return${baseUrl}/insecure/${processingPath}/${encodedSource}.buildSigned(opts): same path; compute HMAC-SHA256 signature using@suaveplan/cryptowith key/salt; return${baseUrl}/${signature}/${processingPath}/${encodedSource}. ThrowIMGPROXY_SIGN_FAILEDif key/salt not configured.- OTel counter
imgproxy.urls_built_totalwithsignedattribute.
- 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 toopenspec/archive/2026-04-24-enterprise-server-caddy-imgproxy/.