This Project is a self-hosted internal operations app for a small SaaS team, combining an AI marketing agent and an AI support assistant behind role-based access control.access, but off-the-shelf helpdesks gate their AI and RBAC behind paid tiers, and agent platforms are licensed against self-hosting.
How it works: built on FastAPI + LangGraph, the app runs two agent graphs sharing one pattern (state = messages, persistent checkpointer, fake-model injectable for tests). The marketing agent is a ReAct agent with 20 tools and a human-in-the-loop publish gate — it can draft and schedule content but cannot publish without human approval, enforced via interrupt() inside the tool itself, not the graph topology. The support agent runs hybrid RAG (BM25 + vector search fused with RRF, gated on absolute relevance scores so it says "I don't know" instead of hallucinating) and can escalate to a human-managed ticket queue.
An admin creates employee logins and grants role-based access: marketing never sees tickets, support never sees content drafts. RBAC is tested with an explicit denial matrix (wrong role → 403, foreign thread → 404).
Stack: FastAPI, LangGraph, Postgres, hybrid BM25+vector retrieval, JWT auth, Docker Compose deployment with Traefik/Let's Encrypt for production. 332 offline tests (scripted fake chat models, no API keys required) cover the agent graphs, RBAC, ticket lifecycle, and RAG gating.
Ethics: self-hosted with a single LLM endpoint swap point for EU data residency, prompt-injection guard treating user/customer text as data not instructions, and a hard autonomy boundary — no agent can publish or contact a human without a persisted interrupt() a person resolves.