CoolFace
Apppublic

kmkarakaya/emlakAsistani

sourceHugging Faceupdated 6mo agoView on Hugging Face
1likes
App README

EmlakAsistan

EmlakAsistan is a real-time voice sales assistant for real estate workflows. It uses Gemini Live for audio conversation, keeps UI logic separated from business logic, and stores application data through backend APIs.

Tech Stack

  • —Frontend: React + Vite + TypeScript + Tailwind
  • —Backend: Express + TypeScript
  • —AI: @google/genai (Gemini Live)
  • —Storage: JSON file persistence under data/

Architecture (Refactor v2)

The codebase is split to keep UI portable and maintainable:

  • —shared/: framework-agnostic domain types and pricing constants
  • —server/: backend entry, routes, storage service
  • —src/services/: frontend business/services layer (no React dependency)
  • —src/hooks/: React binding layer for services
  • —src/components/: render-focused UI components

Current key folders:

text
shared/
   types.ts
   pricing.ts

server/
   index.ts
   routes/
      config.ts
      customers.ts
      projects.ts
      appointments.ts
   services/
      storage.ts

src/
   services/
   hooks/
   components/
   lib/
   App.tsx

Reliability Guarantees

Voice Session Shutdown (Graceful)

When an operator ends a call, the app performs a graceful shutdown instead of immediately tearing down the session:

  • —Stop microphone capture first (no new user audio is sent).
  • —Wait for buffered model audio to drain (with silence + timeout guards).
  • —Close the Gemini Live session after drain.

This prevents the agent from being cut off mid-sentence in normal conditions and keeps close behavior deterministic.

Additional protections:

  • —Stale-run guards prevent callback races between old/new sessions.
  • —Close/error callbacks are suppressed during intentional shutdown.
  • —Session close is idempotent to avoid double-close side effects.

Appointment Capture and UI Consistency

Appointment recording uses a layered, fail-safe strategy:

  • —Primary path: Gemini function tool-call (recordAppointment).
  • —Fallback path: text confirmation detection when a tool-call is missing.
  • —Deduping: tool-call IDs and normalized fallback hashes avoid duplicate writes.
  • —Persistence retries: exponential backoff on appointment writes.

Error handling policy:

  • —Appointment save failures do not crash the active voice call.
  • —Tool responses report failure back to the model when persistence fails.

UI consistency policy:

  • —Appointments are inserted into client state after successful save.
  • —Appointment list is refreshed when the call view closes.

Prerequisites

  • —Node.js 18+
  • —npm

Environment Setup

  1. 1.Copy example env file:
bash
cp .env.example .env
  1. 1.Set your Gemini key in .env:
bash
GEMINI_API_KEY=your_key_here

Run Locally

bash
npm install
npm run dev

Server starts on http://localhost:3000.

Deploy to Hugging Face Spaces (Docker)

This repository now includes a production-ready Dockerfile and .dockerignore for Hugging Face Docker Spaces.

  1. 1.Create a Docker Space in Hugging Face (done).
  2. 2.Add secret in Space settings:
text
GEMINI_API_KEY=your_key_here
  1. 1.Push this repository to your Space remote:
bash
git remote add hf https://huggingface.co/spaces/<username>/<space-name>
git push hf main

The container listens on port 7860, which is the default for Docker Spaces.

Scripts

  • —npm run dev: run backend (serves Vite in middleware mode)
  • —npm run start: production mode server
  • —npm run build: production frontend build
  • —npm run preview: Vite preview
  • —npm run lint: frontend + server type checks
  • —npm run typecheck: frontend TS check
  • —npm run typecheck:server: server TS check
  • —npm run clean: remove dist/

API Endpoints

  • —GET /api/config
  • —GET /api/config/app
  • —PUT /api/config/app
  • —POST /api/config/migrate-local-storage
  • —GET /api/customers
  • —GET /api/projects
  • —POST /api/projects
  • —DELETE /api/projects/:projectId
  • —GET /api/appointments
  • —POST /api/appointments
  • —DELETE /api/appointments/:appointmentId

Unknown /api/* routes return JSON 404.

Data and Migration Notes

  • —Runtime data is persisted in data/app-storage.json.
  • —Legacy localStorage data is migrated once through backend API on app bootstrap.
  • —After migration, legacy keys are cleaned from browser storage.

Validation Checklist

bash
npm run lint
npm run build

Optional API smoke checks:

bash
curl http://localhost:3000/api/customers
curl http://localhost:3000/api/projects
curl http://localhost:3000/api/appointments