← Services
Platform Documentation

The Ambasdr Platform

Ambasdr lets anyone create a personal page with an AI-powered voice and chat agent that represents them. This documentation covers the platform architecture, local development workflow, API surface, agent prompt design, DigitalOcean deployment + CI/CD, and the running production-readiness list.

01

What Ambasdr Is

Ambasdr is a platform where users create a public-facing personal page tied to an AI agent. Visitors interact with the agent through voice (WebRTC via LiveKit) or text chat (SSE streaming). The agent is personalized through the user's profile, uploaded documents, social links, and custom instructions.

The platform handles the full lifecycle: user signup via Auth0, a six-step onboarding flow that collects profile data and documents, a dashboard for ongoing management, and a public page that visitors access via a unique slug.

Backend

Go API Server

Gin-based REST API with OpenAPI code generation, PostgreSQL storage, S3-compatible file uploads, and SSE chat streaming powered by an OpenAI-compatible LLM.

Frontend

React SPA

Vite + React 19 with Auth0 authentication, Tailwind CSS styling, LiveKit WebRTC voice, and Storybook component documentation.

Voice Agent

Python LiveKit Agent

Deepgram STT, ElevenLabs TTS, and Silero VAD compose a real-time voice pipeline that bridges LiveKit rooms to the backend chat API.

02

Monorepo Structure

The repository is a monorepo with four primary workspaces and shared infrastructure configuration.

Directory Purpose
backend/ Go API server and worker. Handles all HTTP endpoints, business logic, database access, file storage, and LLM integration. Uses Gin, goqu, pgx, and the Eino LLM framework.
frontend/ React 19 SPA built with Vite. Auth0-protected dashboard, six-step onboarding, public page with voice/chat modes. Storybook for component docs.
livekit-agent/ Python voice agent using LiveKit Agents SDK. Pulls the composed system prompt from the backend, drives Deepgram STT and ElevenLabs TTS directly, and exposes a search_knowledge function tool back to the LLM. Designed to be deployed to LiveKit Cloud in non-dev environments.
knowledge-graph/ Python FastAPI service wrapping Graphiti. Builds and queries a per-user knowledge graph backed by Neo4j (graph), PostgreSQL (ingestion tracking / DLQ / audit), and MinIO (document storage). The backend talks to it over HTTP via KG_SERVICE_URL.
mobile/ Expo + React Native app, including an on-device Storybook target. Early-stage; not part of the LiveKit / backend deployment loop.
auth0/ Auth0 Post-Login Action (serverless JS). Provisions users in the backend on first login and caches the Ambasdr user ID in Auth0 app_metadata.
docker-compose.yml Local infrastructure containers: PostgreSQL 16, Redis 7, Neo4j 5, MinIO (S3-compatible), OpenSearch 2, and the knowledge-graph FastAPI service.
docs/ Design documents: authentication flow, architecture overview, LiveKit integration plan, and decision records.
diorama-docs/ This documentation site. Docusaurus wrapper for browsing platform docs locally.
03

Local Development

Getting the full platform running locally requires Docker, Go, Node.js, and optionally Python 3.11+ for the voice agent. A tunneling service (ngrok) is needed for Auth0 integration.

Start infrastructure

Run make dev-up to start PostgreSQL, Redis, Neo4j, MinIO, and OpenSearch via Docker Compose. Health checks ensure all services are ready before proceeding.

Run database migrations

Run make migrate-up to apply all schema migrations (15 as of this writing — users + onboarding, pages + documents + slug history, agent configs with focus / generated instructions / generation status, chat threads with channel + visitor role, KG ingestion tracking, page highlights, JSONB greeting messages, and billing fields).

Configure environment variables

Copy backend/.env.example to backend/.env and fill in: Auth0 domain and M2M secret, LLM API key, LiveKit credentials, Stripe (secret key + webhook secret + price ID), shared agent API key, and (if running the Graphiti sidecar) KG_SERVICE_URL. Frontend env vars are in frontend/.env — Auth0 SPA client ID, API URL, Stripe Payment Link, and Gemini key for the chat preview. Knowledge-graph env vars live in knowledge-graph/.env — Anthropic + OpenAI keys, plus the Neo4j / Postgres / MinIO connection settings.

Set up ngrok and start the tunnel

Each engineer needs their own ngrok account and domain. The free tier provides a single static domain. Sign up at ngrok.com, retrieve your domain, then update the NGROK_PROVISION_DOMAIN in the Makefile (or create your own tunnel target). You must also update VITE_AUTH0_AUDIENCE in frontend/.env with your tunnel URL and register it as a callback URL in Auth0. Then run make ngrok-run to expose the local API. This is required for Auth0's Post-Login Action to reach the provisioning endpoint.

Start the backend API

Run make run-api to start the Go API server on port 9080. It connects to all local infrastructure services automatically.

Start the frontend

Run make frontend-install (first time), then make frontend-dev to start the Vite dev server on port 3003.

Start the knowledge graph service (recommended)

Run make kg-install (first time), then make kg-up to start the Graphiti FastAPI sidecar on port 8050 alongside its infra (Neo4j + KG Postgres DB + MinIO). The backend uses it to bake live KG context into generated agent prompts and to back the agent's search_knowledge function tool.

Start the voice agent (optional)

