Case study
OrigenLab
Production full-stack operations platform: Astro public site, Python email intelligence pipeline, SQLite operational store, read-only FastAPI, optional Postgres mirror reporting, and React operator dashboard
OrigenLab distributes laboratory equipment across Chile (Ortoalresa centrifuges, SERVA reagents, category hubs for food/QC/clinical labs). I built a production full-stack operations platform across four apps: public Astro site, Python email intelligence pipeline, SQLite operational store, read-only FastAPI operator API, optional Postgres mirror reporting, and a React operator dashboard. Previews and JSON shapes below are sanitized—no proprietary mail or customer content.
Problem
Leads and threads lived across mailboxes and ad hoc sheets. Reporting meant manual copy-paste; outreach risked duplicates and emails that ignored prior sends.
The business needed software that matched real process: review before send, traceable exports, and a schema that could answer operational questions without exposing raw mail to everyone.
Full-stack scope
Production full-stack operations platform for OrigenLab: Astro public site, Python email intelligence pipeline, SQLite operational store, read-only FastAPI operator API, optional Postgres mirror reporting, and a React operator dashboard—four deployable apps in one monorepo, with sensitive mail and SQLite living outside git.
- apps/web — Astro 6 marketing (origenlab.cl)
- apps/email-pipeline — ingest, SQLite truth, outbound safety, reports, operator CLIs, mutation scripts
- apps/api — read-only FastAPI on port 8001 (SQLite operator routes; optional mirror reporting via /mirror/*; typed demo-safe response contracts)
- apps/dashboard — multi-section React operator dashboard (read-only; human-reviewed outreach)
Why this matters
The system turns scattered email history into reviewable commercial workflows while keeping sensitive data private and preventing unsafe outbound automation. Operators get sanitized previews, mirror reporting when Postgres is synced, explicit gates, and documented demo-safe API surfaces—no autonomous send path.
From public presence to commercial intelligence
A product-forward public site and reusable commercial HTML connect to a local-first ops layer: SQLite as operational truth, optional Postgres mirror for reporting, read-only FastAPI for the dashboard, operator CLIs and reports for deep SQLite review, and a React operator dashboard for day-to-day triage—always with sanitized previews in this case study.
System surfaces
Four deployable apps plus shared commercial HTML assets: public marketing, email intelligence pipeline, operator API, and dashboard. The pipeline connects them through data, safety rules, and human-reviewed workflows—not through autonomous sends or API writes.
Live marketing site: origenlab.cl · Previews below are sanitized mocks (no proprietary HTML pasted in).
01 · Public website (mock)
OrigenLab
Equipos para laboratorio, cotizados con criterio técnico
Laboratorios de servicio, universidades, clínicas e industria en todo Chile.
- Valdivia · cobertura nacional
- Cotización mail/WhatsApp
- Asesoría previa
Ortoalresa
Digicen 22 R
Microcentrífuga refrigerada · ficha y PDF en sitio
Líneas disponibles para cotización
-
Ortoalresa
Centrífugas Ortoalresa
Cinco modelos en catálogo · comparación en /productos/centrifugas
-
SERVA
Reactivos e insumos SERVA
BlueSlick™, TEMED, REPEL-SILANE en página de marca
Explore por necesidad del laboratorio
- Alimentos
- Control de calidad
- Laboratorio clínico
Cómo trabajamos
- 1
Cuéntenos su necesidad
- 2
Revisamos alternativas
- 3
Enviamos cotización
- 4
Coordinamos condiciones
02 · Commercial HTML email (mock)
Same value proposition, packaged for inboxes: table-based layout, mobile fallbacks, and dark-mode-safe surfaces.
HTML email mock
Hero / catálogo
Bloque visual (producto o slideshow) — placeholder en este preview
Presentación comercial · OrigenLab
OrigenLab para sus necesidades de laboratorio
Presentación breve y visual, con líneas disponibles para cotización y conversaciones iniciales.
Quiénes somos
Enfoque en equipos para laboratorios de servicio e investigación, con presencia comercial en todo Chile y asesoría previa a la compra.
Líneas destacadas del catálogo
SERVA
Electroforesis
Reactivos, geles y sistemas HPE™.
Ortoalresa
BIOCEN 22
Microcentrífuga compacta.
Löser / KNAUER
Osmometría
Opciones por punto de congelación.
IKA / Hielscher
Dispersión y ultrasonidos
Dispersión rotor-estator y ultrasonidos.
03 · Data & safety flow
Interactive map
Operational pipeline
Tap a node — overview updates below. Three layers: public → data → safety.
A · Public / commercial
B · Data / backend
Ingest → store → marts → mirror → API
C · Operator / safety
Sent history becomes safety memory
Outbound is logged in normal mail channels, then re-ingested so future checks and suppression stay accurate.
—
- Role
- Why
- Tech
Engineering decisions
- SQLite operational truth · optional Postgres mirror
- apps/api read-only on :8001 · email-pipeline writes
- Operator routes + /mirror/* reporting
- Prospectos via lead_intel mirror (human-reviewed)
- Guarded outbound + human-reviewed drafts
- React smoke + pytest on parsers/exports
04 · Pipeline, Postgres mirror & API
Backend & dashboard
Email pipeline, operator API, mirror reporting, and dashboard
SQLite stays authoritative for ingest, mart rebuilds, outbound safety, and mutation scripts in apps/email-pipeline. apps/api exposes a read-only operator API on port 8001 — no ingest, no send, no record mutation. An optional Postgres mirror feeds mirror reporting routes (/mirror/*) when synced; a Postgres URL is not required for the normal SQLite operator API.
apps/email-pipeline
PST / Gmail → SQLite archive → rebuildable business marts → outbound safety sidecars → optional commercial OC promotion → optional mirror sync. Operator CLIs and report outputs remain the deep SQLite review surface; all writes stay here.
- 1.
Gmail / IMAP ingest → SQLite archive (apps/email-pipeline) - 2.
build_business_mart.py --rebuild (contacts, orgs, signals) - 3.
Optional: promote confirmed OCs → commercial_purchase_* (SQLite) - 4.
Optional: sync_dashboard_postgres_mirror.py → Postgres reporting mirror - 5.
uvicorn origenlab_api.main:app --port 8001 (apps/api) - 6.
npm run dev in apps/dashboard (React :5173) — smoke hits /health + /operator/status
apps/dashboard
Multi-section React operator dashboard—read-only, human-reviewed outreach. Sections include Today, inbox triage, opportunities, deals, Prospectos (lead intelligence), catálogo, suppliers, tenders, payments/logistics, contacts, and system. Consumes apps/api; does not send mail or replace SQLite truth.
- Today
- Inbox triage
- Opportunities
- Deals
- Prospectos
- Catálogo
- Suppliers
- Tenders
- Payments / logistics
- Contacts
- System
Prospectos: SQLite lead research imports → optional Postgres lead_intel mirror → GET /mirror/leads/* with filters (classification, sector, region, campaign bucket, score, blocked).
Monorepo layout
Four deployable apps; marketing never calls the pipeline at runtime. Sensitive mail and SQLite live under ~/data/origenlab-email/, not in git.
| App | Role |
|---|---|
| apps/web | Astro / Tailwind public marketing site (origenlab.cl) |
| apps/email-pipeline | Python / uv Gmail–PST ingest, SQLite marts, outbound safety, reports, operator CLIs, mutation scripts (no FastAPI) |
| apps/api | GET-only FastAPI operator API on :8001 (SQLite-first; optional mirror reporting) |
| apps/dashboard | React / Vite read-only operator dashboard |
Optional Postgres mirror
Optional Postgres mirror: reporting-only schemas for archive, mart, outbound, commercial, reporting, and lead_intel. Alembic manages DDL when the mirror is used; loaders copy from SQLite (eventually consistent). Mirror routes are read-only under /mirror/*; operator day-to-day routes read SQLite directly.
apps/api — health & operator plane
SQLite-first on port 8001. GET /health confirms liveness; GET /operator/status surfaces operator verdict. All routes are GET-only—no autonomous send, no ingest from HTTP.
Representative API payloads
Sanitized illustrative shapes only—full route lists stay in the tables below.
{
"scope": "canonical",
"contact_count": 412,
"organization_count": 198,
"opportunity_signal_count": 1203
} Optional Postgres mirror reporting—not SQLite operational truth.
{
"prospect_key": "lab-ejemplo-cl",
"classification": "equipment_buyer",
"region": "Los Ríos",
"score": 72,
"blocked": false
} Read-only Prospectos; human review before outreach.
Operator API (SQLite-first)
Core routes for Today, triage, and contact drilldown. All GET.
| Method | Path | Purpose |
|---|---|---|
| GET | /health | Liveness (SQLite operator plane) |
| GET | /operator/status | Operator verdict / staleness |
| GET | /cases/warm | Warm commercial case queue (sanitized previews) |
| GET | /opportunities/equipment | Equipment-first operator queue manifest |
| GET | /contacts/{email} | Read-only contact profile (Today side panel) |
Mirror reporting API (optional Postgres)
When Postgres is synced, dashboard sections can consume mirror reporting (routes under /mirror/*). Still read-only—no writes, no send path.
| Method | Path | Purpose |
|---|---|---|
| GET | /mirror/dashboard/summary | KPI counts (?scope=canonical|archive) |
| GET | /mirror/meta/dashboard-sync | Last mirror sync run |
| GET | /mirror/classification/summary | Label distribution (heuristic QA) |
| GET | /mirror/commercial/purchase-events | Confirmed purchase orders |
| GET | /mirror/outbound/readiness | Mirror pre-flight for outbound review |
| GET | /mirror/leads/prospects | Lead research prospects (filters, read-only) |
| GET | /mirror/leads/summary | Lead intel rollup |
| GET | /mirror/health/dependencies | Postgres + SQLite ping (when mirror enabled) |
05 · API demo, docs & access request
API demo & access
Read-only FastAPI demo surface with requestable access
The live operator API is protected because it sits near commercial and email-derived data. For portfolio review, I document the safe routes, response contracts, and demo order; access can be requested for a guided walkthrough or a redacted/mock deployment.
Safe demo route order
These are the routes I would show first in Swagger or curl. They are typed, read-only, and avoid raw message bodies.
- 01
GET /healthService liveness and read-only mode
Open first; no private business data.
- 02
GET /mirror/meta/dashboard-syncPostgres mirror freshness and aggregate counts
Shows reporting sync status without raw records.
- 03
GET /cases/warm?limit=2Warm operator-review cases
Use a small limit; sanitized previews only.
- 04
GET /opportunities/equipment?limit=2Ranked equipment opportunity queue
Best endpoint for business value.
{
"ok": true,
"service": "origenlab-api",
"mode": "operator-sqlite-readonly",
"backend": "sqlite",
"postgres_configured": true
} Small, typed readiness check for the read-only operator API.
{
"status": "success",
"elapsed_seconds": 95.34,
"canonical_contact_count": 2490,
"canonical_organization_count": 1064,
"canonical_opportunity_signal_count": 1014
} Freshness and aggregate mirror counts; no raw customer records.
Documentation links
How access works
- 1. Request a walkthrough or temporary demo access.
- 2. Use local Swagger or a protected deployment; production docs stay disabled.
- 3. Demo only the safe endpoints above unless data is mocked or redacted.
Production is not a public playground. The portfolio-safe path is a short guided demo, local Swagger, or a redacted/mock environment using the same response contracts.
What I built
- Redesigned origenlab.cl: split hero with featured Ortoalresa product, trust chips, Ortoalresa/SERVA commercial lines, three category hubs, quote process, and FAQ—typed catalog data with a validate-catalog CI guard.
- Product vitrine: five Ortoalresa microcentrífugas (local AVIF, PDFs, spec tables) plus comparison on /productos/centrifugas; SERVA reagent SKUs on the brand page; unified WhatsApp/mailto CTAs.
- Custom brand system: velocity-Verlet three-body mark in the header, static footer lockup, mint favicon, SVG export tooling, and internal logo-lab for motion QA.
- apps/email-pipeline: Gmail/PST ingest, SQLite archive + business marts, outbound safety, reports, operator CLIs, mutation scripts—no FastAPI.
- apps/api: read-only operator API on port 8001 (SQLite-first routes for health, warm cases, equipment opportunities, contacts; optional Postgres mirror reporting under /mirror/*).
- apps/dashboard: multi-section React operator UI (Today, inbox triage, opportunities, deals, Prospectos, catálogo, suppliers, tenders, payments/logistics, contacts, system)—read-only, no send path.
- Operator CLIs and report outputs for deep SQLite review; React for day-to-day operator workflows and mirror-backed reporting when Postgres is synced.
- Prospectos / lead intelligence: SQLite lead research imports, Postgres lead_intel mirror, mirror lead routes, filters by classification, sector, region, campaign bucket, score, and blocked status.
- Safe outbound: sent-history, suppression, duplicate prevention, human-reviewed LLM drafts (no auto-send); pytest + npm run smoke on API contracts.
Architecture
Four apps in one monorepo: apps/web (Astro marketing), apps/email-pipeline (Python ingest, SQLite truth, sync scripts, operator CLIs), apps/api (read-only FastAPI :8001), apps/dashboard (React operator UI). Marketing never calls the pipeline at runtime.
SQLite is authoritative for operational data and outbound safety. apps/api is GET-only and does not ingest, send mail, or mutate records. PostgreSQL mirror is optional/parked/reporting-oriented—synced from SQLite, consumed under /mirror/* when configured.
Operator routes serve Today and triage from SQLite; mirror reporting routes expose KPIs, classification, commercial events, outbound readiness, and lead prospects when Postgres is available.
Backend / data pipeline
Ingestion is incremental where possible; normalization steps are tested because email is never clean. Business views separate facts (what was received/sent) from proposed next actions and from heuristic classification labels.
- Operator runbook: ingest → build_business_mart → optional OC promote → (optional) sync_dashboard_postgres_mirror → uvicorn apps/api :8001 → React dashboard.
- GET /health and GET /operator/status for SQLite operator plane; GET /mirror/meta/dashboard-sync and GET /mirror/health/dependencies when mirror reporting is enabled.
- Confirmed purchase events (mirror commercial routes) vs heuristic classification QA—different trust levels, separated in the UI.
- pytest on parsers/exports; Vitest + npm run smoke on dashboard API wiring.
Safety and outbound gates
Automation stops at the risky edge: humans confirm sends. Software enforces what can be queued—history, suppression, duplicates—and makes the safe path obvious in the UI.
What I learned
The highest leverage features are often auditability and guardrails, not more model calls.
When data is sensitive, folder layout and runbooks are part of the product, not an afterthought.