A FastAPI backend and Next.js frontend in which seven specialised agents — Orchestrator, Research, Strategy, Critic, Planner, QA and Memory — collaborate on a shared state ledger to turn a business brief into a go-to-market report with cited claims, confidence ratings and a ranked execution plan.
Captured 2026-08-19 with Playwright against next dev from a clean clone, with placeholder
Supabase and Stripe keys and no backend running — which is exactly the state you will be in
if you clone this. Nothing here is a mock-up; where a page shows an error or a spinner, that is
what it genuinely does under those conditions, and it is labelled.
/dashboard, /dashboard/analysis and /admin are not shown, because they redirect to
/login without a Supabase session. That is the auth guard working, and it means the core
product cannot be photographed from a clean clone. Those three screenshots are the honest gap
in this section rather than an oversight.
/share/<id> renders "Unable to load this report" without a backend, which is the correct
failure and not a bug.
This project was built as a portfolio/assignment exercise and is no longer under active development. It is published so the code and its test suite can be read, not as a maintained product or a service you can sign up for.
Concretely, so you know what you are looking at:
- Nothing is deployed. There is no live URL. Earlier versions of these docs
advertised a Cloud Run service in
asia-south1; that service has been torn down and its URL now 404s.cloudrun-service.yamlanddeploy/are instructions for deploying it yourself, not a description of a running system. - The test suite is real and passes from a clean clone with no configuration. See Testing for exact numbers and how to reproduce them.
- Parts of the codebase are designed but not wired in. See What is built and what is not. The repo is not uniformly finished, and this README tries to be precise about where the edges are.
agent.mdis an internal build guide written in an aspirational voice ("what this becomes"). Where it and this README disagree, this README is the one scoped to verified claims.
Working and covered by tests
| Area | Notes |
|---|---|
| Report assembly pipeline | app/reporting/ — claims, citations, confidence, ranking, source quality, structure, quality gate. The best-tested part of the repo (78–100% line coverage per module). |
| Agent capsules | All seven agents in app/agents/ run against the shared ledger; orchestrator retry/routing logic is exercised. |
| LLM routing | app/llm_router.py (95% covered) — task-complexity routing, circuit breakers, fallback between Gemini / Groq / OpenRouter, token-cost accounting. |
| Workflow dispatch | Two engines behind one seam: in-process inline and durable inngest, both calling assemble_report. |
| API surface | 40 routes: jobs, reports, admin, billing, export, share, webhooks. Auth (Supabase JWT), rate limiting, quota flags. |
| Frontend | Next.js App Router UI — workflow DAG, job dashboard, report viewer, trust panel, share/export. 348 passing component tests. |
| Schema | 7 Alembic migrations including RLS policies and pgvector. |
Designed but not wired in — do not read these as working features
| Area | State |
|---|---|
app/reporting/user_context.py |
726 lines implementing PDF/DOCX ingestion, embedding-based relevance scoring and contradiction detection. Nothing imports it. app/api/routes.py persists user-context items with its own inline logic instead. 0% coverage. |
app/agent_learning.py |
The Research agent's "learn from past executions" phase, imported whenever a database session is present. No test ever exercises that branch, so the cross-job learning behaviour is entirely unverified. 0% coverage. |
| Deep reasoning engine | A full spec (requirements/design/tasks) exists in the author's local .kiro/ directory with zero of its tasks implemented. No code for it is in this repository. |
| Vector memory | app/memory/vector_store.py is only 16% covered. The pgvector wiring exists but cross-job semantic recall is largely unverified. |
| Stripe billing | Runs in an offline mock mode by default, which is what the tests cover. The one occasion the live path was reached with real credentials, the configured price IDs did not exist in the Stripe account — so the real payment flow has never completed successfully. |
| The "Anonymous" plan on the billing page | Advertises a tier nobody can be in. 6614745 disabled anonymous access — FEATURE_ANONYMOUS defaults to false in app/config.py, proxy.ts sends every tokenless visitor to /login, and lib/auth.tsx says in a comment "do NOT create an anonymous session". That commit removed the guest button and left the plan card, so billing/page.tsx still offers "Anonymous / Free / forever / 3 reports per period". Found 2026-08-19 by reading the code behind a screenshot. |
Weakly covered elsewhere: api/routes.py 31%, api/webhooks.py 24%,
api/export.py 25%, middleware/rate_limit.py 27%.
┌──────────────────────────────────────────────────────────┐
│ Next.js frontend (App Router, TypeScript) │
└────────────────────────────┬─────────────────────────────┘
│ REST + SSE
┌────────────────────────────▼─────────────────────────────┐
│ FastAPI backend │
│ auth · rate limiting · quotas · routing │
└────────────────────────────┬─────────────────────────────┘
│ dispatch (one of two engines)
┌────────────────────┴────────────────────┐
│ │
┌──────────▼───────────┐ ┌───────────▼──────────┐
│ inline (in-process) │ │ Inngest (durable) │
│ FastAPI background │ │ off-request, retried│
└──────────┬───────────┘ └───────────┬──────────┘
└────────────────────┬────────────────────┘
│ both call the same seam
┌────────────────────────────▼─────────────────────────────┐
│ app/reporting/assembly.py — assemble_report() │
│ pure, engine-agnostic report construction │
└────────────────────────────┬─────────────────────────────┘
│ shared state ledger
┌────────────────────────────▼─────────────────────────────┐
│ PostgreSQL + pgvector (embeddings) │
└────────────────────────────┬─────────────────────────────┘
│ read / write
┌────────────────────────────▼─────────────────────────────┐
│ Agent capsules │
│ Orchestrator · Research · Strategy · Critic │
│ Planner · QA · Memory │
└──────────────────────────────────────────────────────────┘
There is no Celery and no Redis — both were removed in favour of the inline/Inngest split, so the system has no always-on worker and can scale to zero.
app/
main.py FastAPI app, router mounting, health
config.py Pydantic settings (all env vars, one place)
database.py async + sync SQLAlchemy sessions
models.py ORM models (100% covered)
llm_client.py provider clients + embeddings
llm_router.py complexity routing, circuit breakers, cost accounting
security.py prompt-injection guard, permissions
observability.py structlog + Langfuse tracing
agents/ orchestrator, research, strategy, critic,
planner, qa, memory
reporting/ engine-agnostic report construction:
assembly, claims, confidence, ranking,
quality_gate, source_quality, source_registry,
structure, user_context (NOT wired in)
workflows/ inline.py (in-process) and pipeline.py (Inngest),
both dispatching into reporting/assembly.py
api/ routes, admin, billing, export, share, webhooks
middleware/ auth (Supabase JWT), rate_limit
memory/vector_store.py pgvector persistence (lightly tested)
alembic/ 7 migrations, incl. RLS policies and pgvector
tests/ 393 backend tests
frontend/ Next.js app + 348 jest component tests
cloudrun-service.yaml Cloud Run service definition (not deployed)
deploy/ Cloud Run and Vercel runbooks (instructions only)
docker-compose.yml API + local Postgres
render.yaml deprecated, retained for reference only
agent.md internal build guide (aspirational — see above)
LOCAL_TESTING.md local dev and local↔cloud parity notes
This is the fastest way to see the project actually do something. It needs no
API keys, no database and no .env — tests/conftest.py pins its own SQLite
database, auth secret and Stripe mock keys.
git clone https://github.com/melbinjp/agentic-bi-platform.git
cd agentic-bi-platform
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
pytestFrontend tests:
cd frontend
npm install
npm testRunning the app for real needs LLM credentials and a Postgres database, because the agents make live model calls.
-
Configure. Copy
.env.exampleto.envand fill in at minimumGEMINI_API_KEYorGROQ_API_KEY, plusDATABASE_URL/DATABASE_URL_SYNC.TAVILY_API_KEYenables real web research; without it the Research agent has no search backend. KeepWORKFLOW_ENGINE=inlineandRUN_JOBS_INLINE=truefor local use. -
Start Postgres and the API. With Docker:
docker compose up --build # API on :8000 + Postgres, migrations run on startOr natively, against any Postgres you control:
alembic upgrade head uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
-
Start the frontend. Create
frontend/.env.localwithNEXT_PUBLIC_API_URL=http://localhost:8000/api/v1, then:cd frontend && npm run dev
- API docs: http://localhost:8000/docs
- Health: http://localhost:8000/api/v1/health
- Frontend: http://localhost:3000
LOCAL_TESTING.md covers this in more detail, including
the Inngest durable path and the local↔cloud parity rules.
Both suites run in CI on every push and pull request
(.github/workflows/tests.yml); the badge above
reflects their live status rather than a number typed into this file.
At the time of writing, on a clean clone with no .env:
| Suite | Result | Command |
|---|---|---|
| Backend (pytest) | 392 passed, 1 skipped of 393 collected | pytest |
| Backend coverage | 62% of 5,074 statements | pytest --cov=app |
| Frontend (jest) | 348 passed across 20 suites | cd frontend && npm run test:ci |
pytest.ini enforces a 60% coverage floor, so CI fails on a regression. The one
skipped test is skipped deliberately, with a reason recorded at the skip site.
Coverage is uneven by design of what was worked on: the report-construction modules that determine output quality sit at 78–100%, while the HTTP edges (routes, webhooks, export) and the unwired modules drag the average down. The per-module numbers are in the table above.
The suite is hermetic. It never contacts an LLM provider, a database server
or Stripe. If you have real credentials in a local .env, they are explicitly
overridden in tests/conftest.py so that a developer's environment cannot change
the result — or leak a live API call.
- Secrets live only in a gitignored
.envlocally, and in Google Secret Manager for a Cloud Run deployment. No secret has ever been committed to this repository. - Prompt-injection screening and agent permission boundaries are in
app/security.py; rate limiting and per-tenant quotas are inapp/middleware/. Row-level security policies ship as an Alembic migration. - Cost runaway protection is via bounded critic iterations, circuit breakers in
the model router, and configurable cost ceilings in
app/config.py. .github/workflows/render-doppler-sync.ymltargets the retired Render.com deployment. It is disabled (manual dispatch only) and kept for auditability.
MIT. See LICENSE. Use it, fork it, take pieces of it.
This section read "All rights reserved" until 2026-08-19, and the LICENSE file had been
deleted in 2fae766, so the repository advertised no licence at all. Both are now MIT, which
is the licence the project shipped with originally in 4ec0d51.
Built by Melbin J Paulose. Archived rather than maintained — issues and pull requests are unlikely to be actioned.



