Field Property Partners

Stack

A transparent technical breakdown of how Field Property Partners is built.

Frontend

Next.js 16App Router, server components for SSR memo rendering
React 19Memo template + interactive analyzer page
TypeScriptStrict mode across all client + server code
Tailwind CSS 4Design tokens, dark theme palette
RechartsSensitivity table heatmaps
PlaywrightPDF capture of the live React memo

Backend

FastAPIPython 3.11, async throughout
PostgreSQL 16DigitalOcean managed instance
asyncpgDirect async driver — no SQLAlchemy layer
PydanticValidation on every API boundary
httpxAsync client for every external API
APSchedulerMacro snapshot cron (FRED daily refresh)

Data Providers

ATTOM DataProperty metadata, sales comps, tax records
RentCastRent AVMs + value AVMs (Foundation tier)
HouseCanaryResidential AVMs with forward forecasts (Teams tier)
FREDTreasury yield curve + SOFR
Anthropic Claude Sonnet 4.5Reconciliation prose + listing-facts extraction
CoStarStub class — ready for enterprise integration

Infrastructure

DigitalOcean DropletUbuntu 22.04, 4GB RAM
Docker + Docker ComposeTwo services: fpp-api + fpp-web
CaddyReverse proxy + Let's Encrypt SSL
GitHubPrivate repo

Underwriting Engine

underwriting/multifamily.pyNOI/cap-rate, DCF with terminal value, European waterfall (70/30 LP/GP, 8% pref, 20% promote)
underwriting/sfr.pyMonthly + annual pro forma, BRRRR refi math, fix-and-flip cost basis, multi-scenario classifier
metrics_snapshot.pySingle source of truth — every metric on the memo reads from deal_metrics_snapshot
Internal consistency assertionsPre-PDF assertion that Page 1 numbers match Page 6 prose within 0.5%

Memo Generation

React-rendered componentsSame component tree drives /analyze and /api/pdf
Playwright PDF captureCaptures the live HTML to PDF
Anthropic prose validationRegex-extracts every $ and % from generated text, asserts against snapshot ±tolerance, retries up to 2× on mismatch
Snapshot-only fallbackIf all 3 LLM attempts contain hallucinated numbers, the prose falls back to a static template that quotes only canonical values

Calibration Data

Property tax rates120+ counties verified from county assessor records + 50-state median fallback
Insurance defaultsMarket-specific (FL/CA/TX coastal, fire zones, mountain west)
Rent control flags20+ jurisdictions with annual-cap overrides on rent_growth default
Closing costsState-tiered (NY mansion tax, NJ RTF, IL Cook, HI conveyance)
Multi-word cities200+ city names so 'San Francisco' / 'Las Vegas' / 'Saint Louis' parse correctly from URLs

Pipeline / Workflow

Status workflowNEW → REVIEWED → REACHED OUT → REPLIED → UNDER CONTRACT → PASSED / CLOSED
Inline editsStatus dropdown + notes textarea persist on blur with status_history trail
Listing URL ingestionZillow, Realtor.com, LoopNet, Crexi — 37+ URL variants covered
Race-condition guardSame-URL re-ingest within 5s returns existing deal_id
LLM listing-facts extractionPaste any listing's Property Facts section → structured JSON → underwriting

Validation

Pre-deploy E2E testsReal listing URLs run through production HTTPS endpoints
URL parser corpus33+ URL variants with PASS/FAIL per variant
Internal consistency strict mode30+ verification items on every phase release
No graceful 'PARTIAL'Strict-mode verification — any FAIL blocks the deploy