Stack
| Layer | Technology |
|---|---|
| Frontend | React 18 + TypeScript (Vite 5) — Cloudflare Pages |
| Backend API | Cloudflare Worker (TypeScript) — env: premierrealty |
| Database | Cloudflare D1 — realtor_db (ID: 788cf2ea-86f8-4b88-bf0a-06277168455e) |
| Auth | PBKDF2-SHA256 password hash in D1, HMAC-signed JWT (24hr expiry) |
| Mobile | Position:fixed sidebar drawer + hamburger (mobile-first) |
Database Tables
| Table | Key Columns |
|---|---|
| admin_users | id, name, email, password_hash |
| clients | id, name, email, phone, client_type (Buyer/Seller/Both), status, address, notes |
| listings | id, client_id, address, city, state, zip, property_type, list_price_cents, bedrooms, bathrooms, sqft, mls_number, description, status, listing_date |
| showings | id, client_id, listing_id, date, start_time, end_time, status (Scheduled/Completed/Cancelled/No Show), notes |
| invoices | id, invoice_number, client_id, amount_cents, description, status, issue_date, paid_date |
| invoice_items | id, invoice_id, description, quantity, unit_price_cents, total_cents |
| notes | id, entity_type, entity_id, content |
| settings | key, value — business_name, property_types, invoice_footer, invoice_next_number |
Public API Endpoints (No Auth)
| Route | Purpose |
|---|---|
| GET /api/config | Business name, property types for public site |
| GET /api/listings-public | All Active listings for public property search |
| POST /api/showings-public | Visitor-submitted showing request (no client_id required) |
File Structure
realtor-portal/
src/
App.tsx / api.ts / index.css / main.tsx
context/AppContext.tsx
components/
PublicSite.tsx ← Property listings + showing request form
AdminApp.tsx ← Mobile-first sidebar shell
admin/
Dashboard.tsx / ClientsView.tsx / ListingsView.tsx / ShowingsView.tsx
InvoicesView.tsx / CalendarView.tsx / ReportsView.tsx / SettingsView.tsx
worker/index.ts
migrations/0001_init.sql / 0002_settings_seed.sql (Premier Realty defaults)
wrangler.toml ← premierrealty env