npm package: @kelpi/ad-gen
Description: CLI + service for Kelpi ad creative rendering — designed for Hermes agent use
Latest version: 0.1.0

# Creative Editor Service

A stateless session-based editor that renders HTML/CSS ad creatives into preview images. An external agent writes the HTML; this service stores sessions, renders previews via Playwright, and manages iteration history.

## Architecture

```
                  ┌──────────────┐
  Agent/Client ──>│  Fastify API │──> PostgreSQL
                  └──────┬───────┘       
                         │               
                   ┌─────┴─────┐
                   │ Playwright │
                   │ (renders)  │
                   └─────┬─────┘
                         │
                   ┌─────┴─────┐
                   │ S3 Storage│
                   └───────────┘
```

| Component | Role |
|-----------|------|
| **Fastify API** | Accepts HTML submissions, manages sessions, serves preview URLs |
| **Playwright** | Renders HTML to PNG screenshots at exact ad dimensions |
| **PostgreSQL** | Stores sessions, iterations, feedback, and asset metadata |
| **S3-compatible storage** | Stores rendered preview images and uploaded assets |

## Prerequisites

- Node.js >= 22
- PostgreSQL 15+
- S3-compatible storage (optional — uses local filesystem in dev)
- Playwright Chromium browser (`npx playwright install chromium`)

## Local Development

```bash
# 1. Install dependencies
npm install

# 2. Install Playwright browser
npx playwright install chromium

# 3. Configure environment
cp .env.example .env
# Edit .env with your local Postgres connection

# 4. Run database migrations
npm run migrate

# 5. Start the API server
npm run dev
```

The API listens on `http://localhost:3000` by default.

## Scripts

| Script | Command | Description |
|--------|---------|-------------|
| `npm run dev` | `tsx src/api.ts` | Start API with hot reload |
| `npm run build` | `tsc` | Compile TypeScript to `dist/` |
| `npm start` | `node dist/api.js` | Run compiled API (production) |
| `npm test` | `vitest run` | Run test suite |
| `npm run migrate` | `tsx src/db/migrate.ts` | Apply database migrations |

## API Reference

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/health` | Health check |
| `POST` | `/v1/sessions` | Create a new session (format + brief) |
| `GET` | `/v1/sessions/:id` | Get session state (session, assets, latest iteration, feedback) |
| `GET` | `/v1/sessions/:id/iterations` | List all iterations |
| `POST` | `/v1/sessions/:id/iterations` | **Submit HTML → render → save → return preview URL** |
| `POST` | `/v1/sessions/:id/feedback` | Store feedback text for the agent to read |
| `POST` | `/v1/sessions/:id/assets` | Upload an asset (multipart file) |

### Key endpoint: `POST /v1/sessions/:id/iterations`

```json
// Request
{ "html": "<html>...</html>", "source": "draft", "inputSummary": "Initial design" }

// Response (201)
{ "iteration": { "id": "...", "number": 1, "previewUrl": "https://...", ... } }
```

The service renders the HTML synchronously (~1-2s), uploads the PNG preview, and returns the iteration with a preview URL the agent can inspect.

## Railway Deployment

Single service deployment:

| Setting | Value |
|---------|-------|
| **Build command** | `npm run build` |
| **Start command** | `npm start` |
| **Release command** | `npm run migrate` |

### Setup

1. Create a Railway project with one service pointing to this repo
2. Add a **PostgreSQL** plugin
3. Configure S3-compatible storage (external provider)
4. Set environment variables (see below)
5. Deploy — migrations run automatically via the release command

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `PORT` | No | HTTP port (default: 3000; Railway sets automatically) |
| `APP_BASE_URL` | Yes | Public base URL of the API |
| `DATABASE_URL` | Yes | PostgreSQL connection string |
| `STORAGE_DRIVER` | No | `local` (default) or `s3` |
| `S3_ENDPOINT` | When s3 | S3-compatible endpoint URL |
| `S3_BUCKET` | When s3 | Bucket name |
| `S3_REGION` | When s3 | AWS region |
| `S3_ACCESS_KEY_ID` | When s3 | Access key |
| `S3_SECRET_ACCESS_KEY` | When s3 | Secret key |

## Testing

```bash
npm test
```