System Architecture
CoquiTitle is built as a serverless pipeline using AWS Lambda functions, with Supabase PostgreSQL for data storage and Google Vertex AI for LLM processing.
High-Level Architecture
Lambda Functions
| Lambda | Type | Memory | Timeout | Purpose |
|---|---|---|---|---|
coquititle-api | Zip | 512MB | 30s | REST API endpoints |
coquititle-ocr-processor | Zip | 2048MB | 300s | Document AI OCR processing |
coquititle-extractor | Container | 1024MB | 900s | Multi-pass data extraction |
coquititle-pending-docs-processor | Zip | 1024MB | 300s | Pending document processing |
coquititle-title-state-builder | Container | 512MB | 30s | Deterministic title derivation |
coquititle-evidence-resolver | Container | 512MB | 120s | Evidence validation + LLM fallback |
coquititle-report-generator | Container | 1024MB | 900s | Multi-pass report generation |
Technology Stack
Cloud Infrastructure
| Service | Provider | Purpose |
|---|---|---|
| Compute | AWS Lambda (container) | Pipeline execution |
| Storage | AWS S3 | PDFs, JSON reports |
| Database | Supabase PostgreSQL | Structured data, RLS |
| Realtime | Supabase Realtime | Progress events via WebSocket |
| Secrets | AWS Secrets Manager | API keys, DB credentials |
AI/ML Services
| Service | Provider | Model | Purpose |
|---|---|---|---|
| OCR | Google Document AI | Enterprise OCR | Text + token extraction |
| Extraction | Google Vertex AI | Gemini 2.5 Flash (configurable) | Multimodal 2-pass extraction |
| Report Gen | Google Vertex AI | Gemini 2.5 Flash (configurable) | Multi-pass prose generation |
| Evidence Fallback | Google Vertex AI | Gemini 2.5 Flash | LLM matching for garbled OCR |
Shared Modules
The pipeline uses several shared Python modules located in lambdas/shared/:
LLM Client (shared/llm_client.py)
Centralizes all Vertex AI interactions:
- Thread-safe singleton client initialization
- Automatic Langfuse tracing integration
- Retry logic with exponential backoff for rate limits
- Context caching for multimodal content
Prompt Registry (shared/prompt_registry.py)
Manages prompts via Langfuse with local fallbacks:
- Remote prompt engineering updates without code deploys
- Mustache template support
- Automatic fallback to local prompts if Langfuse unavailable
Title State Module (shared/title_state/)
Deterministic ownership derivation (version tsb_v2):
build_title_state()- Derives ownership state from extraction databuild_chain_of_title()- Builds chronological chain interleaving acquisitions and eventsderive_current_rights()- Computes final ownership from ganancial/condominio/individual rulesrights_derivation.py- Core derivation rules and validation- No LLM dependency for reproducibility
Output structure:
{
"version": "tsb_v2",
"chain_of_title": [...], // Chronological list of acquisitions + events
"confidence_summary": {...}, // Status: confident/needs_review/unknown
"review_flags": [...], // Validation issues with severity
"derivation_map": {...} // Audit trail of which rules produced which outputs
}
Status Flow
Real-time Progress
Progress events are emitted to case_events and delivered via Supabase Realtime:
emit_event(conn, case_id, 'extraction', 'Pass 1: property complete (1/3)', 15,
metadata={
'substep': 'pass1_property',
'input_tokens': 12500,
'output_tokens': 1200,
'result_summary': '4 linderos, 1 cabida, 12 evidence'
})
Events are tagged with run_id so the UI can subscribe to the current run.
Related Pages
- Extraction Pipeline - OCR and multi-pass extraction details
- Evidence Resolution - Matching strategies and LLM fallback
- Report Generation - 3-pass report generation
- Data Model - Database schema and relationships
- Observability - Langfuse tracing and metrics