Skip to content
marcioecomPublic

About

Echo is a WhatsApp-first, multi-tenant customer support platform with an AI-powered support agent and a shared inbox for human operators.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Echo

Echo is a tenant-aware, WhatsApp-first support platform. The monorepo contains:

  • apps/web: TanStack Start operator interface (Cloudflare Workers)
  • apps/api: Fastify API and future Better Auth host
  • apps/worker: background processing runtime
  • packages/domain: shared domain contracts and ULID generation
  • packages/db: Drizzle schema, migrations, and Postgres client
  • packages/config: shared server environment validation

Implemented today

This section tracks what is actually built and tested, not the product vision. See docs/architecture.md for the system diagram.

  • Authentication & organizations. Better Auth-backed sign-up, sign-in, invitations, and member management, covered by apps/api/src/modules/auth/auth.integration.test.ts.
  • WhatsApp channel provisioning. A CLI command (channel:provision:twilio) creates and encrypts per-organization Twilio subaccount credentials, verifies the WhatsApp Sender is ONLINE, and writes an immutable audit event. Covered by channel-connections.integration.test.ts.
  • Inbound WhatsApp ingestion. Twilio webhook signature verification, message normalization, and conversation threading, covered by twilio-webhook.test.ts and inbound-message.integration.test.ts. Inbound processing and outbound delivery are dispatched as BullMQ jobs (process-inbound-message, send-outbound-message) consumed by apps/worker.
  • Support inbox. Paginated conversation listing with cursor-based pagination, conversation detail, and operator replies, covered by support-inbox.integration.test.ts and create-operator-reply.test.ts. The web UI exposes this at /inbox and /inbox/$conversationId.
  • Knowledge base. Organization owners and admins can ingest text or supported files, edit document titles, and replace or delete documents at /settings/knowledge. The knowledge page has a separate Preview tab for testing a question through the Support Agent graph without sending a message or changing a conversation; it shows the graph's decision and any retrieved sources.
  • Operational health. Both the API and worker expose /health/live and /health/ready probes that fail closed when Postgres or Redis is unavailable, and only report sanitized dependency state.
  • CI. .github/workflows/ci.yml runs lint, typecheck, test, and build on every pull request and push to main.

The worker contains a Support Agent graph for inbound first-line responses. Its presence in the codebase does not establish that this version is deployed in production. Meta Embedded Signup is not built; channel provisioning remains an internal CLI operation. Echo has not been verified against real customer traffic.

Prerequisites

  • Node.js 20 or newer
  • pnpm 10.33.4
  • Docker with Compose

Local setup

pnpm install
cp apps/api/.env.example apps/api/.env
cp apps/worker/.env.example apps/worker/.env
pnpm infra:up
pnpm db:migrate
pnpm dev

To use the knowledge-base preview, set AI_GATEWAY_API_KEY and AI_CHAT_MODEL in apps/api/.env. The preview endpoint returns HTTP 503 when AI Gateway access is unavailable.

The local services use these addresses:

Service Address
Web http://localhost:3000
API http://localhost:3001
Worker health http://localhost:3002
Postgres localhost:5432
Redis localhost:6379

Trace agent runs in LangSmith

To trace inbound support-agent runs, set LANGSMITH_TRACING=true and LANGSMITH_API_KEY in apps/worker/.env. Tracing is off by default; LANGSMITH_PROJECT=echo in the example selects the project. Traces include the customer message, retrieved snippets, model call, and filterable organization, conversation, and message IDs.

To verify locally, start the worker with pnpm --filter @workspace/worker dev, send a text message through a configured WhatsApp connection, and inspect the support-agent run in LangSmith.

Evaluate the support agent

pnpm --filter @workspace/agent eval uploads golden set v1 and runs a LangSmith experiment against the current decide step. It needs AI_GATEWAY_API_KEY and LANGSMITH_API_KEY in apps/worker/.env. See packages/agent/src/evals/README.md for the rubric and how to add a case.

Verify connectivity

Both server runtimes fail during startup if Postgres or Redis is unavailable. Once pnpm dev is running, verify their probes:

curl --fail http://localhost:3001/health/live
curl --fail http://localhost:3001/health/ready
curl --fail http://localhost:3002/health/live
curl --fail http://localhost:3002/health/ready

Readiness returns HTTP 503 when either dependency is unavailable. Responses expose only sanitized dependency states.

Database workflow

The Better Auth schema is generated from the API-owned auth configuration. Domain tables are maintained separately in packages/db/src/schema/support.ts.

pnpm auth:schema:generate
pnpm db:generate
pnpm db:migrate
pnpm db:studio

Commit generated SQL migrations. Do not use drizzle-kit push as the normal schema workflow. pnpm db:migrate lists the migrations it applies, or reports that nothing is pending. Database commands load apps/api/.env, the app-local environment owned by the API. The same commands can be run from packages/db as pnpm db:generate, pnpm db:migrate, and pnpm db:studio.

Provision a WhatsApp Channel Connection

The initial onboarding flow uses one Twilio subaccount per Organization. Provisioning is an internal operation until Meta Embedded Signup replaces it.

Apply migrations first, then run the provisioning command. It prompts for the subaccount Auth Token using masked terminal input, so the token is not stored in shell history:

pnpm --filter @workspace/api channel:provision:twilio -- \
  --organization-id 01K1EDN69NFBWCG42B2H99V2C1 \
  --name "WhatsApp Support" \
  --address +5511999999999 \
  --account-sid AC00000000000000000000000000000000

When stdin is not an interactive terminal, the command still accepts the Auth Token from stdin for controlled automation. Never pass it as a command-line argument.

The command verifies that the subaccount exposes an ONLINE WhatsApp Sender for the address, encrypts the Auth Token, activates the provider-neutral Channel Connection, and writes an immutable Audit Event. Rerunning it updates the existing connection rather than creating a duplicate.

PUBLIC_API_URL must be the externally visible API origin used in Twilio's webhook configuration. Twilio signs the exact callback URL, so a proxy-only internal origin cannot be used for signature validation.

Generate a deployment-specific credential encryption key with openssl rand -base64 32. Keep the key outside the database and increment CHANNEL_CREDENTIALS_KEY_VERSION when deliberately rotating it.

Quality checks

pnpm lint
pnpm typecheck
pnpm test
pnpm test:integration
pnpm build

Integration tests start isolated Postgres and Redis containers and do not modify the local development database.

Stop local infrastructure

pnpm infra:down

About

Echo is a WhatsApp-first, multi-tenant customer support platform with an AI-powered support agent and a shared inbox for human operators.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

Used by

Contributors

Languages