AI-powered value-add real estate financial modeling tool. Upload your Offering Memorandum and supporting documents. AI extracts the data, identifies what's missing, and builds a professionally formatted Excel model.
User uploads OM + supporting docs (PDF/DOCX/XLSX/TXT)
│
▼
POST /generate (action=analyze) → Lambda
│
├─ Extracts text from all documents
├─ LLM reads documents and identifies:
│ • Extracted fields (values found in docs, with confidence levels)
│ • Missing fields (not found, with importance ratings)
│ • Property summary (name, type, location)
└─ Returns structured AnalysisResult
│
▼
Interactive Q&A step (browser)
│
├─ Shows found fields with source attribution
├─ For each missing field, user decides:
│ • "I know it" → enters the value
│ • "⚡ AI assume" → LLM researches market data
│ • "Skip" → field is ignored
└─ "Build Model" button
│
▼
POST /generate (action=generate) → Lambda
│
├─ Calls LLM to research assumptions with web search
├─ Builds Excel with proper formatting:
│ • Blue font = user-provided / document-extracted values
│ • Black font = formula-driven calculations
│ • Green font = AI-researched assumptions
├─ Uploads .xlsx to S3
└─ Returns presigned download URL
│
▼
User downloads the Excel file
User can review, edit formulas, and adjust values
- Frontend: React 19 + TypeScript + Vite + Tailwind CSS
- Backend: Python 3.12 AWS Lambda (single
generatefunction with analyze/generate actions) - AI: Any OpenAI-compatible LLM (GPT-4o, Qwen, Claude, etc.)
- Storage: S3 for generated Excel files
- Infrastructure: Terraform (AWS — S3, Lambda, IAM)
- CI/CD: GitHub Actions
real-estate-model/
├── .github/workflows/
│ └── ci-cd.yml # GitHub Actions CI/CD pipeline
├── frontend/ # React SPA
│ ├── index.html
│ ├── package.json
│ ├── vite.config.ts
│ ├── tailwind.config.js
│ ├── postcss.config.js
│ ├── tsconfig.json
│ └── src/
│ ├── index.tsx # React entry point
│ ├── index.css # Tailwind + base styles
│ ├── App.tsx # Router
│ ├── vite-env.d.ts # Vite type declarations
│ ├── pages/
│ │ └── HomePage.tsx # 3-step flow: upload → analyze → review → build
│ ├── components/
│ │ ├── FileUpload.tsx # Drag-and-drop document upload with file preview
│ │ └── MissingFieldCard.tsx # Interactive card for Q&A on missing fields
│ └── services/
│ ├── types.ts # TypeScript type definitions
│ └── api.ts # Backend API client (analyze + generate)
├── backend/
│ └── generate/
│ ├── handler.py # Lambda: document analysis + AI research + Excel build
│ └── requirements.txt # Python dependencies (incl. PyPDF2, python-docx)
├── terraform/
│ ├── main.tf # AWS resources (S3, Lambda, IAM)
│ ├── variables.tf # Configurable variables + secrets
│ └── outputs.tf # Output values (Lambda URL, bucket names)
└── README.md
| Sheet | Content |
|---|---|
| Summary | Key metrics: total capitalization, entry/exit cap rates, cash flows |
| Assumptions | All line items with source attribution (Document Extract / User Input / AI Assumption / Formula) |
| Cash Flow | Annual projection over holding period, sectioned by Income/OpEx/NOI/Debt |
| Returns | Exit value, IRR, equity multiple, cash-on-cash return |
| Sources | All URLs consulted by the AI with hyperlinks |
cd frontend
npm install
npm run dev # starts at http://localhost:5173Create a .env file in frontend/:
VITE_GENERATE_URL=https://your-lambda-url.lambda-url.region.on.aws/
cd backend/generate
pip install -r requirements.txt-
First time: Run Terraform to create all AWS resources:
cd terraform terraform init terraform apply \ -var="frontend_bucket_name=re-model-frontend-<unique>" \ -var="storage_bucket_name=re-model-storage-<unique>" \ -var="llm_api_key=sk-..."
-
Ongoing: Push to
main— GitHub Actions deploys the Lambda and frontend automatically. -
Set the
VITE_GENERATE_URLin GitHub Secrets to the Lambda Function URL from Terraform outputs.
| Secret | Description |
|---|---|
AWS_ACCESS_KEY_ID |
AWS credentials for S3 + Lambda deploys |
AWS_SECRET_ACCESS_KEY |
AWS secret key |
VITE_GENERATE_URL |
Lambda Function URL from Terraform output |
TF_FRONTEND_BUCKET |
S3 bucket name for frontend hosting |
TF_STORAGE_BUCKET |
S3 bucket name for Excel file storage |
LLM_API_KEY |
Your LLM provider API key |