# Wavecast

Wavecast is a podcast hosting platform for publishing, distributing, and analyzing audio shows. It provides podcast feed generation, episode hosting, private feeds, team management, and listener analytics through a web dashboard and API.

## Features

- Show and episode management
- RSS feed generation with Apple Podcasts and Spotify compatible metadata
- Audio uploads with background transcoding
- Public, private, and scheduled episode publishing
- Team roles for owners, editors, and analysts
- Listener analytics by episode, platform, region, and date range
- Custom podcast websites
- API keys for automation and integrations
- Webhook events for uploads, publishes, and analytics exports

## Install

### Requirements

- Node.js 20+
- PostgreSQL 15+
- Redis 7+
- FFmpeg
- S3-compatible object storage

### Local Setup

```sh
git clone https://github.com/example/wavecast.git
cd wavecast
npm install
cp .env.example .env
npm run db:migrate
npm run dev
```

The dashboard will be available at:

```text
http://localhost:3000
```

### Docker

```sh
docker compose up --build
```

Run database migrations after the services are healthy:

```sh
docker compose exec app npm run db:migrate
```

## Usage

Create the first admin user:

```sh
npm run users:create-admin -- --email admin@example.com
```

Start the web app and background worker:

```sh
npm run dev
npm run worker
```

Upload an episode from the dashboard or through the API:

```sh
curl -X POST http://localhost:3000/api/episodes \
  -H "Authorization: Bearer $WAVECAST_API_KEY" \
  -F "showId=show_123" \
  -F "title=Launch Episode" \
  -F "audio=@episode.mp3"
```

A podcast RSS feed is available after a show is published:

```text
https://your-domain.com/feeds/{show-slug}.xml
```

## Configuration

Wavecast is configured through environment variables.

| Variable | Required | Description |
| --- | --- | --- |
| `APP_URL` | Yes | Public URL for the dashboard and generated feeds |
| `DATABASE_URL` | Yes | PostgreSQL connection string |
| `REDIS_URL` | Yes | Redis connection string for queues and caching |
| `SESSION_SECRET` | Yes | Secret used to sign user sessions |
| `STORAGE_DRIVER` | Yes | Storage backend, usually `s3` or `local` |
| `S3_BUCKET` | When using S3 | Bucket for uploaded audio and artwork |
| `S3_ENDPOINT` | When using S3 | S3-compatible endpoint |
| `S3_ACCESS_KEY_ID` | When using S3 | Storage access key |
| `S3_SECRET_ACCESS_KEY` | When using S3 | Storage secret key |
| `TRANSCODE_FORMATS` | No | Comma-separated output formats, default `mp3,aac` |
| `ANALYTICS_RETENTION_DAYS` | No | Number of days to keep raw analytics events |
| `SMTP_URL` | No | SMTP connection string for account emails |
| `WEBHOOK_SIGNING_SECRET` | No | Secret used to sign outbound webhook payloads |

Example:

```env
APP_URL=http://localhost:3000
DATABASE_URL=postgres://wavecast:wavecast@localhost:5432/wavecast
REDIS_URL=redis://localhost:6379
SESSION_SECRET=replace-me
STORAGE_DRIVER=local
ANALYTICS_RETENTION_DAYS=365
```

## Scripts

```sh
npm run dev          # Start the development server
npm run worker       # Start background jobs
npm run build        # Build production assets
npm run start        # Start the production server
npm run db:migrate   # Run database migrations
npm test             # Run the test suite
```

## License

MIT