Datalumina

Getting started

Setup

Toolchain, Supabase project, environment files, the SEC corpus download, and the build checklist.

By the end of this stage the plumbing is done. A hosted Supabase project exists, both services have filled-in .env files, the 25-filing SEC corpus sits in data/downloads/, and you are on a development branch with a phased to-do list to build against.

None of this is glamorous, and that is the point. As Dave says in the video, "This is engineering in the real world. You don't just jump straight into your AI agent and say, build me this." Once the foundation is in place, everything after it moves fast.

Install the prerequisites

You need four things on your machine:

  • Python 3.12+ with uv for the backend and all scripts
  • Node 20+ with pnpm for the frontend
  • Cursor or Claude Code as your AI coding agent (the repo's AGENTS.md files work with either; rename them to CLAUDE.md for Claude Code)
  • A GitHub account with git configured

Verify the runtimes:

uv --version
node --version
pnpm --version

Clone the repo

The main branch is the starting point, with docs, guides, agent instructions, the data download script, and empty backend/ and frontend/ folders. The finished build lives on development if you ever want to peek ahead.

git clone https://github.com/daveebbelaar/document-copilot.git
cd document-copilot

Create the Supabase project

Supabase provides both the Postgres database (with pgvector) and email auth. Follow docs/guides/supabase-setup.md in the repo, or use the short version:

  1. Sign up at supabase.com (free tier is enough) and open New project.
  2. Name it (Dave uses driftwood-capital) and set a strong database password. Save it. You need it for the DATABASE_URL later.
  3. Pick a region close to you, and remember it. Your Railway services should later deploy to the same region. If the backend sits in Europe and the database in the US, every query pays for a network hop across the ocean.
  4. Leave enable automatic row-level security checked, then create the project and wait until it reports healthy.

RLS is why the anon key can safely live in the browser later. With row-level security enabled and policies configured, a logged-in user can only touch their own rows. Without it, a public anon key is a back door into your database.

Create an OpenAI API key

Go to platform.openai.com, create a new API key (name it after the project so you can revoke it later), and copy it somewhere safe. You will not call OpenAI until the ingestion and agent phases, but setting it up now means the environment is complete in one pass.

Configure environment files

Both services ship with a committed .env.example. Copy each one and fill in real values; the .env files themselves are gitignored, so check git status and confirm nothing secret shows up.

cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env

The frontend needs only browser-safe values:

VITE_API_BASE_URL=http://localhost:8000
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key

Find the project URL and anon (publishable) key under Project Settings, API in the Supabase dashboard. The anon key is safe in the browser only because RLS is enabled; that is the deal.

The backend gets the same URL and anon key, plus two real secrets:

SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_ANON_KEY=your-anon-public-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-secret-key
DATABASE_URL="postgresql://postgres:your-password@db.your-project-ref.supabase.co:5432/postgres"
OPENAI_API_KEY=sk-your-openai-api-key

Two details here trip people up every time:

  • The service role key bypasses RLS. It allows privileged access to everything in the project. It lives only in backend/.env, never in the frontend, never in git.
  • DATABASE_URL must be a session-level connection. In the dashboard click Connect and use the direct connection or the session pooler string. Do not use the transaction pooler URL; Alembic migrations require a session connection. And put quotes around the whole URL. If your database password contains special characters like # or %, they break env file parsing without quotes. Dave hits exactly this in the video and the quotes are what fix it.

The remaining backend variables in .env.example (embedding model, retrieval tuning, ALLOWED_ORIGINS) can keep their defaults for now.

Download the corpus

The repo ships with data/download.py, a zero-dependency script that pulls 10-K filings from SEC EDGAR. Open it and set your user agent first; SEC requires a contact address on API requests:

# Params: edit these, then run `uv run data/download.py`
USER_AGENT = "Document Copilot your.email@example.com"
TICKERS = ["AAPL", "MSFT", "NVDA", "AMZN", "GOOGL"]
FILINGS_PER_COMPANY = 5

Then run it from the repo root:

uv run data/download.py
# Downloaded 25 filing(s) to .../data/downloads
# Manifest: .../data/downloads/manifest.json

This fetches the last five fiscal years of 10-Ks for the five companies, organized by year, plus manifest.json, an index recording ticker, form, filing date, accession number, source URL, and local path for every file. The ingestion pipeline later reads its metadata from this manifest. The downloads are gitignored because the corpus is large.

Open one of the .htm files in your browser to see what you are dealing with. Each filing is hundreds of pages of narrative, numbers, and tables. This is the raw material the whole system exists to make queryable.

Generate the to-do list

Before building anything, have your AI agent turn the brief and the architecture into a phased checklist. Dave's prompt in the video, paraphrased, asks the agent to help set up a checklist in docs/todos.md and to figure out the most logical way to set up the project, backend or frontend first, so the architecture gets implemented and the client brief satisfied.

This is also the point in the video where Dave stops typing prompts and starts dictating them. The dictation bar you see popping up is Glaido.

Accelerate your workflowDictate your prompts with Glaido

Glaido is the #1 dictation tool for developers, and the one Dave uses throughout the video.

Try Glaido free

The result in the repo is docs/todos.md, ten phases from Phase 0 (prerequisites) through Phase 9 (deployment), starting backend-first because a frontend without a backend is an empty shell. The ritual for the rest of the build is to work top to bottom, check items off between phases, and keep coming back to this file so you and the agent always share the same picture of what is done and what is next.

Phase 0 is exactly what you just did:

## Phase 0: Prerequisites & foundation

- [x] Install toolchain: Python 3.12+, `uv`, Node 20+, `pnpm`
- [x] Create Supabase project and collect credentials
- [x] Create OpenAI API key (needed from Phase 6 onward)
- [x] Set `USER_AGENT` in `data/download.py` and download sample 10-K corpus
- [x] Confirm `data/downloads/manifest.json` lists AAPL, MSFT, NVDA,
      AMZN, GOOGL filings (2021-2025)

Create a development branch

Keep main clean and do all work on a branch:

git checkout -b development

This mirrors the public repo, where main stays the tutorial starting point and development accumulates the finished build.

daveebbelaar/document-copilot0:28:00

Checkpoint

Before starting on the backend, confirm:

  • uv --version, node --version, and pnpm --version all work
  • Your Supabase project is healthy, with automatic RLS enabled, and you have the URL, anon key, service role key, and database password collected
  • backend/.env and frontend/.env exist, are filled in, and do not appear in git status
  • data/downloads/manifest.json exists and lists 25 filings across AAPL, MSFT, NVDA, AMZN, GOOGL for 2021-2025
  • docs/todos.md exists with Phase 0 checked off, and you are on the development branch

Next: Backend foundation

Scaffold the FastAPI service, the settings module, SQLAlchemy models, and the first Alembic migration.

On this page