- Rebrand LoginPage logo to Oliver design system - Move Admin nav link to bottom-left user area - Remove "Ask AI to improve" button from step 2 (VariantsGrid) - Add CharCount component with copy limits across prompt, edit, and export views - Add delete variant with confirmation dialog on step 2 cards - Add theme palette migration (0007_theme_palette.py) - Add copyLimits.ts and themes.ts libs - Remove unused BannerEditor.tsx page and old logo PNG - Add AGENTS.md project entry point - Add docs/ directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
119 lines
4.5 KiB
Markdown
119 lines
4.5 KiB
Markdown
# Tech Stack
|
||
|
||
<!-- generated: 2026-04-29 -->
|
||
|
||
## Backend
|
||
|
||
| Package | Version | Purpose |
|
||
|---------|---------|---------|
|
||
| Python | 3.12 | Runtime |
|
||
| FastAPI | ≥ 0.115 | HTTP framework |
|
||
| uvicorn[standard] | ≥ 0.30 | ASGI server |
|
||
| SQLAlchemy[asyncio] | ≥ 2.0 | ORM, async queries |
|
||
| asyncpg | ≥ 0.29 | PostgreSQL async driver |
|
||
| alembic | ≥ 1.13 | DB migrations |
|
||
| pgvector | ≥ 0.3 | pgvector Python bindings |
|
||
| rq | ≥ 1.16 | Redis Queue — background jobs |
|
||
| redis | ≥ 5.0 | Redis client |
|
||
| openai | ≥ 1.50 | OpenAI API (chat + embeddings) |
|
||
| Pillow | ≥ 10.0 | Image processing |
|
||
| weasyprint | ≥ 62 | PDF contact sheet generation |
|
||
| python-docx | ≥ 1.1 | RAG corpus ingest (.docx parsing) |
|
||
| python-jose[cryptography] | ≥ 3.3 | JWT encode/decode |
|
||
| bcrypt | ≥ 4.0 | Password hashing |
|
||
| httpx | ≥ 0.27 | HTTP client (DAM API) |
|
||
| pydantic-settings | ≥ 2.0 | Environment-based config |
|
||
| python-dotenv | ≥ 1.0 | .env file loading |
|
||
| hatchling | — | Build backend |
|
||
|
||
**Dev extras:** pytest ≥ 8.0, pytest-asyncio ≥ 0.23, pytest-cov ≥ 5.0, ruff ≥ 0.5, mypy ≥ 1.10
|
||
|
||
---
|
||
|
||
## Frontend
|
||
|
||
| Package | Version | Purpose |
|
||
|---------|---------|---------|
|
||
| React | ^18.3 | UI framework |
|
||
| react-dom | ^18.3 | DOM rendering |
|
||
| react-router-dom | ^6.24 | Client-side routing |
|
||
| TypeScript | ^5.5 | Type safety |
|
||
| Vite | ^5.3 | Build tool and dev server |
|
||
| TailwindCSS | ^3.4 | Utility CSS |
|
||
| @radix-ui/* | ^1–2 | Headless UI primitives (dialog, dropdown, select, tabs, toast, tooltip) |
|
||
| class-variance-authority | ^0.7 | shadcn/ui component variants |
|
||
| clsx + tailwind-merge | ^2 | Class name utilities |
|
||
| konva + react-konva | ^9.3 / ^18.2 | Canvas-based banner preview rendering |
|
||
| lucide-react | ^0.400 | Icon set |
|
||
| zustand | ^4.5 | Client state (auth, journey) |
|
||
| autoprefixer | ^10.4 | PostCSS plugin |
|
||
| eslint | ^9 | Linting |
|
||
|
||
---
|
||
|
||
## Infrastructure
|
||
|
||
| Component | Version / Image | Notes |
|
||
|-----------|----------------|-------|
|
||
| PostgreSQL | pgvector/pgvector:pg16 | Includes pgvector extension |
|
||
| Redis | redis:7-alpine | Queue broker and result store |
|
||
| Docker | Docker Compose v2 | Container orchestration |
|
||
| Apache | 2.4 (host) | Reverse proxy + static file serving |
|
||
| Ubuntu | (host OS) | optical-dev.oliver.solutions |
|
||
| Node.js | Installed on host | Frontend build only (not in Docker) |
|
||
|
||
---
|
||
|
||
## AI Models
|
||
|
||
| Model | Provider | Use |
|
||
|-------|---------|-----|
|
||
| gpt-5.4-mini | OpenAI | Copy generation, intent classification, copy refinement |
|
||
| text-embedding-3-small | OpenAI | RAG chunk embeddings (1536 dims), icon embeddings |
|
||
|
||
---
|
||
|
||
## Environment Variables
|
||
|
||
| Variable | Required | Default | Purpose |
|
||
|----------|---------|---------|---------|
|
||
| `POSTGRES_DB` | Yes | barclays_banners | Database name |
|
||
| `POSTGRES_USER` | Yes | banners | DB user |
|
||
| `POSTGRES_PASSWORD` | Yes (prod) | — | DB password |
|
||
| `REDIS_URL` | Yes | redis://redis:6379/0 | Queue connection |
|
||
| `OPENAI_API_KEY` | Yes | — | OpenAI authentication |
|
||
| `OPENAI_MODEL` | No | gpt-5.4-mini | Copy generation model |
|
||
| `OPENAI_EMBEDDING_MODEL` | No | text-embedding-3-small | Embedding model |
|
||
| `SECRET_KEY` | Yes (prod) | dev-secret-key-… | JWT signing key |
|
||
| `JWT_ALGORITHM` | No | HS256 | JWT algorithm |
|
||
| `ACCESS_TOKEN_EXPIRE_MINUTES` | No | 480 | JWT lifetime (8 hours) |
|
||
| `ADOBE_DAM_API_BASE_URL` | No | (empty) | Empty = mock DAM mode |
|
||
| `ADOBE_DAM_CLIENT_ID` | No | — | DAM OAuth client ID |
|
||
| `ADOBE_DAM_CLIENT_SECRET` | No | — | DAM OAuth secret |
|
||
| `APP_ENV` | No | development | `development` disables API docs in prod |
|
||
| `CORS_ORIGINS` | No | localhost:5174 | Comma-separated allowed origins |
|
||
| `APP_BASE_PATH` | No | (empty) | URL prefix e.g. `/barclays-banner-builder` |
|
||
| `ASSETS_ROOT` | No | /assets | Filesystem path for illustration PNGs |
|
||
| `ARTIFACTS_ROOT` | No | /artifacts | Filesystem path for generated PDFs |
|
||
|
||
---
|
||
|
||
## Port Map
|
||
|
||
| Service | Dev host port | Prod host port | Container port |
|
||
|---------|--------------|---------------|---------------|
|
||
| FastAPI (api) | 127.0.0.1:8010 | 127.0.0.1:8010 | 8000 |
|
||
| React dev server | 5174 | — (static files) | 5174 |
|
||
| PostgreSQL | Not exposed | Not exposed | 5432 |
|
||
| Redis | Not exposed | Not exposed | 6379 |
|
||
|
||
---
|
||
|
||
## Linting and Type Checking
|
||
|
||
| Tool | Command | Config |
|
||
|------|---------|--------|
|
||
| ruff | `ruff check .` | `pyproject.toml` — line-length 100, E/F/I/UP rules |
|
||
| mypy | `mypy .` | Standard, Python 3.12 |
|
||
| eslint | `npm run lint` | eslint v9 |
|
||
| TypeScript | `tsc -b` (part of `npm run build`) | `tsconfig.json` |
|