Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# The repository owner reviews changes before they reach the protected main branch.
* @gopalmani
5 changes: 3 additions & 2 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Backend
on:
push: { paths: ['apps/api/**', 'evaluations/**', '.github/workflows/backend.yml'] }
pull_request: { paths: ['apps/api/**', 'evaluations/**', '.github/workflows/backend.yml'] }
push:
branches: [main]
pull_request: {}
jobs:
test:
runs-on: ubuntu-latest
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Frontend
on:
push: { paths: ['apps/web/**', '.github/workflows/frontend.yml'] }
pull_request: { paths: ['apps/web/**', '.github/workflows/frontend.yml'] }
push:
branches: [main]
pull_request: {}
jobs:
verify:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ The API validates question size, limits generated SQL length, rejects comments/m

## Render deployment

`render.yaml` defines the API, web app, and PostgreSQL database. Secrets and the browser API URL require dashboard entry. Follow [the exact Blueprint procedure](docs/deployment.md); this repository prepares deployment but has not deployed or connected a Render account.
`render.yaml` defines the API and web app. The application database is an external PostgreSQL service such as Supabase, supplied through the backend-only `DATABASE_URL` secret. Both services deploy after CI passes for every commit merged into `main`. Follow [the exact deployment procedure](docs/deployment.md); secrets and the browser API URL still require dashboard entry.

## Limitations and roadmap

Expand Down
22 changes: 18 additions & 4 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,25 @@ docker compose exec ollama ollama pull sqlcoder

Use the first generated value for `CONNECTION_ENCRYPTION_KEY` and the second for `AUTH_SIGNING_KEY`. Open web at `http://localhost:4028`, API docs at `http://localhost:8000/docs`, and check `/health` then `/ready`. Configure a provider for generation. BYOD databases must be publicly reachable PostgreSQL on port 5432 with SSL and a read-only role.

## Supabase application database

QueryMindAI uses PostgreSQL for its own encrypted connection records, schema snapshots, drafts, verified examples, query history, and audit events. This application database is separate from the customer databases connected through the UI.

