See how public companies connect.
A research tool that turns plain-language questions about public companies into a live, evidence-backed graph. Ask about competitors, suppliers, customers, regulators, or risks — the LangGraph agent calls SEC-filings tools, builds the answer as a streaming canvas, and cites every claim back to a 10-K, 10-Q, or 8-K.
Production: https://dingrc.com
| Layer | What we use | Why |
|---|---|---|
| Frontend | React 19 + TypeScript, Vite 8, Tailwind 4, Zustand, React Flow (@xyflow/react), framer-motion, visx for charts, react-router 7 |
SPA with a streaming canvas. Zustand keeps state simple; React Flow handles the graph rendering. |
| Backend | FastAPI, SQLAlchemy 2.0, LangGraph + LangChain Anthropic, Pillow, slowapi | Streaming SSE for agent responses; LangGraph orchestrates the research loop and tool calls. |
| Database | Supabase Postgres + pgvector (HNSW index on chunks.embedding) | Stores companies, filings, chunks (vector embeddings), relationships, evidence, financials, plus per-user data (saved graphs, watchlist, credit ledger). RLS gates user-scoped tables. |
| LLMs | Anthropic Claude — Sonnet 4 for graph-building + relationship extraction; Haiku 4.5 for fast tool selection + summaries | Cost-tiered: Haiku for quick decisions, Sonnet for the heavier reasoning. Per-call costs are logged to query_cost_log. |
| Embeddings | Voyage AI (voyage-3-large) |
Used for chunk embedding during the pipeline. |
| Auth | Supabase Auth (email/password + Google OAuth) | JWTs flow with every API request via the Supabase JS client. |
| Payments | Stripe Checkout — $5/mo subscription (100 credits) + $5 top-up (100 credits). 3 credits per query. | Webhook fires subscription_activated / credits_topped_up etc., handler grants credits via credit_svc.add_credits. |
| Analytics | PostHog (frontend + backend), Google Analytics, Hotjar (via ContentSquare). All gated on cookie consent. | PostHog captures funnel events with shared query_ids tying frontend → backend → DB cost rows. |
| Deploy | Railway (web + backend as separate services), Supabase (DB + Auth), Cloudflare (DNS + Worker for /s/* routing) |
See docs/LAUNCH.md for the full deploy walkthrough. |
| Cron | GitHub Actions, every 30 min | Polls EDGAR's atom feed; runs the full pipeline atomically on each new filing for a tracked ticker. |
dingrc/
├── docs/ # Architecture, launch checklist, feature specs
├── supabase/migrations/ # Database schema migrations
├── .github/workflows/ # Scheduled GitHub Actions (EDGAR cron)
├── services/
│ ├── backend/ # FastAPI app + LangGraph agent + pipeline CLI
│ │ ├── api/ # FastAPI app
│ │ │ ├── controllers/ # Route handlers (research, billing, graphs, watchlist, shares, …)
│ │ │ ├── services/ # Reusable business logic (credits, stripe, financials, cost_log, …)
│ │ │ ├── agent/ # LangGraph research agent + tools + streaming
│ │ │ ├── analytics.py # PostHog client + capture_event helper
│ │ │ └── share_image.py # Pillow OG card renderer
│ │ ├── pipeline/ # Data ingestion + extraction CLI (`pipeline` command)
│ │ ├── db/ # SQLAlchemy models + session factory
│ │ ├── tests/ # pytest
│ │ ├── logs/ # Pipeline run logs (gitignored except .gitkeep)
│ │ └── Dockerfile # API service image
│ └── web/ # React + Vite SPA
│ ├── public/ # Static assets (logo.svg, favicon, robots, sitemap, og-default.png)
│ ├── src/
│ │ ├── api/ # HTTP client + response types
│ │ ├── components/ # UI (modals, panels, graph, onboarding, cookie banner)
│ │ ├── hooks/ # Zustand stores + custom hooks
│ │ ├── graph/ # Layout + canvas command parsing
│ │ ├── integrations/ # Dynamic loaders for GA + Hotjar
│ │ ├── analytics.ts # PostHog (gated on consent)
│ │ └── consent.ts # Cookie consent state + reactive hook
│ ├── nginx.conf # SPA fallback + cache headers
│ └── Dockerfile # Static build image
└── README.md # You are here.
- Python 3.12 (managed via pyenv recommended)
- Node 20+ + npm
- uv for Python deps:
curl -LsSf https://astral.sh/uv/install.sh | sh - Supabase CLI for DB migrations:
brew install supabase/tap/supabase - A Supabase project + Stripe test keys (see
docs/LAUNCH.mdfor what env vars to set)
git clone git@github.com:hoodsy/dingrc.git
cd dingrc
# Backend — create services/backend/.env with the keys listed in docs/LAUNCH.md
cd services/backend
uv sync
uv run dingrc-api # starts FastAPI on :8000
# Frontend (separate terminal) — create services/web/.env with the VITE_* keys
cd ../web
npm install
npm run dev # starts Vite on :5173Vite proxies /api/* → backend at :8000, so the frontend talks to your local backend out of the box.
The minimum env vars to get a working dev loop are listed in docs/LAUNCH.md under the "API service" and "UI service" sections. For local Stripe webhook testing, also run stripe listen --forward-to localhost:8000/api/billing/webhook and copy the printed whsec_… into your .env.
cd services/backend
# Dev server (auto-reloads)
uv run dingrc-api
# Tests
uv run pytest
# Pipeline CLI (data ingestion + processing)
uv run pipeline ingest AAPL MSFT # fetch SEC filings for tickers
uv run pipeline embed # embed unprocessed chunks
uv run pipeline extract # extract relationships via Claude
uv run pipeline enrich # add evidence to relationships
uv run pipeline summarize # generate company summaries
uv run pipeline batch AAPL # run all phases for a ticker
uv run pipeline watch-filings --dry-run # poll EDGAR; show what'd be processed
uv run pipeline --help # all subcommandsPipeline runs that need the embedding model (most of them) require the optional extras: uv sync --extra pipeline, then uv run --extra pipeline pipeline ….
cd services/web
npm run dev # Vite dev server on :5173
npm run build # Production build → dist/
npm run lint # ESLint
npm test # Vitest unit tests
npx tsc -b # Standalone typecheck# Apply pending migrations to the linked Supabase project
supabase db push
# Diff local schema against remote (preview before push)
supabase db diffFor ad-hoc queries, use the Supabase SQL editor in the dashboard. The mcp__supabase__* tools also work from Claude Code if you have the MCP server configured.
Both services deploy automatically when main is pushed; Railway picks up the latest commit. Trigger a manual redeploy from Railway's dashboard if needed.
After any change to a VITE_* build arg on the web service, you must trigger a rebuild — Vite inlines those at build time, not runtime.
- Agent loop:
services/backend/api/agent/— LangGraph state machine that interleaves Claude calls with SEC-data tool invocations. Streamstext_delta,tool_start/tool_end, andcanvas_commandevents over SSE. Frontend renders each event as it arrives. - Canvas commands: A small text protocol (
CENTER,NODE,EDGE,CHART,SPOTLIGHT, …) the agent emits between tool calls. Parser lives inapi/agent/stream.py; client-side handling lives inweb/src/graph/commands.ts. - Credits + free tier: Authenticated users have a credit balance (
users.credits); each query deductsCREDITS_PER_QUERY(3) atomically. Anonymous users get 5 free queries keyed on a localStorage session id (anonymous_usagetable). - Sharing:
POST /api/sharessnapshots the agent graph + renders a Pillow PNG, returns a token.dingrc.com/s/{token}routes through a Cloudflare Worker → backend, which returns templated SPA HTML with per-share OG meta tags injected. - Per-user persistence: Saved graphs and watchlist live in
saved_graphs/watchlist_entries, RLS-gated byauth.uid(). Anonymous users get localStorage-backed equivalents with a one-shot bulk import on first sign-in. - Cost tracking: Every LLM call (agent + pipeline) writes to
query_cost_logwith token counts + USD cost. Cross-reference against PostHogquery_idto compute cost per funnel step.
docs/ARCHITECTURE.md— module-by-module backend overviewdocs/PIPELINE.md— data ingestion detailsdocs/RESEARCH.md— agent design + canvas command protocoldocs/GRAPH.md— graph rendering + layout algorithmdocs/CHARTS.md— visx-based chart systemdocs/CANVAS.md— canvas interactions + spotlight systemdocs/SPOTLIGHT.md— spotlight UI + dimming logicdocs/FINANCIALS.md— financial-metrics service + derivationsdocs/WATCHLIST.md— watchlist feature + future intelligence ideasdocs/PERSONALIZATION.md— long-term personalization visiondocs/LAUNCH.md— deploy checklist + env varsdocs/AUTH_BILLING_SETTINGS_SPEC.md— Stripe + auth + settings flowdocs/posthog-setup-report.md— analytics event inventorydocs/TODO.md— backlog
A few persistent project rules live in ~/.claude/projects/.../memory/ and load automatically per session:
- All DB changes go through Supabase migrations, never raw scripts.
- Single font (Plus Jakarta Sans, sans-serif) across the whole app — no
font-serif. - Code style: minimal, non-repetitive, small composable helpers; reuse existing utilities; don't push to remote without explicit approval.