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 |