Imported from yunniko/photo-metadata-cleaner (
AGENTS.md). Install upstream withnpx skills add yunniko/photo-metadata-cleaner. Copyright stays with the author.
photo-metadata-cleaner — project conventions
Read HANDOVER.md first: current state, decision record, next steps. Goal
in GOALS.md (G-001). Parent initiative in E:\CLAUDE\projects\svc-lab\;
company-wide standards in E:\CLAUDE\COMPANY\.
- Stack: Next.js App Router, TypeScript, Tailwind. No database, no auth, no
accounts. Metadata reading (
exifr) and removal (canvas redraw) both run entirely client-side — no API routes, nothing is ever sent to a server. Keep it that way; this project's entire pitch depends on it being literally true. lib/strip-metadata.ts'sstripPhotoMetadataremoves metadata by redrawing the source image onto a fresh canvas and re-encoding — this is what actually discards the EXIF/XMP/ICC bytes (canvas pixel data never carries them), not a separate "delete these tags" step. Don't add a tag-deletion library here; the redraw is both simpler and more thorough. Do not add manual EXIF-orientation correction to this path — every current browser already auto-rotates a decoded JPEG's pixels to match its orientation tag beforenaturalWidth/drawImagesee them, so a second, manual correction on top double-rotates the result. An earlier version of this function did exactly that; a real e2e run against a rotated fixture caught it (seeHANDOVER.md's decision record) before it shipped.lib/exif-metadata.tsseparates the pure formatting logic (summarizeMetadata, unit-tested with plain mock tag objects matching exifr's documented output shape) from the IO-dependent parsing call (readPhotoMetadata, covered by e2e only). Keep that split — don't move formatting logic behind the async parse call.scripts/generate-test-fixtures.mjsbuilds real JPEGs with real embedded EXIF/GPS viapiexifjs+jpeg-js— both synthetic, so there's no third-party photo/licensing question. Runnpm run generate-fixturesonce before the firstplaywright test; fixtures are gitignored, not committed.npm install/npm cineed--legacy-peer-deps(a live npm/arborist bug, not specific to this project — seesvc-lab/HANDOVER.md).- Two test layers:
npx vitest run(unit — pure orientation math and metadata formatting only) andnpx playwright test(e2e — real file upload, real EXIF parsing, real canvas redraw, real triggered downloads against the generated fixtures). Both must pass before calling a change done; also runnpm run build— it catches server/client boundary bugs the others don't. - See
E:\CLAUDE\COMPANY\INFRASTRUCTURE_DEPLOY.mdfor the redeploy command once live.
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ (resolved from this file's directory; in monorepos the next package may not be visible from the repo root) before writing any code. Heed deprecation notices.
This block is written and re-added by next dev — verify at node_modules/next/dist/server/lib/generate-agent-files.js. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
