Layer 1 — Content Sources
Gmail Inbox
label: to-translate
+
to-translate → processed → translated
  • Forward any article to the Gmail account
  • Apply the to-translate label to queue it
  • After processing, label swaps to translated — never re-processed
Permanent Queue
label: queue
+
queue
  • Always-available featured articles
  • Survive the "Clear all" action
  • Great for curated content you return to often
Demo Mode
paste any text
+
  • Paste any English article for instant translation
  • No Gmail account or labels required
  • Calls translate-text API directly
  • Ideal for portfolio demos
Layer 2 — Auth & Security
Edge Middleware
middleware.ts
+
  • Basic auth gate on all non-API routes
  • Runs at the Vercel edge — before any function executes
  • Credentials stored as Vercel environment variables
Gmail OAuth 2.0
Google API v1
+
  • Refresh-token flow — no user login required at runtime
  • Token refreshed on each serverless function invocation
  • Scoped to Gmail read + label modification only
API Shared Secret
Vercel env variable
+
  • Frontend and backend share the same secret
  • Injected into the frontend bundle at build time via Vercel env
  • Validated on every serverless function call
Layer 3 — Serverless Processing
fetch-and-translate
api/fetch-and-translate.js
+
✦ calls Claude Sonnet 4.6
  • Fetches all emails labeled to-translate
  • Sends each article to Claude paragraph-by-paragraph
  • Forced tool_choice + XML delimiters for reliable pairing
  • Swaps label to translated on success
  • 300s Vercel Pro timeout for long articles
fetch-queue
api/fetch-queue.js
+
  • Returns all emails labeled queue
  • Queue articles are never deleted or re-labeled
  • Merged with localStorage cache on the frontend
translate-text
api/translate-text.js
+
✦ calls Claude Sonnet 4.6
  • Translates a single pasted text (Demo Mode)
  • Same Claude pipeline — tool_choice + XML pairing
  • No Gmail interaction — self-contained
send-to-kindle
api/send-to-kindle.js
+
  • Exports a translated article to Kindle
  • Formats bilingual content for e-reader display
Layer 4 — Reader Interface
Home Queue
pages/Home.tsx
+
  • Lists all available translated articles
  • Merges Gmail fetch results with localStorage cache
  • Permanent queue articles always appear at the top
Bilingual Reader
pages/Reader.tsx
+
  • French paragraph above, English below — per ParagraphPair
  • Left accent bar visually ties each FR/EN pair together
  • Immersive parallel reading for language acquisition
Text-to-Speech
Web Speech API
+
  • Click speaker icon or French text to hear pronunciation
  • Per-paragraph speed controls: 0.5×, 0.8×, 1.0×
  • French locale voice — native accent playback
Persistent Cache
utils/storage.ts
+
  • Articles stored in localStorage after first fetch
  • Survive page refresh — no redundant API calls
  • "Clear all" removes non-queue articles only
Deployed on Vercel
React frontend + 4 serverless functions · 300s max function duration
Edge middleware runs globally
before any route resolves