Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,36 @@ Or run `npx echo-start my-app` to choose interactively.

# Development

Fill out `packages/app/control/.env` and `packages/app/server/.env`. Then...
## Prerequisites

- Node.js 18+ (Node 20 recommended)
- pnpm 10+
- Docker + Docker Compose plugin (`docker compose`)

## First run

From repo root:

- `pnpm i`
- `pnpm dev`

What `pnpm dev` does automatically on first run:

- Creates `packages/app/control/.env` (from `.env.example`) if missing
- Generates a local `AUTH_SECRET` and local `DATABASE_URL` if they are empty
- Starts local Postgres via Docker Compose (`echo-control-postgres-v2` on `localhost:5469`)
- Runs Prisma generate + migrations for control
- Starts:
- Echo Control at `http://localhost:3000`
- Echo Server at `http://localhost:3069`

## Optional local config

- `packages/app/server/.env` is optional for booting locally.
- To test real provider calls, add provider keys in `packages/app/server/.env` (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, etc.).
- To test OAuth providers in control, set provider credentials in `packages/app/control/.env`.

## Troubleshooting

- If `pnpm dev` says Docker is missing, install Docker Desktop (or Docker Engine + Compose plugin).
- If Docker is installed but not running, start Docker and run `pnpm dev` again.
33 changes: 10 additions & 23 deletions packages/app/control/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,44 +46,31 @@ A comprehensive Next.js application for managing Echo applications, API keys, an
### Prerequisites

- Node.js 18+
- PostgreSQL database
- pnpm
- Docker + Docker Compose plugin (`docker compose`)

### Installation

1. **Clone and navigate to the project**:

```bash
cd echo-control
```

2. **Install dependencies**:
1. **Install dependencies (from repo root)**:

```bash
pnpm install
```

3. **Create .env file**:

```bash
# Generate .env file
pnpm local-setup
```

4. **Run database migrations**:
2. **Run local setup + dev server**:

```bash
npx prisma generate
npx prisma db push
pnpm dev
```

5. **Start the development server**:
`pnpm dev` now handles local bootstrap automatically:

```bash
pnpm run dev
```
- Creates `packages/app/control/.env` if it does not exist
- Generates local `AUTH_SECRET` + `DATABASE_URL` defaults if missing/empty
- Starts Postgres in Docker (`echo-control-postgres-v2`)
- Runs Prisma generate + migrations

6. **Open the application**:
3. **Open the application**:
Visit [http://localhost:3000](http://localhost:3000)

## Features Overview
Expand Down
2 changes: 1 addition & 1 deletion packages/app/control/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"predev": "docker compose -f docker-local-db.yml up -d && sleep 3 && prisma generate && prisma migrate deploy",
"predev": "pnpm run local-setup && ./scripts/predev.sh",
"dev": "next dev --turbopack",
"local-setup": "./scripts/setup.sh",
"prebuild": "prisma generate",
Expand Down
26 changes: 26 additions & 0 deletions packages/app/control/scripts/predev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

set -euo pipefail

if ! command -v docker &> /dev/null; then
echo "Error: Docker is required to run Echo locally."
echo "Install Docker Desktop (or Docker Engine + Compose plugin), then retry."
exit 1
fi

if ! docker compose version &> /dev/null; then
echo "Error: Docker Compose plugin is required."
echo "Make sure 'docker compose' is available, then retry."
exit 1
fi

if ! docker info &> /dev/null; then
echo "Error: Docker daemon is not running."
echo "Start Docker and run 'pnpm dev' again."
exit 1
fi

docker compose -f docker-local-db.yml up -d
sleep 3
pnpm exec prisma generate
pnpm exec prisma migrate deploy
63 changes: 51 additions & 12 deletions packages/app/control/scripts/setup.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,59 @@
#!/bin/bash

# Check if .env file exists and if AUTH_SECRET is already set
if [ -f .env ] && grep -q "^AUTH_SECRET=" .env; then
echo "AUTH_SECRET already exists in .env file. Skipping generation."
set -euo pipefail

ENV_FILE=".env"
DEFAULT_DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public"

if [ ! -f "$ENV_FILE" ]; then
if [ -f .env.example ]; then
cp .env.example "$ENV_FILE"
echo "Created .env from .env.example."
else
touch "$ENV_FILE"
echo "Created empty .env."
fi
fi

get_env_value() {
local key="$1"
local raw_value

raw_value="$(grep -E "^${key}=" "$ENV_FILE" | tail -n 1 | cut -d '=' -f2- || true)"
raw_value="${raw_value%\"}"
raw_value="${raw_value#\"}"
raw_value="${raw_value%\'}"
raw_value="${raw_value#\'}"

echo "$raw_value"
}

set_env_value() {
local key="$1"
local value="$2"

if grep -qE "^${key}=" "$ENV_FILE"; then
sed -i "s|^${key}=.*|${key}=\"${value}\"|" "$ENV_FILE"
else
printf '\n%s="%s"\n' "$key" "$value" >> "$ENV_FILE"
fi
}

auth_secret_value="$(get_env_value "AUTH_SECRET")"
if [ -z "$auth_secret_value" ]; then
generated_auth_secret="$(node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))")"
set_env_value "AUTH_SECRET" "$generated_auth_secret"
echo "Generated AUTH_SECRET."
else
echo "Generating AUTH_SECRET..."
AUTH_SECRET=$(node -e "console.log('AUTH_SECRET=' + require('crypto').randomBytes(32).toString('base64'))")
echo $AUTH_SECRET
echo $AUTH_SECRET >> .env
echo "AUTH_SECRET already set."
fi

