diff --git a/README.md b/README.md index 5a06ee746..aeea72ab5 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ Skip the hard choice between fronting API costs, high-friction BYOK flows, or bu Building AI apps forces you to pick your poison: -| Approach | Developer Cost | User Experience | Revenue Model | -|----------|---------------|-----------------|---------------| -| **BYOK** | None (but no revenue) | Complex key management | None | -| **Dev API Key** | Unpredictable burn rate | Simple | Need metering + billing | -| **Bill End Users** | Weeks building infra | Simple | Auth + Stripe + metering | +| Approach | Developer Cost | User Experience | Revenue Model | +| ------------------ | ----------------------- | ---------------------- | ------------------------ | +| **BYOK** | None (but no revenue) | Complex key management | None | +| **Dev API Key** | Unpredictable burn rate | Simple | Need metering + billing | +| **Bill End Users** | Weeks building infra | Simple | Auth + Stripe + metering | Echo eliminates all three problems. @@ -38,6 +38,7 @@ Echo eliminates all three problems. Replace your AI SDK imports with Echo. Users authenticate once, get a balance, and pay for their own usage. You set a markup and earn revenue automatically. **Before:** + ```typescript // Option 1: Front costs yourself import { openai } from '@ai-sdk/openai'; @@ -51,15 +52,16 @@ const response = await generateText({ ``` **After:** + ```typescript // Users pay, you earn markup, zero infrastructure import { useEchoModelProviders } from '@merit-systems/echo-react-sdk'; import { generateText } from 'ai'; const { openai } = useEchoModelProviders(); -const response = await generateText({ - model: openai('gpt-5'), - prompt: '...' +const response = await generateText({ + model: openai('gpt-5'), + prompt: '...', }); ``` @@ -116,7 +118,58 @@ Or run `npx echo-start my-app` to choose interactively. # Development -Fill out `packages/app/control/.env` and `packages/app/server/.env`. Then... +## Prerequisites + +Before running Echo locally, make sure you have: + +- **Node.js 18+** - [Download here](https://nodejs.org/) +- **pnpm** - Will be installed automatically by the setup script +- **Docker Desktop** - [Download here](https://www.docker.com/products/docker-desktop/) + +## Quick Setup + +```bash +git clone https://github.com/Merit-Systems/echo.git +cd echo +./setup.sh +pnpm dev +``` + +The setup script handles environment configuration and dependency installation. + +## Manual Setup + +1. Install dependencies: -- `pnpm i` -- `pnpm dev` + ```bash + npm install -g pnpm + pnpm install + ``` + +2. Start Docker Desktop + +3. Create `.env` files with required variables (see `packages/app/control/src/env.ts` for full list) + +4. Run `pnpm dev` + +## Services + +- Echo Control: http://localhost:3000 +- Echo Server: http://localhost:3070 +- PostgreSQL: localhost:5469 + +## Troubleshooting + +**Docker not running**: Start Docker Desktop + +**Port conflicts**: Change ports in `.env` files + +**Database issues**: Reset with `docker-compose -f packages/app/control/docker-local-db.yml down -v` + +## Development Commands + +```bash +pnpm dev # Start all services +pnpm test:unit # Run unit tests +pnpm format # Format all code +``` diff --git a/packages/app/control/README.md b/packages/app/control/README.md index c507343d7..02d009038 100644 --- a/packages/app/control/README.md +++ b/packages/app/control/README.md @@ -41,53 +41,21 @@ A comprehensive Next.js application for managing Echo applications, API keys, an - **Payments**: Stripe (mocked) - **TypeScript**: Full type safety -## Setup Instructions +## Quick Setup -### Prerequisites +From the root directory: -- Node.js 18+ -- PostgreSQL database -- pnpm - -### Installation - -1. **Clone and navigate to the project**: - - ```bash - cd echo-control - ``` - -2. **Install dependencies**: - - ```bash - pnpm install - ``` - -3. **Set up the database**: - - ```bash - # Copy the example environment file - cp .env.example .env - - # Update DATABASE_URL in .env with your PostgreSQL connection string - # Example: DATABASE_URL="postgresql://username:password@localhost:5469/echo_control" - ``` - -4. **Run database migrations**: - - ```bash - npx prisma generate - npx prisma db push - ``` - -5. **Start the development server**: +```bash +./setup.sh +pnpm dev +``` - ```bash - pnpm run dev - ``` +## Manual Setup -6. **Open the application**: - Visit [http://localhost:3000](http://localhost:3000) +1. Install dependencies: `pnpm install` +2. Start Docker Desktop +3. Create `.env` file with required variables (see `src/env.ts`) +4. Run `pnpm dev` ## Environment Variables @@ -107,30 +75,6 @@ NEXTAUTH_URL="http://localhost:3000" API_KEY_PREFIX="echo_" ``` -## Features Overview - -### Dashboard - -- View all Echo applications -- Quick balance overview -- Create new applications -- Generate payment links - -### App Details - -- Comprehensive usage analytics -- API key management -- Transaction history -- Model-specific usage breakdown -- Direct Stripe integration - -### Balance Management - -- Real-time balance calculation -- Payment history -- Admin controls for balance adjustments -- Stripe payment integration - ## Development ### Running Tests @@ -159,14 +103,4 @@ pnpm run build pnpm start ``` -## Contributing - -1. Fork the repository -2. Create a feature branch -3. Make your changes -4. Test thoroughly -5. Submit a pull request - -## License - -This project is licensed under the MIT License. +Visit [http://localhost:3000](http://localhost:3000) diff --git a/setup.sh b/setup.sh new file mode 100755 index 000000000..4371036e0 --- /dev/null +++ b/setup.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +echo "Setting up Echo for local development..." + +# Check for pnpm +if ! command -v pnpm &> /dev/null; then + echo "Installing pnpm..." + npm install -g pnpm + if [ $? -ne 0 ]; then + echo "Failed to install pnpm. Please install manually: npm install -g pnpm" + exit 1 + fi +fi + +# Check for Docker +if ! command -v docker &> /dev/null; then + echo "Docker not found. Please install Docker Desktop: https://www.docker.com/products/docker-desktop/" + exit 1 +fi + +if ! docker info &> /dev/null; then + echo "Docker not running. Please start Docker Desktop." + exit 1 +fi + +echo "Installing dependencies..." +pnpm install +if [ $? -ne 0 ]; then + echo "Failed to install dependencies." + exit 1 +fi + +echo "Setting up environment files..." + +# Control .env +if [ ! -f "packages/app/control/.env" ]; then + echo "Creating control .env file..." + touch packages/app/control/.env + + # Generate AUTH_SECRET and add required variables + AUTH_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))") + cat > packages/app/control/.env << EOF +# ---------- +# Application +# ---------- + +ECHO_CONTROL_APP_BASE_URL="http://localhost:3000" +API_KEY_PREFIX="echo_" + +# ---------- +# Database +# ---------- + +DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public" + +# ---------- +# AUTH +# ---------- + +AUTH_SECRET=$AUTH_SECRET +AUTH_GOOGLE_ID=placeholder_google_id +AUTH_GOOGLE_SECRET=placeholder_google_secret +AUTH_GITHUB_ID=placeholder_github_id +AUTH_GITHUB_SECRET=placeholder_github_secret +AUTH_RESEND_KEY=placeholder_resend_key +AUTH_RESEND_FROM_EMAIL=noreply@example.com + +# ---------- +# STRIPE +# ---------- + +STRIPE_SECRET_KEY=placeholder_stripe_secret_key +STRIPE_PUBLISHABLE_KEY=placeholder_stripe_publishable_key +STRIPE_WEBHOOK_SECRET=placeholder_stripe_webhook_secret +WEBHOOK_URL=http://localhost:3000/api/webhooks/stripe + +# ---------- +# OAuth Tokens +# ---------- + +OAUTH_JWT_SECRET=$AUTH_SECRET +OAUTH_REFRESH_TOKEN_EXPIRY_SECONDS=2592000 +OAUTH_ACCESS_TOKEN_EXPIRY_SECONDS=15 + +# ---------- +# Telemetry +# ---------- + +OTEL_EXPORTER_OTLP_ENDPOINT= +SIGNOZ_INGESTION_KEY= +SIGNOZ_SERVICE_NAME= + +# ---------- +# Blob Storage +# ---------- + +BLOB_READ_WRITE_TOKEN= +EOF +fi + +# Server .env +if [ ! -f "packages/app/server/.env" ]; then + echo "Creating server .env file..." + touch packages/app/server/.env + + AUTH_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))") + cat > packages/app/server/.env << EOF +PORT=3070 +DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public" +ECHO_CONTROL_BASE_URL=http://localhost:3000 +ECHO_API_KEY=placeholder_api_key +OAUTH_JWT_SECRET=$AUTH_SECRET +EOF +fi + +echo "" +echo "Setup complete. Run 'pnpm dev' to start development servers." +echo "" +echo "Services will be available at:" +echo "- Echo Control: http://localhost:3000" +echo "- Echo Server: http://localhost:3070" +echo "- PostgreSQL: localhost:5469"