Tech Stack
How BARs Engine is built — frontend, backend, data layer, and AI infrastructure.
Frontend (Next.js App)
Server components, App Router, and React 19 concurrent features. Most pages are server-rendered for auth-aware data fetching; client components handle interactive UI.
Strict typing across the entire frontend. Types flow from Prisma schema → server actions → components, reducing the surface for runtime surprises.
Utility-first CSS. The dark zinc palette (zinc-900/zinc-800 cards, white text) is the design system. No separate component library — just Tailwind.
Schema-first ORM. The source of truth for the data model lives in prisma/schema.prisma. Run npm run db:sync after schema changes.
Used on the frontend for streaming AI responses (charge capture, quest generation). Pairs with the OpenAI provider on the backend side of Next.js API routes.
Backend (Python / FastAPI)
Async HTTP server for domain-specific AI endpoints. Lives in /backend and runs separately from the Next.js app. Currently has a health endpoint; domain routes are being built out.
Async-first ORM for the Python backend. Models mirror the Prisma schema so both apps share one PostgreSQL database. Alembic handles migrations.
The universal translator between raw data and clean Python objects. Every FastAPI request/response is validated through Pydantic models. Type hints are the source of truth — if it type-checks, the data is valid.
Wraps LLM calls (GPT, Claude, Gemini) in typed, testable Python code. Agents get tools (Python functions the AI can call), dependencies (DB connections, API keys), and structured output (validated Pydantic models returned from the LLM). The app/agents/ directory is the planned home.
Pydantic's observability layer, built on OpenTelemetry. Two lines of setup gives full traces of every agent run — what the AI said, what tools it called, how many tokens it used. Optional in dev, recommended in prod.
Rust-powered replacement for pip + virtualenv. 10–100x faster installs. Used instead of pip in the backend Dockerfile and local dev setup.
Data Layer
Single Postgres instance shared by both the Next.js app (via Prisma) and the Python backend (via SQLAlchemy). Runs locally via Docker; hosted on Neon/Vercel Postgres in production.
Used for storing uploaded assets (voice recordings, images, artifacts).
Pydantic AI — Key Concepts
The Python backend uses Pydantic AI as its agent framework. These are the five concepts worth knowing.
An Agent wraps a model, gives it instructions, tools, and an expected output type. Created once at startup, reused per request. Think of it as the "app" for an LLM.
Instead of raw text, agents return validated Pydantic models. If the model returns invalid data, Pydantic AI tells it to retry. Quest proposals, emotional first aid summaries, and charge captures all use this pattern.
Python functions decorated with @agent.tool that the AI can choose to call mid-run. The function signature and docstring become the tool schema. Example: a tool that looks up a player's active quests before generating a suggestion.
Database sessions, API keys, and HTTP clients injected into tool functions at runtime. In tests, swap in fakes. In prod, pass real connections. The agent code never changes.
Every agent.run() produces a structured trace: messages, tool calls, token usage, latency. Two lines to enable. Crucial for understanding what the AI actually did in a given run.
Full field guide: docs/PYDANTIC_ECOSYSTEM_RESEARCH.md
How the two apps connect
The Next.js app is the primary player-facing interface — quests, BARs, emotional first aid, campaigns, wiki. It talks directly to Postgres via Prisma.
The Python backend (FastAPI) handles AI-heavy operations: agent runs, structured extractions, multi-step workflows. It exposes a REST API that the Next.js app calls for those features. Both apps share the same Postgres database.
The split exists because Pydantic AI's agent framework and Python's AI ecosystem are richer than the Node.js equivalents for complex agent workflows. Simple streaming AI (charge capture, quick generation) stays in Next.js API routes using the Vercel AI SDK.