VIFG Nonprofit Platform
Production platform and delivery stack supporting a nonprofit serving the visually impaired community.
Past client project
Through People’s Connection LLC, I developed Time2Move’s original real estate application, including customer tools, a shared inquiry-processing backend, and integrations with external services. The work connected property exploration and customer inquiries with structured follow-up workflows.
At a glance
Status
Past engagement · Original deployment inactive
Project
Time2Move
Role
Sole developer across the frontend, backend, and service integrations.
Scope
Real estate website, inquiry workflows and service integrations
I wrote the original frontend and backend application code. The implementation covered regional content, property-search embeds, mortgage and fee calculators, rate and review integrations, and a shared inquiry-processing backend.
One central decision was to bring six inquiry types under a common backend contract. That centralized validation and integration logic while preserving each request’s purpose and context. Each form used the same submission path, carrying its request type, contact details, and source information into backend processing. Contact normalization and deterministic intent rules prepared those submissions for the CRM adapter.
I also implemented API configuration and submission safeguards. I kept provider responsibilities explicit: IDX Broker supplied hosted property search and registration, while native inquiry processing remained separate. Operational documentation covered service responsibilities and recovery procedures.
Core stack: Next.js, React, TypeScript, Python, FastAPI, Redis.
How customer inquiries move through the application and its service integrations.
Six native forms share one contract, then a Next.js rewrite forwards POST /api/leads to FastAPI and its delivery adapters.
Application logic
Six native forms
Native inquiry journeys
Application logic
One submission contract
Intent, consent, attribution
Application logic
Next.js rewrite
POST /api/leads · Forward to backend
Application logic
FastAPI service
Pydantic validation · Contact normalization · Deterministic intent rules
External provider
Follow Up Boss
Event delivery adapter
Notifications / backup
FastAPI service connects to Resend
Conditional notification · or backup attempt
Resend can run as an optional background notification after primary acceptance, or as a synchronous backup attempt when primary delivery is not accepted. This is not a durable queue or guaranteed delivery.
My contribution
I implemented the shared form contract, backend validation and contact preparation, deterministic intent rules, and provider adapters.
Architecture reconstructed from project source.
From provider ingestion to reusable records and a rebuildable serving cache.
Separating provider ingestion, record identity, and presentation made the review data reusable and the serving cache rebuildable.
External provider
Google provider adapters
Business Profile / Places
Application logic
Normalize and deduplicate
Stable record identity · Consistent review fields
Stored data
Canonical Redis records and indexes
Published + featured IDs · Versioned sync state
Stored data
Versioned public serving cache
Public response + stats
Application logic
Reviews API and carousel
Read the public cache
Migrate snapshots
Legacy snapshots connects to Canonical Redis records and indexes
Migrate into the · canonical model
Rebuild without provider fetch
Canonical Redis records and indexes connects to Versioned public serving cache
Refresh is request-driven, with authenticated manual sync and rebuild paths. The serving cache can be rebuilt from canonical records without fetching the provider again.
Later in development, I used ChatGPT and Codex to clarify integration questions and refine the implementation.
The broader AI plans included:
These capabilities remained unfinished when the engagement ended.
A proposed extension to explicit routing rules, with local checks and a human-review gate.
A new educational example, not a feature completed in Time2Move. The examples below are precomputed; no model or CRM requests are made.
Predefined form choices can keep their explicit routing rules. A proposed LLM could help interpret free-text requests, while schema checks, review, and deterministic business logic control what gets accepted. The historical backend uses deterministic taxonomy rules, not an LLM classifier.
I want to sell my house and speak with someone about the next steps.
Precomputed for teaching; not actual model output.
{
"intent": "seller",
"summary": "Interested in selling and requesting guidance.",
"evidence": [
"sell my house",
"speak with someone"
],
"needs_review": true
}Outcome: Hold for human review. Only an approved interpretation could reach existing deterministic routing; this example makes no routing or delivery request.
Finding a source phrase does not prove the interpretation is correct. Schema validity and factual correctness are separate questions.
The application requires human review even when needs_review is false. Unknown or ambiguous intent calls for clarification. Only a reviewed interpretation could be considered by the existing deterministic routing rules.
Consent, contact identity, source attribution, and explicit user selections remain outside model control. Suggestions are never merged into those trusted fields.
The proposed schema accepts only intent, summary, evidence, and needs_review. Intent is buyer, seller, consultation, or unknown. Summary is 1–240 characters; evidence contains 0–3 exact source phrases of 1–160 characters each; needs_review is boolean. Unknown fields and wrong types are rejected.
{
"type": "object",
"additionalProperties": false,
"required": [
"intent",
"summary",
"evidence",
"needs_review"
],
"properties": {
"intent": {
"type": "string",
"enum": [
"buyer",
"seller",
"consultation",
"unknown"
]
},
"summary": {
"type": "string",
"minLength": 1,
"maxLength": 240,
"pattern": "\\S"
},
"evidence": {
"type": "array",
"minItems": 0,
"maxItems": 3,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 160,
"pattern": "\\S"
}
},
"needs_review": {
"type": "boolean"
}
}
}Before using a model, compare it against labeled examples and the existing rule baseline. Inspect per-intent precision and recall, appropriate abstention, and unsupported details. These illustrative proposals provide no evidence of model accuracy.
Further reading: Pydantic strict validationThe engagement ended before the wider roadmap and planned validation were complete. The original Time2Move deployment is now inactive.
The practical delivery lesson was to define a useful first release, identify integration dependencies early, and give validation and later AI enhancements explicit milestones.
More portfolio context.
Production platform and delivery stack supporting a nonprofit serving the visually impaired community.
Pilot platform that automates inventory alerts, buyer matching, and seller workflows for wholesale vehicle activity.