feat: AR-House initial commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user