A single Python/FastAPI application implementing all four Round-3 assessment workflows on one shared core:
| # | Workflow | What it does |
|---|---|---|
| 1 | Invoice Automation | Extract invoice PDFs → store → human review → department approval |
| 2 | PO Matching & Validation | Extract invoice → match against a Purchase Order (± tolerance) → discrepancy detection → payment routing |
| 3 | Resume Screening & Scheduling | Parse resume (PDF/DOCX) → score vs job description → shortlist → interview invite + calendar event |
| 4 | Support Ticket Automation | Classify/prioritize email → route to team → acknowledge → ticket lifecycle (+ RAG reply suggestions) |
All four share one pipeline:
email ingest → text extract → Gemini structured extraction → validate/clean
→ [domain step] → persist (Postgres) → [side effects] → human review → lifecycle + audit
Stack (the assessment's "n8n JSON or equivalent"): pure Python 3.12 / FastAPI, Supabase / Postgres (+ pgvector + Storage), Google Gemini. Workflow diagrams are in
docs/workflows/and rendered indocs/architecture.md; the orchestrator (core/pipeline.py) is the executable workflow definition. See ADR-001.
- Runs fully offline for demos/CI — replays sample emails/PDFs, writes outbound email +
calendar invites to
outbox/, serves Gemini from a replay cache. No credentials required. - Switches to live IMAP / SMTP / Google Calendar / Gemini purely via environment variables.
- Guaranteed-valid JSON via Gemini
response_schema+ Pydantic, with strip-fence/repair fallback. - Deterministic business logic: the LLM extracts; unit-tested Python decides (PO match engine, priority escalation, shortlisting).
- Resilience: retries with backoff, idempotency (Message-ID + dedupe hashing), a dead-letter table, confidence/anomaly-based routing to human review, structured logs with correlation ids.
- 87 tests (81 unit + a full end-to-end integration test across all four workflows).
# 1. Install
uv sync --extra dev # or: just setup
# 2. Start Postgres (pgvector) and create + seed the schema
docker compose up -d db # or: just db-up
cp .env.example .env
uv run anthrasync db init # or: just db-init
uv run anthrasync seed # purchase orders, job description, knowledge base
# 3. Run each workflow end-to-end, fully offline
uv run anthrasync run invoice --input samples/invoice/emails/ # or: just demo-invoice
uv run anthrasync run po_match --input samples/po_match/emails/ # just demo-po
uv run anthrasync run ticket --input samples/ticket/emails/ # just demo-ticket
uv run anthrasync run resume --input samples/resume/emails/ # just demo-resume
# 4. Review dashboard + API
uv run anthrasync serve # http://127.0.0.1:8000 ( /dashboard , /docs )Outbound emails and calendar invites appear in outbox/; stored documents in storage/.
Each workflow lives in src/anthrasync/workflows/<key>/ (self-contained: schemas.py,
prompt.md, workflow.py, models.py, status.py). The AI prompts are the prompt.md
files (plus jd_prompt.md for Task 3).
- Task 1 — Invoice (
invoice/): extracts 15 fields incl. line items, flags gross≠net+VAT anomalies, detects duplicates (vendor+invoice#hash), stores asDraft; a scheduled sweep emails department approvers; approve/reject →Fully Approved/Rejected. - Task 2 — PO Matching (
po_match/): reuses invoice extraction, retrieves the PO, runs a deterministicmatch_engine.py(vendor/PO#/currency/qty/price/net/tax/total with configurable tolerance), and applies rules →Ready for Payment/Procurement Review/Rejected. - Task 3 — Resume (
resume/): parses PDF and DOCX, scores against the seeded JD (second Gemini pass) blended with pgvector semantic similarity, shortlists (≥80 / 60–79 / <60), and for shortlisted candidates sends an interview invite +.icsand setsInterview Scheduled. - Task 4 — Support Tickets (
ticket/): triage (category/priority/sentiment/tags), rule-based priority escalation, configurable category→team routing, RAG reply suggestions over a pgvector knowledge base, customer acknowledgement email, and a 5-state lifecycle.
Full list with defaults in .env.example. The most important:
| Variable | Default | Purpose |
|---|---|---|
APP_MODE |
offline |
offline (file email, outbox, .ics, local storage) or live |
GEMINI_MODE |
replay |
replay (fixtures/cache, no key) or live (calls Gemini) |
GEMINI_API_KEY |
— | required only when GEMINI_MODE=live |
DATABASE_URL |
local pgvector container | async Postgres URL |
ENABLED_WORKFLOWS |
invoice,po_match,ticket,resume |
which workflows to mount |
PO_MATCH_TOLERANCE_PCT |
2.0 |
± tolerance for PO matching |
RESUME_SHORTLIST_SCORE / RESUME_REVIEW_SCORE |
80 / 60 |
shortlisting thresholds |
CONFIDENCE_REVIEW_THRESHOLD |
0.75 |
below this → human review |
GMAIL_USER / GMAIL_APP_PASSWORD |
— | live IMAP/SMTP |
GOOGLE_SERVICE_ACCOUNT_JSON |
— | live Google Calendar |
uv run pytest -q # all tests (or: just test)
uv run pytest tests/unit -q # fast, no DB/network (or: just test-unit)Unit tests cover the match engine, validators, routing/escalation, shortlisting, the state
machine, and the LLM replay client. The integration test (tests/integration/) drives all four
workflows end-to-end against the local Postgres.
Set APP_MODE=live, GEMINI_MODE=live, and provide GEMINI_API_KEY (+ GMAIL_* for email,
GOOGLE_SERVICE_ACCOUNT_JSON for calendar). No code changes — the adapters switch automatically.
For Supabase cloud, point DATABASE_URL/DATABASE_URL_SYNC at your project and set SUPABASE_URL
/ SUPABASE_SERVICE_KEY to use Storage.
| Deliverable | Location |
|---|---|
| Exported workflow(s) / equivalent | docs/workflows/*.mmd + docs/architecture.md + core/pipeline.py |
| Source code | src/anthrasync/ |
| Database schema | db/schema.sql |
| AI prompts | src/anthrasync/workflows/<task>/prompt.md (+ jd_prompt.md) |
| Sample test data | samples/ |
| README / setup / assumptions | this file + ADR-001 |
| Demo script | docs/demo-script.md |
- Supabase (Postgres) is the sole datastore — no Airtable/NocoDB. Justified as the "or equivalent" (managed Postgres + pgvector + Storage) in ADR-001.
- Offline replay is the canonical demo path; live providers are wired but optional.
- Building all four exceeds the "pick one" requirement by choice; each task is independently
runnable (
ENABLED_WORKFLOWS) and submittable. - Money uses
Decimal; currencies normalized to ISO codes; dates to ISO-8601. - LLM replay fixtures under
tests/fixtures/gemini/represent Gemini's output for the sample inputs, making demos deterministic and free to run.
src/anthrasync/ core/ (shared platform) · workflows/ (4 plugins) · api/ · web/dashboard/
db/ schema.sql
docs/ architecture.md · workflows/ · decisions/ · demo-script.md
samples/ per-task emails + PDFs/DOCX + PO/JD/KB reference data
tests/ unit/ · integration/ · fixtures/gemini/
scripts/ sample-data generators