Skip to content

hoodsy/dingrc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

114 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dingrc

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


Tech stack

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.

Repo layout

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.

Local dev

Prereqs

  • 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.md for what env vars to set)

First-time setup

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 :5173

Vite 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.


Common commands

Backend

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 subcommands

Pipeline runs that need the embedding model (most of them) require the optional extras: uv sync --extra pipeline, then uv run --extra pipeline pipeline ….

Frontend

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

Database

# Apply pending migrations to the linked Supabase project
supabase db push

# Diff local schema against remote (preview before push)
supabase db diff

For 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.

Deploy

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.


Key concepts

  • Agent loop: services/backend/api/agent/ — LangGraph state machine that interleaves Claude calls with SEC-data tool invocations. Streams text_delta, tool_start/tool_end, and canvas_command events 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 in api/agent/stream.py; client-side handling lives in web/src/graph/commands.ts.
  • Credits + free tier: Authenticated users have a credit balance (users.credits); each query deducts CREDITS_PER_QUERY (3) atomically. Anonymous users get 5 free queries keyed on a localStorage session id (anonymous_usage table).
  • Sharing: POST /api/shares snapshots 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 by auth.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_log with token counts + USD cost. Cross-reference against PostHog query_id to compute cost per funnel step.

Where to look in the docs

  • docs/ARCHITECTURE.md — module-by-module backend overview
  • docs/PIPELINE.md — data ingestion details
  • docs/RESEARCH.md — agent design + canvas command protocol
  • docs/GRAPH.md — graph rendering + layout algorithm
  • docs/CHARTS.md — visx-based chart system
  • docs/CANVAS.md — canvas interactions + spotlight system
  • docs/SPOTLIGHT.md — spotlight UI + dimming logic
  • docs/FINANCIALS.md — financial-metrics service + derivations
  • docs/WATCHLIST.md — watchlist feature + future intelligence ideas
  • docs/PERSONALIZATION.md — long-term personalization vision
  • docs/LAUNCH.md — deploy checklist + env vars
  • docs/AUTH_BILLING_SETTINGS_SPEC.md — Stripe + auth + settings flow
  • docs/posthog-setup-report.md — analytics event inventory
  • docs/TODO.md — backlog

Memory aids for Claude Code

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.

Legal

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors