Agent-based workflow platform that collapses a 6-step manual school-club administration process into a single automated pipeline — covering intake validation, cost planning, enrollment decisions, document generation, and schedule export.
Built as a course project for Agentic AI & Process Automation at UT Dallas, with production-style engineering practices (typed schemas, migrations, audit logging, separation of deterministic vs. LLM-based agents).
Many small-organization admin workflows are still done by hand: a teacher proposes a club, an administrator manually validates the intake form, calculates costs, decides whether enrollment meets the threshold, generates announcement documents, and exports schedules. Each step is a place where a mistake or delay can creep in.
ClubOps treats each step as an agent — some deterministic (rule-based, auditable, never hallucinates), some LLM-based (where natural language generation is genuinely useful) — and orchestrates them behind a FastAPI backend with a PostgreSQL state store and a Next.js admin UI.
Frontend (Next.js + TypeScript)
│
▼
FastAPI Backend ──► PostgreSQL (state + append-only audit log)
│
├── Intake Agent (deterministic — field validation, risk flags)
├── Cost Planning Agent (deterministic — break-even arithmetic)
├── Review Agent (deterministic — committee packet generation)
├── Enrollment Decision Agent (deterministic — OPEN / COMMITTEE / CANCEL rules)
├── Document Agent (Jinja templates + optional LLM polish)
└── Schedule Export Agent (deterministic — calendar export)
Critical decisions that affect real outcomes (whether a club opens, what students pay, whether enrollment is cancelled) are made by deterministic rule-based agents. They are easy to test, never hallucinate, and produce the same output for the same input every time.
LLM calls are restricted to areas where they actually help: polishing generated documents, drafting committee review packets, and producing natural-language announcements. The LLM never makes a yes/no decision that affects an applicant's status.
This separation also makes the system evaluation-friendly: each agent class can be measured independently for accuracy and reliability without one confounding the other.
Every state transition writes a row to workflow_events:
| Column | Purpose |
|---|---|
from_state / to_state |
What the application transitioned between |
event_type |
Submit, approve, escalate, cancel, document generation, etc. |
actor |
Who/what triggered it (admin / agent name) |
payload_json |
Full input + output of the agent call |
created_at |
Timestamp |
This is essentially event sourcing: the full history of every application is replayable, every agent decision is auditable, and offline analysis of agent behavior is straightforward.
| Layer | Tools |
|---|---|
| Backend | Python 3.11, FastAPI, SQLAlchemy 2.0, Alembic |
| Database | PostgreSQL (with JSONB for flexible event payloads) |
| Frontend | Next.js 14, TypeScript, React |
| Document rendering | Jinja2 templates → Markdown → optional LLM polish |
| Infra | Docker Compose (local dev) |
| LLM | OpenAI API (for document polish only) |
| Development | Cursor + Claude Code as primary workflow |
clubops-agent/
├── backend/
│ ├── app/
│ │ ├── api/routes/ # FastAPI route handlers
│ │ ├── core/ # Config, enums, exceptions
│ │ ├── db/ # Base + session
│ │ ├── models/ # SQLAlchemy ORM (club_application, workflow_event, ...)
│ │ ├── schemas/ # Pydantic input/output schemas
│ │ ├── services/
│ │ │ ├── agents/ # 5 workflow agents (intake, cost, review, enrollment, schedule)
│ │ │ ├── documents/ # Jinja rendering + LLM polish
│ │ │ ├── storage/ # Local file storage abstraction
│ │ │ └── workflow_*.py # Workflow orchestration services
│ │ └── main.py # FastAPI entrypoint
│ ├── alembic/ # Database migrations
│ └── pyproject.toml
├── frontend/ # Next.js admin UI
└── docker-compose.yml
docker-compose up -d # Postgres
cd backend
uv sync # or: pip install -e .
alembic upgrade head
uvicorn app.main:app --reload
cd ../frontend
npm install
npm run devAPI docs: http://localhost:8000/docs
Admin UI: http://localhost:3000
- End-to-end multi-agent system design — not a single LLM wrapper, but five distinct agents orchestrated through a typed workflow with explicit state transitions.
- Architectural judgment about when not to use an LLM — deterministic rules for high-stakes decisions, LLMs only where natural language is the actual value-add.
- Production-style engineering — typed schemas (Pydantic + SQLAlchemy), migrations (Alembic), append-only audit log, separation of concerns, Docker-based reproducible dev environment.
- Evaluation-friendly architecture — agent isolation + reproducible audit trail makes it possible to measure each agent's behavior independently and replay historical runs.
- AI-native development — built end-to-end in Cursor and Claude Code, with systematic documentation of orchestration patterns, edge cases, and failure modes.
Course project (2025). Architecturally complete; not deployed to real users. The codebase is intended as a portfolio demonstration of how a multi-agent admin workflow can be designed with the same discipline as a real production system.
Hsiao-Ann Chen (Andy) — MS Business Analytics & AI, UT Dallas LinkedIn · GitHub