feat: AR-House initial commit

This commit is contained in:
2026-07-03 12:24:58 -04:00
commit 047c05287a
216 changed files with 127552 additions and 0 deletions
+247
View File
@@ -0,0 +1,247 @@
# 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/<topic>.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.