# Tech Stack ## 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` |