# Oliver DeckForge

AI-powered enterprise presentation generator with multi-tenant architecture, custom template support, and role-based access control.

## Architecture

```
                    ┌─────────┐
                    │  nginx  │ :80
                    └────┬────┘
                   ┌─────┴─────┐
              ┌────┴───┐  ┌────┴───┐
              │ Next.js │  │FastAPI │
              │  (web)  │  │ (api)  │
              │  :3000  │  │ :8000  │
              └────┬────┘  └───┬────┘
                   │       ┌───┴────┐
                   │  ┌────┴──┐ ┌───┴────┐
                   │  │Worker │ │Postgres│
                   │  │ (arq) │ │  :5432 │
                   │  └───┬───┘ └────────┘
                   │      │
                   └──────┴──── app_data volume
```

| Service    | Stack                                | Purpose                                |
|------------|--------------------------------------|----------------------------------------|
| **web**    | Next.js 14, Redux Toolkit, Shadcn UI | Frontend SPA + Puppeteer PDF/PPTX export |
| **api**    | FastAPI, SQLModel, Alembic           | REST API, auth, RBAC, SSE streaming    |
| **worker** | arq (async Redis queue)              | Background AI generation jobs          |
| **postgres** | PostgreSQL 16                      | Primary database                       |
| **redis**  | Redis 7                              | Job queue + caching                    |
| **nginx**  | nginx                                | Reverse proxy, static file serving     |

## Features

- **AI Presentation Generation** — Upload documents (DOCX, PPTX, images) or provide a URL/topic, get a full slide deck
- **Custom Templates** — Upload master PPTX decks, AI parses layouts into reusable React components
- **Multi-Tenant** — Client-based data isolation with per-client branding and storage
- **RBAC** — Super admin, client admin, and user roles with granular permissions
- **SSO** — Azure AD authentication with dev bypass mode for local development
- **Review Workflow** — Draft / In Review / Approved status tracking for presentations
- **Export** — PDF and PPTX export via headless Chromium
- **Admin Panel** — User/team/client management, analytics, storage, settings, audit logs
- **Multi-Provider AI** — Anthropic (Claude), OpenAI, Google, Ollama for LLM; multiple image generation providers
- **i18n** — Internationalization support via react-i18next

## Quick Start

### Prerequisites

- Docker & Docker Compose
- An Anthropic API key (for AI generation)
- A Google API key (for image generation, optional)

### 1. Configure environment

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

Edit `.env` and set your API keys:

```env
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=...          # optional, for image generation
```

### 2. Start all services

```bash
make dev
```

This builds and starts all 6 services. The app will be available at:

- **App**: http://localhost (via nginx) or http://localhost:3000 (direct)
- **API docs**: http://localhost/docs
- **Database**: localhost:5432

### 3. Run database migrations

```bash
make migrate
```

### 4. Seed initial data

```bash
make seed
```

This creates the default super admin user and a sample client.

### 5. Log in

With Azure AD credentials not configured, the app uses dev auth bypass mode. Log in at http://localhost/login with the password set in `DEV_AUTH_PASSWORD` (default: `devpass123`).

## Local Development (without Docker)

### Backend

```bash
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Set environment variables
export DATABASE_URL="postgresql+asyncpg://deckforge:deckforge@localhost:5432/deckforge"
export REDIS_URL="redis://localhost:6379/0"

# Run API server
uvicorn api.main:app --reload --port 8000

# Run worker (separate terminal)
python -m arq workers.main.WorkerSettings
```

### Frontend

```bash
cd frontend
npm install
npm run dev
```

The frontend dev server runs on port 3000 and proxies API requests to the backend via Next.js rewrites.

## Makefile Commands