Run make agent-install (first time), then make agent-run to register the Python agent with LiveKit for voice sessions. Locally the agent registers against the LiveKit dev key; in staging/prod it's deployed to LiveKit Cloud via the lk CLI — see the deployment runbook.

Auth0 Tunneling Requirement

Auth0's Post-Login Action runs in Auth0's cloud and must call the backend's POST /internal/users/provision endpoint. Without a public tunnel, authentication will succeed at Auth0 but the user won't be provisioned in the local database, causing 401 errors on all API calls.

The domain ambasdr-api.ngrok.app in the Makefile is specific to the project owner's ngrok account. Each engineer must create their own free ngrok account at ngrok.com, claim their static domain, and update three things: (1) the NGROK_PROVISION_DOMAIN variable in the Makefile, (2) VITE_AUTH0_AUDIENCE in frontend/.env with their tunnel URL, and (3) register the tunnel URL as an allowed callback in Auth0 using the Auth0 CLI.

04

Auth0 Integration (Google Supported)

Authentication uses Auth0 with Google as the only active social connection. The frontend UI shows Facebook and LinkedIn buttons, but those connections are not yet enabled in Auth0. The platform uses a Post-Login Action to provision users in the Ambasdr database on their first login.

First Login

Provisioning Flow

Auth0 calls POST /internal/users/provision with the user's Auth0 subject, email, and avatar. The backend creates the user and returns a UUID. Auth0 caches this in app_metadata.ambasdr_user_id and injects it as a custom claim in the access token.

Returning Login

Cached Fast Path

On subsequent logins, the cached ambasdr_user_id is read from app_metadata and injected into the token without calling the backend. This means returning users don't depend on backend availability during login.

Auth0 CLI Setup

Engineers should install the Auth0 CLI (auth0) and authenticate with auth0 login. This is needed for the make dev-reset and make dev-reset-user commands, which clear Auth0 app_metadata when resetting local state. The CLI is also used to manage callback URLs and Action secrets.

05

Resetting State

When you need a clean slate, the database and Auth0 caches must be reset together. Resetting only the database leaves stale user IDs in Auth0's app_metadata, causing 404 errors on login.

Command What it does
make db-reset Drops all tables and re-runs migrations. Database only. Use this if you just need to clear data without touching Auth0.
make dev-reset Runs db-reset, then clears app_metadata for all dev users via the Auth0 CLI. After this, log out and log back in to trigger a fresh provisioning call.
make dev-reset-user EMAIL=user@example.com Clears app_metadata for a single Auth0 user. Useful when only one engineer needs to restart the onboarding flow without affecting others.
After Any Reset

Always log out of the frontend and log back in after a reset. The next login triggers the Auth0 Post-Login Action, which calls the provisioning endpoint and creates a fresh user in the database with a new UUID. Without re-logging, the frontend's cached access token still contains the old (now-deleted) user ID.

06

Makefile Reference

All local development tasks are managed through a root-level Makefile. Here are the key targets grouped by area.

Target Description
dev-up / dev-down Start / stop Docker Compose services (PostgreSQL, Redis, Neo4j, MinIO, OpenSearch).
migrate-up / migrate-down Run or rollback database migrations using golang-migrate.
run-api Start the Go API server (go run cmd/api/main.go).
run-worker Start the background worker for async tasks.
build Compile both API and worker binaries to backend/bin/.
test-unit Run Go unit tests (-tags unit).
test-integration Run Go integration tests (-tags integration) against real containers (testcontainers).
test-e2e Run Go end-to-end tests (-tags e2e).
frontend-dev Start the Vite dev server with hot module replacement.
run-storybook Start Storybook on port 6006 for component development.
storybook-publish Publish Storybook to Chromatic using the token from frontend/.env.
ngrok-run / ngrok-stop Start / stop the ngrok tunnel for Auth0 integration.
agent-install Create Python venv and install LiveKit agent dependencies.
agent-run Start the Python voice agent.
kg-install Create Python venv and install Graphiti / knowledge-graph dependencies.
kg-up / kg-down Start / stop the Graphiti FastAPI sidecar (port 8050) and its required infra containers.
kg-reset Wipe the KG stores only — clears Neo4j, recreates the KG Postgres DB, empties the MinIO bucket.
db-reset-full Run db-reset plus kg-reset so the app DB and KG stores reset together.
check-services Verify every local dev process is up (containers, both Postgres DBs, backend API, Graphiti, frontend, voice agent, ngrok tunnel).
docs-dev / docs-build Sync HTML and start (or build) the Docusaurus docs server (this site).
07

Testing Strategy

Backend tests use testify suites with testcontainers for real PostgreSQL and MinIO instances. The database is never mocked. All tests run with build tags to separate unit, integration, and e2e concerns.

Unit

Isolated Logic

Tagged //go:build unit. Tests pure business logic without external dependencies. Run with make test-unit.

Integration

Handler + DB

Tagged //go:build integration. Spins up real PostgreSQL and MinIO via testcontainers. Tests the full handler chain: HTTP request through router, service logic, repository, and database. Run with make test-integration.

E2E

External Services

Tagged //go:build e2e. Tests that require live external services (Auth0, LLM APIs). Run with make test-e2e.

Integration tests cover every HTTP endpoint with real request/response cycles. The test fixture (backend/tests/integration/fixtures.go) provides a shared TestFixture struct with repository, storage, and database clients. JWT helpers generate test tokens for authenticated requests.