agnes-the-ai-analyst/scripts
Petr Simecek 9b5214ea6f
feat(dev): LOCAL_DEV_MODE for one-command local dev + magic-link fixes (#32)
* feat(dev): add LOCAL_DEV_MODE for one-command local dev

When LOCAL_DEV_MODE=1, every protected route auto-authenticates as a seeded
admin user (default dev@localhost) — no login screen, no Google OAuth config,
no magic-link roundtrip. Startup logs a loud warning to make misuse obvious.

Also fixes two preexisting bugs in the magic-link flow that surfaced while
wiring up the dev fallback:

- /auth/email/verify only accepted POST, but the URL embedded in emails is
  a GET link — clicking from any mail client returned 405. Added a GET
  variant that consumes the token, sets the auth cookie, and redirects to
  /dashboard.
- Token expiry check compared an offset-aware datetime.now(timezone.utc)
  against an offset-naive value from DuckDB, raising TypeError on every
  valid link. Normalize the stored timestamp to UTC before subtracting.

Dev-only fallback (scoped strictly to LOCAL_DEV_MODE to keep test and
production behavior identical): send-link logs the magic link to stderr
and returns it as dev_link in the JSON response when no SMTP is configured.

Usage:
  ./scripts/run-local-dev.sh
  open http://localhost:8000  # lands on /dashboard as admin

* fix(dev): URL-encode magic-link email + avoid /login redirect loop

Two issues surfaced by Devin review on PR #32.

1. _build_magic_link interpolated email into the URL unescaped. For addresses
   with '+' (e.g. user+tag@gmail.com) Starlette's query parser decoded '+'
   as a space on the GET /verify side, so repo.get_by_email returned None
   and every click yielded 401 "Invalid link". quote(email, safe='') fixes
   both the email transport and the dev_link fallback.

2. /login in LOCAL_DEV_MODE unconditionally redirected to /dashboard. If
   dev-user seeding failed at startup (main.py wraps seed in try/except),
   /dashboard 401'd, the HTML redirect handler bounced to /login, and the
   loop repeated until the browser aborted. Now /login checks the dev user
   actually exists before short-circuiting; otherwise it falls through to
   the normal login form so the missing seed is visible.
2026-04-22 14:47:33 +02:00
..
grpn User management + PAT + CLI distribution + HTML auth redirect (#9 #10 #11 #12) (#28) 2026-04-22 14:24:28 +02:00
bootstrap-gcp.sh fix(bootstrap): grant monitoring.editor + enable monitoring API 2026-04-21 20:32:50 +02:00
duckdb_manager.py docs: update references to deleted files 2026-04-09 17:15:19 +02:00
fetch-env-from-secrets.sh infra: add fetch-env-from-secrets.sh for VM-side .env generation 2026-04-21 16:18:35 +02:00
generate_openapi.py feat: multi-instance deployment — all 14 must-have items from spec 2026-04-10 11:57:42 +02:00
generate_sample_data.py refactor: delete old sync pipeline — 9,500 lines removed 2026-03-31 07:50:37 +02:00
init.sh refactor: final cleanup — delete legacy auth, clean deps, fix hash, migrate to uv 2026-03-31 19:18:30 +02:00
migrate_json_to_duckdb.py feat: add JSON to DuckDB migration script with tests 2026-03-27 15:09:06 +01:00
migrate_metrics_to_duckdb.py feat: add standalone metric YAML → DuckDB migration script 2026-04-10 19:35:36 +02:00
migrate_parquets_to_extracts.py feat: add migration scripts for extract.duckdb transition 2026-03-30 20:21:12 +02:00
migrate_registry_to_duckdb.py feat: add migration scripts for extract.duckdb transition 2026-03-30 20:21:12 +02:00
README.md fix: rewrite Makefile and scripts/README.md 2026-04-09 17:16:04 +02:00
run-local-dev.sh feat(dev): LOCAL_DEV_MODE for one-command local dev + magic-link fixes (#32) 2026-04-22 14:47:33 +02:00
smoke-test.sh fix: address Devin review round 4 — bash arithmetic, CalVer max, docs 2026-04-10 14:39:16 +02:00
switch-dev-vm.sh chore: add switch-dev-vm.sh helper for hackathon (#20) 2026-04-21 21:33:02 +02:00

Scripts

Utility and migration scripts for Agnes AI Data Analyst.

Active Scripts

Script Purpose
generate_sample_data.py Generate sample data for development/demo
duckdb_manager.py DuckDB database management utilities
init.sh Initial server setup (install deps, create dirs)

Migration Scripts (one-time use)

Script Purpose
migrate_json_to_duckdb.py Migrate v1 JSON state files to DuckDB
migrate_parquets_to_extracts.py Migrate v1 parquet layout to extract.duckdb
migrate_registry_to_duckdb.py Migrate v1 table registry to DuckDB