Dr. Vinay Kumar Yadav.

PropTech · B2B2C

Live

ConfirmHai

Real-time rental availability confidence for student housing

role: AI Product Architect & Technical Lead — solo buildertimeline: 2025 – ongoingconfirmhai.com

The problem

Three specific, named pain points

  1. 01

    The "rented out" trap

    Listing sites show rooms that were rented weeks ago, because nobody re-verifies availability after the first post.

  2. 02

    Roommate roulette

    No structured way to check schedule, cleanliness, or budget compatibility before moving in with a stranger.

  3. 03

    Broker leakage

    Heavy upfront commissions and spam contact leakage before a tenant even sees a genuine, currently-available listing.

Architecture

FastAPI, async end to end, 37 routes in production

Routers → services → models is enforced as a contract, not a convention: shared files (models, schemas, config, main) are treated as contract changes that require wider review before touching them.

Client

tenant.html / owner.html

  • Single-file HTML frontends

API layer

FastAPI routers

  • 37 routes
  • async Python

Service layer

Business logic

  • ConfidenceEngine
  • PredictiveEngine
  • Auth / OTP service

Data layer

SQLAlchemy 2.0 (async)

  • Models + migrations

Database

PostgreSQL (Neon)

  • SQLite in dev
  • Deployed on Render

Product decision

The Availability Confidence Score

Why a live score, not a status toggle

Most listing platforms ask owners to manually flip an "available / unavailable" switch — and owners never do it once the room is filled, which is exactly how the "rented out" trap happens. A boolean field trusts the owner to act; it doesn't model how trust decays.

Instead, ConfirmHai scores availability from freshness and vacancy signals that decay automatically over time, and treats a single WhatsApp reply from the owner as a first-class signal that can move the score instantly. The trade-off accepted here is real: a scoring engine plus a WhatsApp integration is more to build and operate than a boolean field. But the boolean field is the entire reason competitors' listing data goes stale.

Signal

Freshness

  • Time since last confirmation

Signal

Vacancy activity

  • Interest / booking signals

Engine

ConfidenceEngine + PredictiveEngine

  • Blends signals into a live score

Output

0–100% confidence

  • Shown to every tenant

Override signal

Owner WhatsApp reply: "rent ho gaya"

  • ("it's rented")
forces

Result

Score → 0, status: Rented

  • Verified end-to-end

Integration

WhatsApp / Meta Cloud API

Owner onboarding and freshness nudges run over WhatsApp — verified with webhook signature checks and a rate-limited OTP flow.

Owner

WhatsApp message

webhook

Meta

Cloud API

Verify

Signature check

  • Rejects unsigned payloads

FastAPI

OTP issue / verify

  • bcrypt-hashed
  • TTL + attempt-capped

Session

JWT issued

The same channel also drives the freshness-nudge loop: a stale listing triggers an automatic owner nudge; the reply refreshes (or zeroes) the confidence score. An "Invisible Listing" flow parses an owner's Hinglish WhatsApp caption directly into a live property listing.

Security

Zero-trust audit remediation

Every row below was verified against a specific threat, not shipped speculatively.

ControlThreat mitigatedImplementationStatus
JWT denylistStolen or leaked token reused after logoutRevoked tokens tracked server-side and checked on every authenticated requestEnforced
bcrypt hashingCredential or OTP database leakPasswords and OTPs bcrypt-hashed before storage — never stored in plaintextEnforced
IDOR / authz guardsCross-account access to another user's dataExplicit ownership checks on every resource route, verified in a zero-trust auditFixed
OTP rate limitingBrute-force OTP guessing5 attempts per 30 minutes, then lockedCapped
PII maskingContact leakage before a tenant paysOwner and tenant phone numbers stay masked until a paid unlock clearsEnforced
Stored XSS remediationMalicious script injected via listing contentInput sanitized and output-encoded; found and fixed during a zero-trust security auditFixed
Money / PII audit loggingUndetected fraud or data misuseEvery payment event and PII access is written to an audit logEnforced
Prod fail-fast configSilent misconfiguration reaching productionApp refuses to boot in production if dev-only settings or secrets are detectedEnforced
Webhook signature verificationSpoofed WhatsApp/Meta webhook payloadsEvery inbound webhook is signature-checked before it's processedEnforced

Monetization

Pay-to-unlock, with idempotency

The trade-off that actually mattered

ConfirmHai gates owner/roommate contact details behind a paid unlock — phone numbers stay masked until payment clears. The interesting risk here isn't pricing, it's idempotency: a payment callback can fire twice — webhook retries, a double-tap, a flaky network retry — and if that duplicate isn't caught, one real payment unlocks two different contacts for free.

Every unlock is tied to a payment_ref that's checked for prior use before access is granted — anti-replay by construction, not by trusting the client.

Engineering discipline

Anti-spiral-error scoping: the FEATURE_MAP

AI-directed engineering fails in a specific way: a change scoped to one feature quietly breaks an unrelated one because it touched a shared file without understanding the blast radius. The rule: check the map, touch only that feature's files. Changes to shared files (models, schemas, config, main) are flagged as contract changes.

Illustrative FEATURE_MAP structure

FeatureFilesEndpointsTables
Confidence scoreservices/confidence_engine.pyPOST /listings/{id}/refresh-scorelistings, confidence_signals
Owner OTP authrouters/owners.py, services/otp_service.pyPOST /owners/register, /verify-otpowners
Paid unlockrouters/unlock.py, services/payment_service.pyPOST /unlock/{listing_id}unlocks, payments

Testing strategy

~24 automated pytest suites, kept green per change

Tests must pass before a commit lands; a smoke test on /health plus the affected endpoints runs before every merge.

Suite categoryWhat it verifiesWhy it exists
authRegistration, OTP issuance/verification, JWT issuance and expiryPrevents silent regressions in login flows as AI-directed changes touch shared auth code
authz / IDORDeliberate cross-account access attempts against every resource routeAuthorization bugs rarely show up in happy-path testing — they show up when you try to access someone else's data on purpose
confidence engineScore computation across freshness/vacancy signal combinations, WhatsApp reply overrideThe scoring engine is the product's moat — a silent regression here is a trust regression for real users
rate limitingOTP attempt and TTL enforcement under repeated requestsConfirms brute-force protection actually triggers at runtime, not just that a config value exists
security headersRequired response headers present on every routeSecurity headers regress silently when middleware order or route registration changes

Status

Live at confirmhai.com, in front of early real users pre-marketing.

See this system broken down by category: Architecture · API Design · Security · Testing