Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
8cae9bf
refactor: modularize database models and introduce workspace support …
Entropy-rgb Jul 20, 2026
4b9a5b7
refactor: modularize database models and introduce workspace support …
Entropy-rgb Jul 20, 2026
3a381e5
Merge branch 'Feat/workspaces' of https://github.com/BoloDB/bolodb in…
Entropy-rgb Jul 22, 2026
dfc5768
feat: complete workspace UI and finalize backend scoping
Entropy-rgb Jul 22, 2026
5bb7058
Fix broken tests related to workspace migration
Entropy-rgb Jul 22, 2026
5e06b43
"Fix broken tests related to workspace migration"
Entropy-rgb Jul 22, 2026
e7bc485
Fix 500 error on /workspaces by using ORM User model instead of Pydan…
Entropy-rgb Jul 22, 2026
3204976
fix: docker for deploy using standard procedures
Entropy-rgb Jul 22, 2026
9e1ae87
fix: remove docker container name to allow preview apps , so that the…
Entropy-rgb Jul 22, 2026
dac4f3f
feat: add first_name, last_name, avatar_url to user models
Entropy-rgb Jul 22, 2026
6642be2
feat: add alias_name to connection model and API
Entropy-rgb Jul 22, 2026
02e1baf
feat: add profile update endpoint (PATCH /api/auth/me)
Entropy-rgb Jul 22, 2026
31a1423
feat: refactor DatabaseManager for multi-database support with db_id
Entropy-rgb Jul 22, 2026
b3b875c
feat: add db_id parameter to backend controllers
Entropy-rgb Jul 22, 2026
d3b6aff
feat: add x-db-id header dependency and wire into routes
Entropy-rgb Jul 22, 2026
321ad3f
feat: add workspace update API
Entropy-rgb Jul 22, 2026
c71e03c
fix: remove automatic default workspace creation on signup
Entropy-rgb Jul 22, 2026
66013ab
chore: rename alembic migration revision with extended schema
Entropy-rgb Jul 22, 2026
42282d0
chore: remove fix_tests.py utility script
Entropy-rgb Jul 22, 2026
961781d
feat: add updateProfile, updateWorkspace, updateConnectionAlias API f…
Entropy-rgb Jul 22, 2026
350076e
feat: redesign connect screen with workspace-aware split layout
Entropy-rgb Jul 22, 2026
f88844c
feat: add workspace rail and workspace switching to sidebar
Entropy-rgb Jul 22, 2026
96a4735
feat: redesign profile page to account settings layout
Entropy-rgb Jul 22, 2026
85183dc
feat: add workspace-aware redirect logic
Entropy-rgb Jul 22, 2026
350b534
feat: update connect page and layout for workspace setup
Entropy-rgb Jul 22, 2026
086f5d2
feat: add workspace setup wizard and update workspaces page
Entropy-rgb Jul 22, 2026
3b776bd
fix: correct workspace_id/user_id bug in query history and serialization
Entropy-rgb Jul 22, 2026
fd3934d
fix: add _db_get_schema/_db_get_dialect/_db_execute helpers for db_id…
Entropy-rgb Jul 22, 2026
302e99a
feat: add role constraints and owner protection to workspace models a…
Entropy-rgb Jul 22, 2026
ec42955
fix(backend): resolve code review issues, handle workspace race condi…
Entropy-rgb Jul 22, 2026
0b13c81
fix(database): add db_id parameter to DatabaseManager.get_schema
Entropy-rgb Jul 22, 2026
fbf1585
chore: add venv to .gitignore
Entropy-rgb Jul 22, 2026
be0017d
feat: add activity log model, controller, and alembic migration
Entropy-rgb Jul 22, 2026
8f16529
feat: wire activity logging into workspace and database routes
Entropy-rgb Jul 22, 2026
3877bb4
feat: add activity log frontend component and API
Entropy-rgb Jul 22, 2026
366b600
chore: add .opencode/ to .gitignore
Entropy-rgb Jul 22, 2026
4cfb62a
feat: add SavedQuery and Dashboard ORM models
Entropy-rgb Jul 22, 2026
5b711e4
feat: add async database access layer for saved queries and dashboards
Entropy-rgb Jul 22, 2026
ec98a61
feat: add dashboard controller with concurrent query execution
Entropy-rgb Jul 22, 2026
5fb28ff
feat: add /api/saved-queries and /api/dashboards endpoints
Entropy-rgb Jul 22, 2026
e3d17db
fix: protect catalog save/suggest endpoints with admin role
Entropy-rgb Jul 22, 2026
0d11dec
chore: add echarts and svelte-echarts dependencies
Entropy-rgb Jul 22, 2026
c6e6394
feat: add ChartPanel and SaveQueryDialog components
Entropy-rgb Jul 22, 2026
fde1c5d
feat: add 'Save to Dashboard' button to AnswerCard
Entropy-rgb Jul 22, 2026
e5be22d
feat: add DashboardEditor component and dashboard route pages
Entropy-rgb Jul 22, 2026
45987bc
feat: add database switcher dropdown to AskScreen
Entropy-rgb Jul 22, 2026
9383c9c
feat: add admin-only actions to SettingsTab
Entropy-rgb Jul 22, 2026
894c462
refactor: remove onboard page and redirect verify-email to appState.init
Entropy-rgb Jul 22, 2026
a8bac05
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 22, 2026
7ed16ed
chore: remove deprecated OnboardScreen component
Entropy-rgb Jul 22, 2026
faa3916
feat: scope active db_id per workspace in localStorage
Entropy-rgb Jul 22, 2026
c753aff
feat: redesign SaveQueryDialog with custom CSS
Entropy-rgb Jul 22, 2026
97cc289
feat: restrict DataCatalog editing to admin/owner roles
Entropy-rgb Jul 22, 2026
9f2a25e
feat: add database-switching loading state to AskScreen
Entropy-rgb Jul 22, 2026
dcc16a2
feat: enhance Sidebar with loading state, DB tags, and dashboard nav
Entropy-rgb Jul 22, 2026
b46d9c6
fix: refactor ConnectScreen onMount and use connected_at time
Entropy-rgb Jul 22, 2026
cc1b517
fix: correct apiCall argument order and use activeWorkspace.role in d…
Entropy-rgb Jul 22, 2026
ac2d615
fix: correct apiCall argument order and use activeWorkspace.role in d…
Entropy-rgb Jul 22, 2026
cd4e0ad
chore: add migration script for per-workspace db_id scoping
Entropy-rgb Jul 22, 2026
802acf1
fix package-lock.json bug for deploy
Entropy-rgb Jul 22, 2026
9a7d4eb
bug fixes
Entropy-rgb Jul 22, 2026
bcc7245
fix docker-compose for server deploy
Entropy-rgb Jul 23, 2026
da59800
infrastructure: production Docker setup with static frontend in nginx
Entropy-rgb Jul 23, 2026
16d415f
backend: improve database serialization and fix schema migration
Entropy-rgb Jul 23, 2026
b67a035
backend: remove JWT_SECRET fallback for connection encryption
Entropy-rgb Jul 23, 2026
41220ff
backend: workspace API fixes and role-based permission hardening
Entropy-rgb Jul 23, 2026
8be59cb
backend: fix dashboard query execution with UUID key normalization
Entropy-rgb Jul 23, 2026
c1072d5
chore: remove deprecated scripts and test files
Entropy-rgb Jul 23, 2026
2e9d6e3
frontend: redesign dashboard pages (list, view, edit)
Entropy-rgb Jul 23, 2026
1fef68d
frontend: redesign dashboard components (ChartPanel, Editor, Settings…
Entropy-rgb Jul 23, 2026
e9fc1a1
frontend: profile page redesign, layout navbar fix, CSS variable addi…
Entropy-rgb Jul 23, 2026
d5ac5ea
frontend: redesign workspace list page
Entropy-rgb Jul 23, 2026
3edab55
fix dockerfile
Entropy-rgb Jul 23, 2026
f9945a4
fix docker compose
Entropy-rgb Jul 23, 2026
57f1c52
stop llm language hallucination
Entropy-rgb Jul 23, 2026
92bda3b
fix: Unclickable Database Change Button in Chat
Entropy-rgb Jul 23, 2026
bcae25c
chore: remove unnecessary connect screen switch label
Entropy-rgb Jul 23, 2026
f396bcd
chore: remove unnecessary labels
Entropy-rgb Jul 23, 2026
a0c82f3
feat: add delete feature to dashboards
Entropy-rgb Jul 23, 2026
4288421
fix askscreen bug
Entropy-rgb Jul 23, 2026
8e18dbd
change to use port 8080 to avoid colliding with coolify
Entropy-rgb Jul 23, 2026
3bc074c
fix ports in docker compose
Entropy-rgb Jul 23, 2026
296e6aa
handle proxy to coolify
Entropy-rgb Jul 23, 2026
0bb7558
add explicit traefik mention
Entropy-rgb Jul 23, 2026
04f028e
backend: LLM chart output, connection encryption, invite codes, activ…
Entropy-rgb Jul 23, 2026
cadc076
frontend: chart types, CSV download, switchingDatabase state, chart e…
Entropy-rgb Jul 23, 2026
b670bae
frontend: refactor components with AppShell, activity export, chart-a…
Entropy-rgb Jul 23, 2026
419434a
backend: workspace lifecycle, invite management, and activity-log pru…
Entropy-rgb Jul 23, 2026
37bdf6e
frontend: workspace management UI, invite infrastructure, and shared …
Entropy-rgb Jul 23, 2026
9717ebc
dashboard refresh and chart column inference, SQL rerun, and query im…
Entropy-rgb Jul 23, 2026
5cfb7fb
address greptile's findings
Entropy-rgb Jul 23, 2026
b999e5a
address @coderabbit's findings
Entropy-rgb Jul 23, 2026
0316416
feat(backend): implement workspace settings model, permissions regist…
Entropy-rgb Jul 23, 2026
a855ee1
feat(routes): migrate route permission dependencies & add workspace s…
Entropy-rgb Jul 23, 2026
e60f688
feat(frontend & tests): add Permissions matrix tab, Defaults UI, and …
Entropy-rgb Jul 23, 2026
051d629
feat(sample-data): replace TechStore sample with the PostgreSQL websh…
Entropy-rgb Jul 23, 2026
97aae13
fix(connections): restore a workspace's database from its stored cred…
Entropy-rgb Jul 23, 2026
8a4deac
fix(query): scope knowledge, execution and logging to the selected da…
Entropy-rgb Jul 23, 2026
28e5bb8
fix(frontend): share databases and conversations across routes, fix c…
Entropy-rgb Jul 23, 2026
bceade5
feat(charts): draw answer-card charts with ECharts, on a colour-visio…
Entropy-rgb Jul 23, 2026
c08aab4
fix(workspaces): repair invites, rank-order permissions, migrate on d…
Entropy-rgb Jul 23, 2026
e3c0876
refactor(state): make the backend stateless — no local ~/.bolodb, key…
Entropy-rgb Jul 24, 2026
cd96deb
fix(connections): rebuild the sample database when its connection is …
Entropy-rgb Jul 24, 2026
32a513d
ci: pin ruff and its rule set so linting doesn't drift with releases
Entropy-rgb Jul 24, 2026
73c8d0f
fix: Panel accepting foreign queries
Entropy-rgb Jul 24, 2026
58905b2
fix: stop accepting foreign queries
Entropy-rgb Jul 24, 2026
4633a9b
Apply suggestions from code review by strix
Entropy-rgb Jul 24, 2026
f4a685b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 24, 2026
e73c13b
fix: address PR review findings (RBAC, db scoping, migrations, UI)
Entropy-rgb Jul 24, 2026
f1c46fe
fix: chat topbar dropdown used to show databases was gated by connect…
Entropy-rgb Jul 24, 2026
4cf03b9
three fixes applied:
Entropy-rgb Jul 24, 2026
34af0de
fix: Retention setting was being ignored and the global setting was b…
Entropy-rgb Jul 24, 2026
30fc4a7
fix: solve the typeError in name input field
Entropy-rgb Jul 24, 2026
53bfee9
feat: make conversations workspace + user scoped , rather than them b…
Entropy-rgb Jul 24, 2026
bb3d0e8
fix: address feedback api issues
Entropy-rgb Jul 24, 2026
c65e71c
docs: update architecture documentation and file map for BoloDB v2
Entropy-rgb Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ FRONTEND_URL=
PUBLIC_POSTHOG_PROJECT_TOKEN=
PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

# ── Connection encryption (advanced) ──
# Encryption key for storing database connection strings at rest.
# If unset, a key is auto-generated and stored in ~/.bolodb/.secret.
# RECENT_CONNECTIONS_MASTER_KEY= # Master key for key rotation (encrypts the key file)
# RECENT_CONNECTIONS_KEY= # Direct encryption key (alternative to master key)
# ── Connection encryption (required for storing DB URLs at rest) ──
# Encrypts saved connection URLs. REQUIRED — the app will not start without it,
# and saved connections cannot be stored or reopened until it is set. It is read
# only from the environment (never written to disk), so keep it stable across
# deploys: change it and previously saved connections must be re-added.
# Generate with: python -c "import secrets; print(secrets.token_urlsafe(48))"
RECENT_CONNECTIONS_KEY=

# ── Server (advanced) ──
# Set to "true" when behind HTTPS termination (nginx with SSL)
Expand All @@ -42,3 +44,9 @@ SKIP_DB_LOCK=false
# CORS_ORIGINS=
# Set automatically in Docker; controls SQLite path selection
# RUNNING_IN_DOCKER=true

# ── Maintenance & Storage ──
ACTIVITY_LOG_RETENTION_DAYS=30
ACTIVITY_CLEANUP_ENABLED=true
ACTIVITY_CLEANUP_INTERVAL_HOURS=24
BOLODB_DATA_DIR=
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff
# Pin to match .pre-commit-config.yaml so CI and local hooks lint
# identically; an unpinned install pulls whatever ruff released last,
# whose changing defaults have broken CI before.
pip install ruff==0.15.22
pip install -r backend/requirements.txt

- name: Lint with Ruff
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ credentials.json
*.key
.credentials
docker-compose.override.yml
venv/

.opencode/
.agents/
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ BoloDB is built using a modern containerized stack designed for ease of local de
- **Backend:** FastAPI (Python 3.10+) utilizing SQLAlchemy for database connectivity, and `sqlglot` for secure AST-based read-only validation.
- **Frontend:** A SvelteKit application utilizing TypeScript and Tailwind CSS for a polished, responsive user interface.
- **Database:** PostgreSQL container storing user accounts, query history, conversations, and recent connections.
- **Knowledge Base:** Per-user SQLite database storing verified queries, glossary, and trust level.
- **Knowledge Base:** PostgreSQL persistence storing verified queries, glossary, and trust level.
- **Reverse Proxy:** Nginx configured to route traffic seamlessly between the frontend and backend services while handling proxy configurations.
- **LLM Connectors:** Support for OpenRouter API.

Expand Down
9 changes: 7 additions & 2 deletions DOCKERFILE.render
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,14 @@ COPY --from=frontend-builder /app/build /usr/share/nginx/html
COPY nginx.conf.render /etc/nginx/conf.d/default.conf

RUN addgroup --system bolodb && adduser --system --home /home/bolodb --ingroup bolodb bolodb \
&& mkdir -p /home/bolodb/.bolodb \
&& chown -R bolodb:bolodb /home/bolodb/.bolodb /app
&& mkdir -p /app/data \
&& chmod +x /app/backend/docker-entrypoint.sh \
&& chown -R bolodb:bolodb /app

EXPOSE 80

# Same as the compose image: migrate to head before serving, so pointing
# DATABASE_URL at a new database needs no manual step.
ENTRYPOINT ["/app/backend/docker-entrypoint.sh"]

CMD sh -c "nginx -g 'daemon off;' & exec python -m uvicorn backend.app.server:create_app --factory --host 0.0.0.0 --port 4321 --log-level info"
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2026 HAAHIT
Copyright (c) 2026 BoloDB

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
132 changes: 64 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,102 +4,98 @@

**Ask your data. Trust the answer.**

A text-to-SQL product for non-technical users. Connect any SQL database, ask
questions in plain English, get answers with a plain-English explanation and a
confidence level. Every answer you confirm teaches it your database — accuracy
improves with use.
A multi-tenant text-to-SQL web application for non-technical users and teams. Connect your database, ask questions in plain English, and get instant answers with plain-English restatements, ECharts visualizations, and confidence levels. Save queries to interactive dashboards and manage multi-user workspaces with role-based access control (RBAC).

**📚 Full documentation lives in [`docs/`](docs/README.md)** — written for
non-technical readers, with code pointers for developers at every step.
**📚 Full documentation lives in [`docs/`](docs/README.md)** — written for non-technical readers, with code pointers for developers at every step.

---

## Quick Start (Docker)

The easiest and recommended way to run BoloDB is using Docker. This ensures all services (FastAPI Backend, SvelteKit Frontend, Nginx, and MongoDB) run seamlessly.
The easiest and recommended way to run BoloDB is using Docker Compose (FastAPI backend + SvelteKit frontend + Nginx + PostgreSQL).

1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) or Docker Engine.
2. Clone the repository and navigate into the root directory.
3. Copy `.env.example` to `.env` and fill in required secrets (`OPENROUTER_API_KEY`, `JWT_SECRET`, `DATABASE_URL`, `RECENT_CONNECTIONS_KEY`, `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `SUPABASE_JWT_SECRET`).
4. Start the application stack:

1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) (Windows/Mac) or Docker Engine (Linux).
2. Open a terminal in the project directory.
3. Start the application:
**Production / Deployment**:
```bash
docker compose up -d
docker compose up --build -d
```
4. Open [http://localhost:5173](http://localhost:5173) in your browser.
5. Set the `OPENROUTER_API_KEY` environment variable in your docker-compose or `.env` file, connect a database (or click "Try with sample data"), and start asking!
Open [http://localhost:8080](http://localhost:8080).

## The AI engine
**Local Development (Vite HMR)**:
```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
```
Open [http://localhost:8080](http://localhost:8080) (Nginx proxy) or [http://localhost:5174](http://localhost:5174) (Vite frontend).

BoloDB uses **OpenRouter** (specifically the `deepseek/deepseek-v4-flash` model) for all AI operations. You only need one thing:
an OpenRouter API key.
---

1. Go to https://openrouter.ai/keys.
2. Click **Create Key** and copy it.
3. Set it as the `OPENROUTER_API_KEY` environment variable for your deployment.
## Key Features

| Model | Best for |
|---|---|
| `deepseek/deepseek-v4-flash` (default) | Best cost/accuracy balance for most uses |
- **Multi-Tenant Workspaces & RBAC**: Isolate connections, dashboards, and knowledge bases per workspace. Assign Owner, Admin, or Member roles with fine-grained capability checks.
- **OpenRouter AI Engine**: Powered by `deepseek/deepseek-v4-flash` via OpenRouter.
- **Interactive Dashboards & Charts**: Automated ECharts visual inference (Bar, Line, Area, Pie, Number, Table) with query panel customization.
- **Semantic Layer**: Define custom business metrics, explicit join paths, synonyms, and value mappings to guide AI SQL generation.
- **Safety & Defense in Depth**: Read-only AST validation, SSRF protection, host allowlisting, and 5s statement timeouts.
- **PostgreSQL Persistence**: All state (users, workspaces, connections encrypted at rest, query history, dashboards, verified Q&A) is persisted asynchronously in PostgreSQL.

**Privacy:** what's sent to the AI to generate SQL is your question plus the
context BoloDB builds around it: the database *structure* (table/column names,
keys), a few sample values and sample rows per table, your confirmed
business-term glossary, previously verified question→SQL examples, and the
last couple of conversation turns. **The prompt never includes** bulk table
contents, query results, or credentials — the OpenRouter API key travels only in
the request's authentication header. See
[docs/03-the-ai-layer-openrouter.md](docs/03-the-ai-layer-openrouter.md) for exactly
what's in every prompt.
---

## Database connection strings
## Supported Database Connections

| Database | Format |
| Database | Connection URL Format |
|---|---|
| SQLite | `sqlite:///C:/path/to/file.db` |
| PostgreSQL | `postgresql://user:pass@host:5432/dbname` |
| MySQL | `mysql+pymysql://user:pass@host:3306/dbname` |
| SQLite | `sqlite:///C:/path/to/file.db` |
| SQL Server | `mssql+pyodbc://user:pass@server/db?driver=ODBC+Driver+17+for+SQL+Server` |
| DuckDB | `duckdb:///path/to/file.duckdb` |

---

## Architecture & Code Map

Full file and directory index is available in [`docs/07-file-map.md`](docs/07-file-map.md).

```text
Browser (SvelteKit 5 Frontend, frontend/src)
│ HTTP / SSE streaming (JWT cookie auth, X-Workspace-Id and X-Db-Id headers)
FastAPI Backend (backend/app)
├── controllers/query.py ─── The query pipeline (knowledge → schema link → LLM → repair)
├── llm.py ───────────────── OpenRouter provider (deepseek/deepseek-v4-flash)
├── schema_link.py ───────── Schema linking, budget management & table scoring
├── sqlvalidate.py ───────── AST static SQL validation
├── repair.py ────────────── Self-repair loop for auto-correcting broken SQL
├── semantic.py ──────────── Semantic layer catalog & inference
├── database.py ──────────── DB introspection & read-only execution guard
└── pgdatabase/ ──────────── Async PostgreSQL persistence (KnowledgeService, Users, Workspaces, Dashboards)
```

Tip: connect with a **read-only database account** for safety (BoloDB also
enforces read-only itself — see
[docs/05-safety-validation-and-self-repair.md](docs/05-safety-validation-and-self-repair.md)).

## How it works

1. **Connect** a database and ensure your OpenRouter API key is set in the environment.
2. **Onboard** (first time) — BoloDB profiles the tables, confirms business-term meanings with you, and runs a few starter questions for you to verify
3. **Ask** questions in plain English. Every answer includes:
- A plain-English restatement ("I summed completed orders for this month")
- A confidence level (High/Medium/Low) based on real signals
- The results table and SQL on a toggle
- Automatic self-repair: generated SQL is validated against your schema and fixed before you ever see an error
4. **Verify** — click "Yes, correct" to save the answer. Similar future questions reuse it and show higher confidence. The trust level climbs from Supervised to Assisted to Trusted

The full pipeline, step by step with code pointers:
[docs/02-how-a-question-becomes-an-answer.md](docs/02-how-a-question-becomes-an-answer.md).
---

## Useful Docker Commands
## Running Unit Tests

```bash
docker compose up -d # Start the application in the background
docker compose logs -f # View live logs from all services
docker compose down # Stop all services
docker compose build --no-cache # Rebuild all images from scratch
pip install -r backend/requirements.txt
pytest tests -v
```

## Running tests
The test suite runs entirely offline using mock OpenRouter providers.

```bash
pip install -r backend/requirements.txt
pytest tests
```
---

The test suite needs no network and no API key — all AI calls are faked.
## Privacy & Security

## Privacy
- Connection credentials are **encrypted at rest** using Fernet symmetric encryption key (`RECENT_CONNECTIONS_KEY`).
- AI prompts include only database structure, compact column schemas, verified Q&A examples, and business glossary definitions. Bulk data rows, query results, and credentials are **never sent** to the AI model.
- All SQL execution runs in strict **read-only** mode with statement timeout protection.

- All learned knowledge and user settings are stored locally (`~/.bolodb/`) and in the local MongoDB container volume. The API key is read from the environment and never stored on disk.
- To generate SQL, the AI is sent your question plus context: the schema, a few sample values/rows per table, your confirmed glossary terms, verified question→SQL examples, and recent conversation turns. The prompt never includes bulk table data, query results, or credentials (the API key is used only as the request's authentication header).
- Queries run strictly read-only.
- No telemetry, no cloud sync.
---

## License

MIT — see [LICENSE](LICENSE).
MIT see [LICENSE](LICENSE).
11 changes: 9 additions & 2 deletions backend/DOCKERFILE
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ RUN pip install --no-cache-dir -r /app/backend/requirements.txt
COPY backend/ /app/backend/

# ── 3. Create non-root user ──
# /app/data holds the regenerable sample database; create it owned by the
# runtime user so it is writable whether or not a volume is mounted over it.
RUN addgroup --system bolodb && adduser --system --home /home/bolodb --ingroup bolodb bolodb \
&& mkdir -p /home/bolodb/.bolodb \
&& chown -R bolodb:bolodb /home/bolodb/.bolodb /app
&& mkdir -p /app/data \
&& chmod +x /app/backend/docker-entrypoint.sh \
&& chown -R bolodb:bolodb /app

USER bolodb

Expand All @@ -31,5 +34,9 @@ EXPOSE 4321
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD python -c "import httpx; httpx.get('http://localhost:4321/api/health', timeout=3).raise_for_status()" || exit 1

# Migrations run first, so a deploy pointed at a new or stale database brings
# the schema to head before the app serves its first request.
ENTRYPOINT ["/app/backend/docker-entrypoint.sh"]

CMD ["python", "-m", "uvicorn", "backend.app.server:create_app", \
"--factory", "--host", "0.0.0.0", "--port", "4321", "--log-level", "warning"]
14 changes: 14 additions & 0 deletions backend/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,23 @@ def run_migrations_offline() -> None:
context.run_migrations()


# Any 64-bit constant works; it only has to be the same in every process that
# migrates this database. Derived from the project name so it cannot collide
# with an advisory lock another application takes on a shared cluster.
_MIGRATION_LOCK_ID = 8410231166942030001


def do_run_migrations(connection):
context.configure(connection=connection, target_metadata=target_metadata)
with context.begin_transaction():
# Containers start migrations concurrently on a scaled deployment, and
# two Alembic runs against one database race on alembic_version. The
# transaction-scoped advisory lock makes the second wait for the first
# and then find nothing left to apply; it is released on commit or
# rollback, so a crashed migration cannot wedge later deploys.
connection.exec_driver_sql(
f"SELECT pg_advisory_xact_lock({_MIGRATION_LOCK_ID})"
)
context.run_migrations()


Expand Down
Loading
Loading