# Check if DATABASE_URL is already set
if [ -f .env ] && grep -q "^DATABASE_URL=" .env; then
echo "DATABASE_URL already exists in .env file. Skipping."
database_url_value="$(get_env_value "DATABASE_URL")"
if [ -z "$database_url_value" ]; then
set_env_value "DATABASE_URL" "$DEFAULT_DATABASE_URL"
echo "Set DATABASE_URL to local default."
else
echo "DATABASE_URL='postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public'" >> .env
echo "DATABASE_URL already set."
fi

echo "Setup complete! You can now run 'pnpm dev' to start the development server."
echo "Local setup complete."
10 changes: 5 additions & 5 deletions packages/app/control/setup-db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ if [ ! -f .env ]; then
echo "📝 Creating .env file..."
cat > .env << 'EOF'
# Database - Docker PostgreSQL
DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control?schema=public"
DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public"

# Stripe (Mocked for now)
STRIPE_SECRET_KEY="mock_stripe_secret_key"
Expand All @@ -25,7 +25,7 @@ fi

# Start PostgreSQL container
echo "🐳 Starting PostgreSQL container..."
docker-compose -f docker-local-db.yml up -d postgres
docker compose -f docker-local-db.yml up -d postgres

# Wait for PostgreSQL to be ready
# No need for manual health check since docker-local-db.yml already has healthcheck configured
Expand All @@ -46,7 +46,7 @@ pnpm exec prisma db push
echo "🎉 Database setup complete!"
echo ""
echo "📊 You can now run:"
echo " npm run dev # Start the application"
echo " pnpm dev # Start the application"
echo " pnpm exec prisma studio # View the database"
echo " docker logs local-postgres # View database logs"
echo " docker stop local-postgres # Stop the database"
echo " docker logs echo-control-postgres-v2 # View database logs"
echo " docker stop echo-control-postgres-v2 # Stop the database"
2 changes: 1 addition & 1 deletion packages/app/server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ OPENROUTER_API_KEY=
# Database
# ----------

DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control?schema=public"
DATABASE_URL="postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public"


# ----------
Expand Down
31 changes: 15 additions & 16 deletions packages/app/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,35 @@

## Prerequisites

This server depends on the generated Prisma client from the `echo-control` project. Before running the server, you need to ensure the Prisma client is copied locally.
- Node.js 18+
- pnpm
- For full local stack: Docker + Docker Compose plugin (`docker compose`)

## Development

### First Time Setup
### Recommended (from repo root)

1. Make sure the `echo-control` project has generated its Prisma client:

```bash
cd ../control
pnpm run build # or whatever command generates the Prisma client
```
```bash
pnpm install
pnpm dev
```

2. Copy the generated Prisma client:
```bash
pnpm run copy-prisma
```
The root `pnpm dev` command starts both `echo-control` and `echo-server`.

### Running the Server

```bash
# Development mode (automatically copies Prisma client)
# In this package only:
pnpm run dev

# Production mode
# Build + start
pnpm run build
pnpm start
```

The `dev` and `start` scripts automatically run `copy-prisma` as a pre-hook, so you don't need to run it manually.
The server scripts automatically copy Prisma schema/client artifacts from `echo-control` before build/start.
If `DATABASE_URL` is not set, the server uses a local default:
`postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public`.

## Docker Considerations

Expand Down Expand Up @@ -78,4 +77,4 @@ CMD ["pnpm", "start"]

## Error Handling

If the generated Prisma client is not found, the server will throw a descriptive error message asking you to run `pnpm run copy-prisma`.
If the generated Prisma client artifacts are missing, run `pnpm run copy-prisma` and retry.
4 changes: 3 additions & 1 deletion packages/app/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ const upload = multer({
export const prisma = new PrismaClient({
datasources: {
db: {
url: env.DATABASE_URL ?? 'postgresql://localhost:5469/echo',
url:
env.DATABASE_URL ??
'postgresql://echo_user:echo_password@localhost:5469/echo_control_v2?schema=public',
},
},
log: ['warn', 'error'],
Expand Down