πŸ—ΊοΈ The map

Architecture

The whole system on one page. Every module in this course zooms into one region of this map.

TL;DR

A Next.js app talks directly to Postgres through store functions β€” no REST layer. Three background jobs (PDF compile, discovery cron, reminder cron) run on Trigger.dev and share the same stores. Five packages keep domain logic, data access, AI, connectors, and the LaTeX compiler behind clean boundaries. The database is the only shared state.

The system, clickable

Vercel β€” the request path

πŸ–₯️
Pages (server components)
✍️
Server actions
πŸ”‘
Clerk auth

Trigger.dev β€” the background path

πŸ“„
compile-resume-pdf
πŸ“‘
scheduled-discovery
⏰
reminder-delivery

Shared packages

🧠
@wera/core
πŸ—„οΈ
@wera/db
πŸ€–
@wera/ai
πŸ”Œ
@wera/connectors
🧯
@wera/resume

External services

🐘
Neon Postgres
πŸͺ£
Cloudflare R2
✨
OpenAI
πŸ•·οΈ
Apify
πŸ“¬
Resend
Click any component to learn what it does

The primary journey: paste a URL, get a tracked application

This is the flow the whole product exists to serve. Step through it:

πŸ§‘β€πŸ’»
Browser
✍️
Server action
πŸ€–
AI boundary
πŸ—„οΈ
Postgres
Click "Next Step" to begin

The shape of the whole design

Wera is built like a well-run kitchen-table workshop with a locked toolshed. The workshop (the web app) does everything by hand, in the open, with tools it fetches from clearly labeled drawers (the packages). Anything dangerous β€” a stranger's LaTeX, a scraper's output, an AI's claims β€” never enters the workshop directly: it goes through an inspection bench first, where it's checked, stamped, and logged. And anything slow or scheduled happens in the shed out back (background jobs), so the workshop never blocks.

It's a modular monolith: one deployable app plus internal packages with one-way dependencies (app β†’ packages, never the reverse), sharing a single Postgres instance as the only state. Reads bypass any API layer (server components call stores in-process); writes are server actions returning discriminated-union states. Background work is at-least-once by platform, made safe by idempotency keys with unique indexes at every side effect. Untrusted input crosses three hardened boundaries β€” zod schemas (connectors, AI), a subprocess sandbox (LaTeX), and an SSRF guard (user URLs).

Tradeoff: no service boundaries means no independent scaling and no fault isolation between features β€” accepted because the write volume is one human. The failure mode to watch is the Neon HTTP driver: every statement is a round-trip, so a 500-item ingest is ~2,500 sequential HTTP calls; the code compensates with caps and periodic progress flushes rather than batching.

πŸ’‘
The one-way street rule

Packages never import from the app, and core imports from nothing at all. When you can draw every arrow pointing the same direction, you can test each layer in isolation and replace any vendor at the seam. Engineers call this a dependency discipline.