# CastDeck

CastDeck is a podcast hosting platform for publishing, distributing, and tracking audio shows. It provides show management, episode publishing, RSS feed generation, private feeds, analytics, and basic monetization workflows for independent creators and small networks.

## Features

- Create and manage multiple podcast shows
- Upload, process, and host episode audio
- Generate Apple Podcasts and Spotify-compatible RSS feeds
- Schedule episodes for future release
- Draft, publish, unpublish, and archive episodes
- Support public and private podcast feeds
- Track downloads, listener apps, countries, and episode performance
- Manage team roles for producers, editors, and admins
- Configure custom domains for podcast websites and feeds
- Store media locally or in S3-compatible object storage

## Requirements

- Node.js 20+
- PostgreSQL 15+
- Redis 7+
- pnpm 9+
- FFmpeg

## Installation

Clone the repository:

```bash
git clone https://github.com/example/castdeck.git
cd castdeck
```

Install dependencies:

```bash
pnpm install
```

Create the environment file:

```bash
cp .env.example .env
```

Update `.env` with your local database, Redis, storage, and application settings.

Run database migrations:

```bash
pnpm db:migrate
```

Start the development server:

```bash
pnpm dev
```

The application will be available at:

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

## Usage

Create an admin user:

```bash
pnpm users:create-admin
```

Log in to the dashboard and create your first show. Add the show title, artwork, description, category, author information, and default publishing settings.

Upload an episode from the dashboard or use the CLI:

```bash
pnpm episodes:upload \
  --show my-show \
  --file ./episodes/launch-episode.mp3 \
  --title "Launch Episode"
```

Publish the episode:

```bash
pnpm episodes:publish --show my-show --episode launch-episode
```

Your podcast RSS feed will be available at:

```text
http://localhost:3000/feeds/my-show.xml
```

For production deployments, run the app with:

```bash
pnpm build
pnpm start
```

## Configuration

CastDeck is configured through environment variables.

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `APP_URL` | Yes | `http://localhost:3000` | Public URL for the web app and generated podcast links. |
| `DATABASE_URL` | Yes | None | PostgreSQL connection string. |
| `REDIS_URL` | Yes | `redis://localhost:6379` | Redis connection string for queues and caching. |
| `SESSION_SECRET` | Yes | None | Secret used to sign user sessions. |
| `MEDIA_STORAGE_DRIVER` | Yes | `local` | Storage backend. Supported values: `local`, `s3`. |
| `MEDIA_LOCAL_PATH` | No | `./storage/media` | Local path for uploaded audio and artwork. |
| `S3_BUCKET` | No | None | S3 bucket used when `MEDIA_STORAGE_DRIVER=s3`. |
| `S3_REGION` | No | None | S3 region. |
| `S3_ENDPOINT` | No | None | Custom endpoint for S3-compatible providers. |
| `S3_ACCESS_KEY_ID` | No | None | S3 access key. |
| `S3_SECRET_ACCESS_KEY` | No | None | S3 secret key. |
| `FFMPEG_PATH` | No | `ffmpeg` | Path to the FFmpeg binary. |
| `ANALYTICS_RETENTION_DAYS` | No | `730` | Number of days to retain download analytics. |
| `ENABLE_PRIVATE_FEEDS` | No | `true` | Enables token-protected private podcast feeds. |
| `SMTP_URL` | No | None | SMTP connection string for transactional email. |

Example production configuration:

```env
APP_URL=https://podcasts.example.com
DATABASE_URL=postgres://castdeck:password@postgres:5432/castdeck
REDIS_URL=redis://redis:6379
SESSION_SECRET=change-this-secret
MEDIA_STORAGE_DRIVER=s3
S3_BUCKET=castdeck-media
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=change-this-key
S3_SECRET_ACCESS_KEY=change-this-secret
ENABLE_PRIVATE_FEEDS=true
```

## License

MIT