Create a Supabase project, then open **Connect** in its dashboard. For a Render service, use the **Session pooler** connection string on port `5432`: it supports persistent application traffic over IPv4. Supabase direct connections are IPv6 by default and may require its paid IPv4 add-on, while transaction pooling on port `6543` has prepared-statement constraints. See [Supabase connection guidance](https://supabase.com/docs/guides/database/connecting-to-postgres).

Convert the URL prefix for the installed SQLAlchemy driver and require TLS:

```text
postgresql+psycopg2://postgres.PROJECT_REF:URL_ENCODED_PASSWORD@SESSION_POOLER_HOST:5432/postgres?sslmode=require
```

Enter the complete value only in Render's secret `DATABASE_URL` field. Never commit it, expose it through `NEXT_PUBLIC_*`, or paste it into an issue or pull request. If a password has been shared outside the secret manager, rotate it in **Supabase → Project Settings → Database** before deployment.

## Render Blueprint procedure

1. Push this repository to GitHub. In Render choose **New → Blueprint**, connect that repository, and select `render.yaml`.
2. Review creation of `querymind-postgres`, `querymind-api`, and `querymind-web`. Select paid plans where the Blueprint/free availability differs for your account or region.
3. Enter backend secrets in the non-synced fields: Groq `LLM_API_KEY`, a Fernet `CONNECTION_ENCRYPTION_KEY`, and an independent random `AUTH_SIGNING_KEY`. Never reuse or commit these values.
2. Review creation or update of `querymind-api` and `querymind-web`. The Blueprint intentionally does not provision a Render PostgreSQL database.
3. Enter backend secrets in the non-synced fields: Supabase session-pooler `DATABASE_URL`, Groq `LLM_API_KEY`, a Fernet `CONNECTION_ENCRYPTION_KEY`, and an independent random `AUTH_SIGNING_KEY`. Never reuse or commit these values.
4. Set `CORS_ALLOW_ORIGINS` on the API to the final HTTPS web origin, without a trailing slash.
5. Deploy the API. On the free tier, the API start command runs `alembic upgrade head` before starting Uvicorn because Render does not support pre-deploy commands for free services. Confirm `https://<api-host>/health` and `/ready`.
6. Set `NEXT_PUBLIC_API_URL` on `querymind-web` to `https://<api-host>/api/v1`, then trigger a clean frontend deploy. Render does not provide a supported Blueprint interpolation from another web service’s eventual public hostname into a Next.js build variable; this manual build-time step is required.
Expand All @@ -28,9 +42,9 @@ Use the first generated value for `CONNECTION_ENCRYPTION_KEY` and the second for

The Blueprint keeps local embedding features disabled because the standard API build omits the large SentenceTransformer runtime. To enable them, change the API build command to `pip install -r requirements-embeddings.txt`, provision adequate memory, then set the feature flags true. Groq announced free/developer-tier retirement of `llama-3.3-70b-versatile` for August 16, 2026; replace `LLM_FALLBACK_MODEL` before that date if the deployment is affected.

Build filters deploy the API for backend/shared deployment changes and the web for frontend/shared deployment changes. `render.yaml` contains no real API keys. This repository has been prepared and syntax-checked locally; no Render account or live deployment has been connected by this work.
Both services use repository-root commands and intentionally omit build filters. Every commit merged into the linked `main` branch runs both GitHub Actions workflows; Render waits for checks to pass, then deploys both the API and web service. Confirm the Blueprint is linked to `main` and **Auto Sync** is enabled. `render.yaml` contains no database password or API key.

A merge to `main` does not unconditionally rebuild both services. Render evaluates each service's `buildFilter`: changes under `apps/web/**` deploy the web service, changes under `apps/api/**` deploy the API, changes touching both deploy both, and shared files listed in both filters (such as `render.yaml`) trigger both. This avoids unnecessary backend deploys for UI-only pull requests.
Removing the old `querymind-postgres` resource from the Blueprint does not migrate its data. The suspended database must be deleted separately in Render after confirming Supabase migrations and API readiness. Existing metadata is lost unless it is exported from Render and imported into Supabase first.

## Customer read-only PostgreSQL role

Expand Down
26 changes: 7 additions & 19 deletions render.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
databases:
- name: querymind-postgres
plan: free
databaseName: querymind
user: querymind

services:
- type: web
name: querymind-api
plan: free
runtime: python
rootDir: apps/api
buildCommand: pip install -r requirements.txt
startCommand: alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port $PORT
buildCommand: pip install -r apps/api/requirements.txt
startCommand: cd apps/api && alembic upgrade head && uvicorn app.main:app --host 0.0.0.0 --port $PORT
healthCheckPath: /health
autoDeployTrigger: commit
buildFilter:
paths: [apps/api/**, render.yaml, docker-compose.yml, .env.example]
autoDeployTrigger: checksPass
envVars:
- key: PYTHON_VERSION
value: 3.12.10
- key: DATABASE_URL
fromDatabase: { name: querymind-postgres, property: connectionString }
sync: false
- key: APP_ENV
value: production
- key: ENABLE_EXTERNAL_CONNECTIONS
Expand Down Expand Up @@ -67,12 +58,9 @@ services:
name: querymind-web
plan: free
runtime: node
rootDir: apps/web
buildCommand: npm ci && npm run build
startCommand: npm run start -- -p $PORT
autoDeployTrigger: commit
buildFilter:
paths: [apps/web/**, render.yaml, .env.example]
buildCommand: cd apps/web && npm ci && npm run build
startCommand: cd apps/web && npm run start -- -p $PORT
autoDeployTrigger: checksPass
envVars:
- key: NODE_VERSION
value: 20.19.5
Expand Down
Loading