# PHASE 3.5 — Due Diligence Multi-Fuente **Estado**: Phase 3.5.A en curso. Fundación lista, falta documento fetchers y PDF. **Objetivo macro**: dar al cliente DOS niveles de producto: - **Pre-screening ($15)** — 2-3 min, ~1 Firecrawl credit. Decide GO / NO-GO rapido. - **Reporte completo ($150)** — 5-15 min, ~2-5 creditos. PDF con TODOS los docs publicos. Esto monetiza el trabajo que ya se hace gratis (clerks publicos + PA + court records) y agrega valor por la sintesis + la curaduria de documentos. --- ## Tier system — que entrega cada producto ### Pre-screening ($15) — los 3 BASICOS | Documento | Fuente | Costo | Por que | |---|---|---|---| | **Final Judgment / Clean Deed** | Clerk records (CCIS / Acclaim / realauction docket) | Gratis | Confirma que hay caso real y el monto | | **Primary Lien (mortgage)** | Recorder Official Records | Gratis | El monto que el plaintiff reclama | | **Photo exterior** | PA (bcpa.net) o Zillow CDN fallback | 0-1 cred | Validacion visual basica | **Plus**: Zestimate + comps (1 cred) + tax assessed + plaintiff classification + LienPositionAnalyzer verdict (GO/NO_GO/MAYBE/INSUFFICIENT_DATA). **Entregable**: card en la app + "Pre-screening result" inline. NO PDF. ### Reporte completo ($150) — TODO lo publico Pre-screening +: - IRS NFTL (Notice of Federal Tax Lien) check - PACER bankruptcy check (chapters 7/11/13) - Code enforcement violations - Building permits / open permits - Property tax delinquencies (tax collector) - Sunbiz corporate filings (si owner es LLC) - Sales history del deed (ultimos 10 anios) - Comps detallados (5-10) - HOA/condo docs (si aplica) - Title chain summary - **PDF profesional** (~15-25 paginas) con header del cliente + branding Tiempo: 5-15 min. Costo Firecrawl: 2-5 cred (PA detail + comps + Sunbiz fallback). --- ## Phase 3.5.A — Foundation (en curso, 70% done) **Hecho**: - [x] `properties_store.py` — carpetas `properties/{STATE}/{County}/{deal_type}/{id}/` con subcategorias - [x] `dd_orchestrator.py` — esqueleto run_pre_dd / run_full_dd / should_auto_trigger_dd - [x] Pre-screening pipeline wired: court_records + tax_assessed + comps + price_validator + LienPositionAnalyzer - [x] Schema: `external_id` separado de `case_number` (migracion 280 deals movidos) - [x] PA photos GRATIS (Broward backfill 36/37 hits, $0) - [x] Cards en app.py con foto + 5 botones + pre-screening inline - [x] 41 FL counties registrados en realforeclose.com + 7 CO + 3 AZ **Pendiente Phase 3.5.A**: - [ ] UI dedicada para "Reporte completo" — boton ya esta, falta el flujo real (hoy ejecuta heuristica) - [ ] Categorias canonicas en `properties_store.py` definidas pero no todos los fetchers escriben ahi - [ ] `dd_orchestrator.run_full_dd()` hoy es placeholder — solo llama lo mismo que pre_dd **Done cuando**: cliente puede hacer click "Reporte completo" y ver un PDF generado, aunque tenga 5 secciones. --- ## Phase 3.5.B — Document fetchers (proximo bloque grande, ~2-3 semanas) ### Fetchers free (Playwright) — multi-county adapters Cada fetcher devuelve `{found: bool, documents: [{category, filename, url, content}], data: {}}` para que el orchestrator lo guarde en la carpeta correcta. | Fetcher | Output | Counties priority | |---|---|---| | `data_fetchers/court_records.py` | Final judgment, lis pendens, case status | Duval (ya hecho), Broward, Miami-Dade, Palm Beach, Orange | | `data_fetchers/recorder.py` | Deeds, mortgages, releases, assignments | Mismo set | | `data_fetchers/code_enforcement.py` | Open violations, liens | County-by-county (cada uno tiene portal distinto) | | `data_fetchers/building_dept.py` | Open permits, last inspection | Idem | | `data_fetchers/tax_collector.py` | Tax delinquencies, tax certificates | Mismo set | | `data_fetchers/property_appraiser.py` | Sales history, sketch, full record | Ya parcialmente (pa_photo_lookup.py) | **Arquitectura**: cada `data_fetchers/.py` exporta `fetch(county, state, identifier) -> dict`. Internamente switch por county a la implementacion correcta (`_fetch_broward`, `_fetch_miami_dade`, etc.). ### Fetchers federales / state-wide (gratis o Firecrawl bajo) | Fetcher | Estado | Notas | |---|---|---| | `data_fetchers/irs_nftl.py` | Pendiente | Search por owner_name en IRS NFTL DB — gratis pero rate-limited | | `data_fetchers/pacer.py` | Pendiente | Bankruptcy lookup — requiere cuenta PACER paga $0.10/page | | `data_fetchers/sunbiz.py` | Pendiente | Si owner es LLC, traer corporate filing FL state — gratis | | `data_fetchers/fl_dor.py` | Pendiente | FL Dept of Revenue — sales tax liens — gratis | ### Fallback universal — Firecrawl `/extract` Para counties FUERA de FL que aun no tienen scraper dedicado, usar `data_fetchers/firecrawl_anywhere.py` con schema generico (ver IDEAS_BACKLOG item #3). 4 cred per deal complete. **Done Phase 3.5.B cuando**: pre-screening + full report consume datos REALES de los 5 counties FL priority (Broward, Miami-Dade, Palm Beach, Orange, Duval). --- ## Phase 3.5.C — PDF report generator (~1 semana) ### Stack tecnico **Opcion A (recomendado): WeasyPrint** — HTML + CSS → PDF. Permite templates con Jinja2, CSS print rules, branding facil. **Opcion B: ReportLab** — codigo Python directo. Mas control, menos legible. Decision: WeasyPrint. ### Templates a crear ``` templates/reports/ pre_screening_summary.html # 2-3 paginas full_report.html # 15-25 paginas _header.html # branding cliente _footer.html # disclaimer legal _components/ plaintiff_box.html comps_table.html photo_grid.html documents_index.html ``` ### Secciones del Full Report 1. **Executive Summary** — verdict, top 3 risks, plaintiff, monto, address 2. **Property details** — fotos, sketch, PA data, year built, sqft, lot size 3. **Owner** — name, mailing address, LLC details (si Sunbiz aplica) 4. **Court status** — case docket, final judgment date, judgment amount 5. **Liens** — primary mortgage, secondary, IRS NFTL, HOA, code enforcement 6. **Title chain** — last 3 deeds con fechas + amounts 7. **Tax position** — assessed, market, taxes paid/owed, exemptions 8. **Comps** — 5-10 sales recientes en .5 mile, $/sqft, days on market 9. **Investment math** — bid suggestion, ARV estimate, repair budget ballpark 10. **Documents anexos** — lista de PDFs descargados en `properties/.../` con paths ### Generador ```python # pdf_generator.py def render_pre_screening_pdf(deal_id: int) -> Path: ... def render_full_report_pdf(deal_id: int) -> Path: ... ``` Salida: `properties/{state}/{county}/{type}/{id}/reports/report_{timestamp}.pdf` **Done cuando**: deal 349 (Broward) genera PDF de 10+ paginas con secciones 1-5 reales. --- ## Phase 3.5.D — DueDiligenceAgent (synthesis layer, ~1 semana) Hoy el `LienPositionAnalyzer` solo mira plaintiff. Para el reporte completo necesitamos un AGENTE que sintetice TODOS los outputs de los fetchers en un narrative. ### Diseno ```python # dd_agent.py def run_dd_agent(deal_id: int) -> dict: """ Llama a Ollama (modelo Coordinator: qwen2.5:32b) con un prompt que recibe: - Court records output - All liens (mortgage, IRS, HOA, code) - PA data - Comps - Title chain Y devuelve: - executive_summary (3-4 oraciones) - top_risks (lista de 3-5) - investment_thesis (1 paragrafo) - bid_suggestion (rango $) - confidence_score (1-10) """ ``` ### Modelfile `modelfiles/DueDiligenceCoordinator.modelfile` — base qwen2.5:32b (19GB, mas reasoning power). System prompt: "Eres un senior underwriter. Recibes data publica + extraida. Tu trabajo es escribir el executive summary y los risks que un investor experimentado escribiria." **Done cuando**: deal con foreclosure + IRS NFTL detectado produce summary que MENCIONA el IRS lien como top risk. --- ## Phase 3.5.E — Wave 1.5A v1.1 (Duval Acclaim Land Records) **Contexto**: Duval Clerk tiene 2 sistemas: - CCIS (court cases) — ya scrapeamos - Acclaim Land Records (deeds + mortgages + lis pendens) — NO scrapeamos aun **Por que importa**: lis pendens son LEADING INDICATOR — case que aun no llego a final judgment pero pre-foreclosure. Vale oro para outreach temprano. ### Tareas - [ ] `scrapers/duval_acclaim.py` — Playwright scraper de Acclaim - [ ] Filtros: por document_type=lis_pendens, party_name, date_range - [ ] Output: deals con `deal_type=pre_foreclosure` (nuevo tipo) + 90 dias de runway - [ ] Registro en `scrapers/registry.py` como `duval_acclaim` - [ ] UI: filtro nuevo en Search por deal_type=pre_foreclosure **Done cuando**: Duval Acclaim devuelve >50 lis pendens del mes, todos con owner + property identificable. --- ## Orden de ejecucion sugerido ``` Hoy: Phase 3.5.A close (UI Reporte completo functional aunque sea minimal) Semana 1-2: Phase 3.5.B fetchers (los 5 county FL priority) Semana 3: Phase 3.5.C PDF generator Semana 4: Phase 3.5.D DD agent + integracion con PDF Semana 5: Phase 3.5.E Duval Acclaim Backlog (parallel): IDEAS_BACKLOG items P1/P2 segun bandwidth ``` --- ## Decisiones tecnicas que ya fueron tomadas (NO revisitar) - **case_number != external_id** (Zillow zpid va a external_id). Migracion completada. - **realauction.com es multi-state multi-domain** (realforeclose / realtaxdeed / treasurersdeedsale). Engine soporta `domain` field. - **PA primero, Zillow fallback** para fotos (PA es gratis Playwright, Zillow es 1 cred). - **1 foto por deal** (no 5) — cost-conscious. - **Pre-screening MANDATORY court_records** para distressed deals (foreclosure/auction/tax_deed/reo). - **OWNER_VERIFIED cuenta como success** en court_records (no es INSUFFICIENT_DATA). - **LienPositionAnalyzer** soporta verdict INSUFFICIENT_DATA + PLAYERS section. - **CSS**: 0 emojis user-facing, paleta corporate, Stop button NO se oculta. - **Folder structure** `properties/{STATE}/{County}/{deal_type}/{identifier}/{category}/` definida en `properties_store.py`. --- ## Como usar este plan 1. Empezar sesion → leer este archivo + `IDEAS_BACKLOG.md` 2. Si hay tarea en curso de Phase 3.5 → continuar en ese checkbox 3. Si Phase 3.5 actual completada → mover al siguiente bloque 4. Marcar [x] cuando done + agregar commit hash al lado 5. Si discoveris algo nuevo que NO bloquea → va a `IDEAS_BACKLOG.md` --- ## Riesgos identificados - **Firecrawl budget (1000 cred/mes)**: con full report a 2-5 cred y 250 deals/mes = 500-1250 cred. Hay que monitorear y posiblemente bumpear plan. - **Multi-county fetchers son trabajo lineal** — cada county tiene su portal con su captcha / su SPA. Estimado 2-4h por county-fetcher pair. - **PACER cuesta plata** — si lo integramos, pasa de margen variable. Considerar omitirlo del basic full report y ofrecerlo como add-on $50. - **PDF generation puede ser lento** (WeasyPrint con 20+ paginas y muchas imagenes) — preparar para 30-60s render time. - **Agent (qwen2.5:32b) requiere 19GB RAM/VRAM** — confirmar que la maquina del cliente lo corre.