- Fix PPTX/PDF export: Puppeteer URL port mismatch (80 → 3000) - Fix backend export_utils to use NEXT_INTERNAL_URL env var - Add Chromium to frontend Dockerfile for Docker-based export - Fix slide edit socket hang up with asyncio.wait_for() timeouts - Add FastAPI StaticFiles mounts for /static and /app_data - Add Next.js rewrite for /static/ to proxy to backend - Show template thumbnail in master decks admin page - Add error logging to ReviewWorkflow component - Add Docker env vars for web service (APP_DATA_DIRECTORY, app_data volume) - Add project README in English Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
221 lines
8.8 KiB
Markdown
221 lines
8.8 KiB
Markdown
# 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.
|