| Command       | Description                          |
|---------------|--------------------------------------|
| `make dev`    | Build and start all services         |
| `make build`  | Build Docker images                  |
| `make up`     | Start services (detached)            |
| `make down`   | Stop all services                    |
| `make migrate`| Run Alembic database migrations      |
| `make seed`   | Seed initial data                    |
| `make test`   | Run backend pytest suite             |
| `make test-e2e`| Run Cypress E2E tests               |
| `make logs`   | Tail all service logs                |
| `make shell-api` | Shell into API container          |
| `make shell-db`  | psql into PostgreSQL              |

## Project Structure

```
├── backend/
│   ├── api/                  # FastAPI app, routers, middlewares
│   │   ├── v1/
│   │   │   ├── admin/        # Admin panel endpoints
│   │   │   ├── auth/         # Authentication (Azure AD + dev bypass)
│   │   │   └── ppt/          # Presentation CRUD, generation, export
│   │   └── middlewares/      # Auth, RBAC, audit middlewares
│   ├── models/               # SQLModel database models
│   ├── services/             # Business logic (AI, templates, settings)
│   ├── workers/              # arq background job definitions
│   ├── utils/                # Helpers (export, layout, env)
│   ├── alembic/              # Database migrations
│   └── Dockerfile
├── frontend/
│   ├── app/                  # Next.js 14 App Router pages
│   │   ├── (presentation-generator)/  # Main app routes
│   │   ├── admin/            # Admin panel pages
│   │   └── api/              # API routes (export via Puppeteer)
│   ├── components/ui/        # Shadcn UI components
│   ├── store/slices/         # Redux Toolkit state management
│   ├── locales/              # i18n translation files
│   └── Dockerfile
├── docker-compose.yml
├── nginx.conf
├── Makefile
└── .env.example
```

## Environment Variables

| Variable               | Required | Default            | Description                              |
|------------------------|----------|--------------------|------------------------------------------|
| `ANTHROPIC_API_KEY`    | Yes      | —                  | Anthropic API key for Claude             |
| `ANTHROPIC_MODEL`      | No       | claude-sonnet-4-6  | Claude model ID                          |
| `GOOGLE_API_KEY`       | No       | —                  | Google API key for image generation      |
| `IMAGE_PROVIDER`       | No       | nanobanana_pro     | Image provider (see below)               |
| `POSTGRES_PASSWORD`    | No       | deckforge          | PostgreSQL password                      |
| `JWT_SECRET_KEY`       | Yes      | —                  | Secret for JWT token signing             |
| `AZURE_AD_TENANT_ID`   | No       | —                  | Azure AD tenant (blank = dev auth mode)  |
| `AZURE_AD_CLIENT_ID`   | No       | —                  | Azure AD app client ID                   |
| `AZURE_AD_CLIENT_SECRET`| No     | —                  | Azure AD app secret                      |
| `DEV_AUTH_PASSWORD`    | No       | devpass123         | Password for dev auth bypass             |
| `APP_DATA_DIRECTORY`   | No       | ./data             | Directory for generated files            |

### Supported AI Providers

**LLM**: `anthropic` (default), `openai`, `google`, `ollama`, `custom`

**Image generation**: `nanobanana_pro` (default), `gemini_flash`, `dall-e-3`, `gpt-image-1.5`, `pexels`, `pixabay`, `comfyui`

## Authentication

### Azure AD SSO (Production)

Configure `AZURE_AD_TENANT_ID`, `AZURE_AD_CLIENT_ID`, and `AZURE_AD_CLIENT_SECRET` in `.env`. Users authenticate via Microsoft login flow.

### Dev Bypass (Local Development)

When `AZURE_AD_TENANT_ID` is not set, the app uses a simple password-based login. Set the password via `DEV_AUTH_PASSWORD`.

## Custom Templates

1. Navigate to **Admin > Clients > [Client] > Master Decks**
2. Upload a PPTX file — the system will:
   - Extract slide layouts and XML definitions
   - Generate PDF screenshots via LibreOffice
   - Use AI (LLM vision) to convert each layout into a React TSX component
3. The parsed layouts appear as available templates during presentation generation
4. Manage layouts: delete unwanted ones, filter by type, toggle visibility

## License

Proprietary. All rights reserved.
