BatchCodeCheck — Cosmetics Batch Code Decoder

Project Info

  • Client Own product
  • Year 2026 → present
  • Category Web tool / Cosmetics
  • Stack Next.js 15 (App Router), React 19, TypeScript, Tailwind v4, npm workspaces monorepo with a shared decoder package, SQLite (better-sqlite3, WAL), Cloudflare Turnstile, Brevo SMTP, PM2 cluster
  • AI Claude Vision reads the code from a photo — and only reads it: the date is always computed by the rules engine

Project Description

Every cosmetics package carries a batch code stamped by the filling line, and almost nobody can read it. BatchCodeCheck decodes it into a production date: type the code or photograph it, optionally name the brand, and the site returns the date together with the rule it came from — the manufacturer group, the scheme, and how many real codes that scheme has been checked against. Where a brand's scheme is not confirmed, the site says so instead of guessing.

The core decision: a scheme is data with a status, not code. Every rule in the decoder carries verified / unverified, a count of reference observations and a source. A rule becomes verified only when at least five observations from one group leave a single hypothesis that agrees with an exact reference — a date printed on the same pack, a regulator recall listing lots and dates (openFDA), a scheme the brand publishes itself, or a reply from its support. Today the site reads 19 schemes across L'Oréal, Estée Lauder, Shiseido, Kenvue, P&G, Beiersdorf, Kao, Henkel, Burt's Bees and Dr. Bronner's; brands whose format changes inside the group (Maybelline, Chanel, Dior) are refused on purpose — a wrong date costs more than an honest "we don't know".

Architecture: an npm-workspaces monorepo with a Next.js 15 app and a shared package holding the decoder engine, so a mobile client can reuse it as is. The engine returns only codes and numbers, never prose — every sentence comes from a dictionary and dates are formatted with Intl.DateTimeFormat. Photos are downscaled on the client and read by Claude Vision; every API route is gated by Cloudflare Turnstile on the server. An "I know the real date" form collects reference samples into SQLite with a Brevo notification, and the coverage table, brand pages, sitemap and FAQPage markup are all built from the same rule data — adding a rule updates the whole site.

BatchCodeCheck — schemes it can read and where to find the code on a package