Application workflow
End-to-end pipeline from project submission to compliance report. Each stage runs in-process inside the same Next.js node container; progress is streamed to the browser over Server-Sent Events.
Ingest
A user submits the project to scan.
simple-git clones the public repository at depth 1 into a per-scan workspace under data/scans/<id>/src.
multipart upload extracted with unzipper. A zip-slip guard rejects any entry escaping the scan root.
Index
One pass over the workspace builds a structured project context.
Capped 2000 files, ignoring node_modules / .git / build outputs. Detects primary languages.
README, SECURITY.md, model cards, datasheets, CI configs, manifests (package.json, pyproject.toml, Cargo.toml).
Per-article keyword grep. For TS/JS the TypeScript compiler returns the enclosing function/class. For Python an indent-aware walk returns the def/class block.
Fan-out — 10 article agents in parallel
Each agent runs through Vercel AI SDK with a Zod-typed Verdict schema. Provider-pluggable: Anthropic, OpenAI, or any OpenAI-compatible endpoint. Per-agent timeout (90s default) + 2 retries with exponential backoff.
Receives all 10 verdicts and emits a calibrated overall score (Art 9, 10, 11, 15 weighted higher) plus an executive summary highlighting top risks and strengths.
Stream
Verdicts surface in the UI the moment each agent finishes — no batch wait.
A singleton EventEmitter dispatches status / verdict / complete / error to a /api/scan/:id/stream Server-Sent Events handler.
EventSource client replaces skeleton placeholders with real Cards as each verdict arrives. Progress bars and findings update live.
Persist
Authoritative state lives in SQLite; the cloned source plus a JSON snapshot are kept on disk.
Tables: scans (one row per submission) and verdicts (nine rows per scan). Indexed on scan_id.
Full report mirrored alongside the cloned source for offline inspection and reproducibility.
Report
The user reviews the verdict — a tick/cross summary with drill-downs and an optional PDF export.
KPI strip, per-article aggregate heatmap, recent-scans table on /.
9-card grid with status, score bar, summary, file:line findings + recommendations.
Server-side pdfkit produces a paginated A4 report at /api/scan/:id/pdf.