diff --git a/docker-compose.yml b/docker-compose.yml index e62e3c90c..c078ccfcd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -289,17 +289,12 @@ services: - grafana-data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning:ro - ./grafana/dashboards:/var/lib/grafana/dashboards:ro - # The app's SQLite DB, for the maintainer dashboards (PR/review tables via the frser-sqlite-datasource). - # Mounted read-WRITE — not :ro — on purpose: SQLite WAL mode needs to write the -shm index to read live - # committed rows; a read-only mount would fail to open or miss recent writes. The datasource only ever - # runs SELECTs (provisioned dashboards, editable:false), so the app DB is never mutated from here. - - gittensory-data:/appdb environment: GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?Set GRAFANA_ADMIN_PASSWORD in .env before using --profile observability} GF_USERS_ALLOW_SIGN_UP: "false" - # Maintainer dashboards read the app DB through this SQLite plugin (table/stat panels); the GitHub - # data source (official, signed) queries the live GitHub API for the accurate upstream PR/issue census. - GF_INSTALL_PLUGINS: frser-sqlite-datasource,grafana-github-datasource + # Only install the signed GitHub datasource plugin. Do not mount or query the live app SQLite + # database from Grafana; observability must not bypass application authorization. + GF_INSTALL_PLUGINS: grafana-github-datasource # Read-only fine-grained PAT for the GitHub data source provisioning ($GITHUB_TOKEN expansion). From .env. GITHUB_TOKEN: "${GITHUB_TOKEN:-}" diff --git a/grafana/dashboards/maintainer-reviews.json b/grafana/dashboards/maintainer-reviews.json index f33390a92..f85d83f55 100644 --- a/grafana/dashboards/maintainer-reviews.json +++ b/grafana/dashboards/maintainer-reviews.json @@ -1,550 +1,35 @@ { "uid": "gittensory-maintainer", - "title": "Gittensory — Reviews & PRs (maintainer)", - "tags": ["gittensory", "maintainer"], + "title": "Gittensory \u2014 Reviews & PRs (maintainer)", + "tags": [ + "gittensory", + "maintainer" + ], "timezone": "browser", "schemaVersion": 39, "version": 2, "refresh": "1m", - "time": { "from": "now-90d", "to": "now" }, + "time": { + "from": "now-90d", + "to": "now" + }, "templating": { - "list": [ - { - "name": "repo", - "label": "Repository", - "type": "query", - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "query": "SELECT DISTINCT repo_full_name FROM pull_requests ORDER BY 1", - "includeAll": true, - "multi": false, - "allValue": "__all__", - "current": { "text": "All", "value": "__all__" }, - "refresh": 2, - "sort": 1 - } - ] + "list": [] }, "panels": [ { - "id": 1, - "type": "row", - "title": "Fleet summary · $repo (counts reflect PRs gittensory has OBSERVED — not the full upstream census; see note below)", - "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 } - }, - - { - "id": 2, - "type": "stat", - "title": "Open PRs (observed)", - "gridPos": { "h": 4, "w": 4, "x": 0, "y": 1 }, - "fieldConfig": { - "defaults": { - "color": { "mode": "fixed", "fixedColor": "blue" }, - "unit": "short" - } - }, - "options": { - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "colorMode": "value", - "graphMode": "none" - }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "rawQueryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='open' AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "queryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='open' AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "timeColumns": [] - } - ] - }, - - { - "id": 3, - "type": "stat", - "title": "Merged (recorded)", - "description": "Merges gittensory witnessed via webhook — NOT the repo's all-time merged total. Needs the upstream reconcile to match GitHub.", - "gridPos": { "h": 4, "w": 4, "x": 4, "y": 1 }, - "fieldConfig": { - "defaults": { - "color": { "mode": "fixed", "fixedColor": "green" }, - "unit": "short" - } - }, - "options": { - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "colorMode": "value", - "graphMode": "none" - }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "rawQueryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.merged_at IS NOT NULL AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "queryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.merged_at IS NOT NULL AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "timeColumns": [] - } - ] - }, - - { - "id": 4, - "type": "stat", - "title": "Closed (recorded)", - "gridPos": { "h": 4, "w": 4, "x": 8, "y": 1 }, - "fieldConfig": { - "defaults": { - "color": { "mode": "fixed", "fixedColor": "red" }, - "unit": "short" - } - }, - "options": { - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "colorMode": "value", - "graphMode": "none" - }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "rawQueryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='closed' AND p.merged_at IS NULL AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "queryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='closed' AND p.merged_at IS NULL AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "timeColumns": [] - } - ] - }, - - { - "id": 5, - "type": "stat", - "title": "PRs reviewed", - "description": "Distinct PRs gittensory posted a review on — this IS accurate (it is gittensory's own activity).", - "gridPos": { "h": 4, "w": 4, "x": 12, "y": 1 }, - "fieldConfig": { - "defaults": { - "color": { "mode": "fixed", "fixedColor": "purple" }, - "unit": "short" - } - }, - "options": { - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "colorMode": "value", - "graphMode": "none" - }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "rawQueryText": "SELECT COUNT(DISTINCT target_key) AS value FROM audit_events WHERE event_type='github_app.pr_public_surface_published' AND ('$repo'='__all__' OR target_key LIKE '$repo' || '#%')", - "queryText": "SELECT COUNT(DISTINCT target_key) AS value FROM audit_events WHERE event_type='github_app.pr_public_surface_published' AND ('$repo'='__all__' OR target_key LIKE '$repo' || '#%')", - "timeColumns": [] - } - ] - }, - - { - "id": 6, - "type": "stat", - "title": "Open & awaiting review", - "gridPos": { "h": 4, "w": 4, "x": 16, "y": 1 }, - "fieldConfig": { - "defaults": { - "color": { "mode": "thresholds" }, - "unit": "short", - "thresholds": { - "mode": "absolute", - "steps": [ - { "color": "green", "value": null }, - { "color": "orange", "value": 1 } - ] - } - } - }, - "options": { - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "colorMode": "value", - "graphMode": "none" - }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "rawQueryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='open' AND ('$repo'='__all__' OR p.repo_full_name='$repo') AND NOT EXISTS (SELECT 1 FROM audit_events a WHERE a.event_type='github_app.pr_public_surface_published' AND a.target_key = p.repo_full_name || '#' || p.number)", - "queryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='open' AND ('$repo'='__all__' OR p.repo_full_name='$repo') AND NOT EXISTS (SELECT 1 FROM audit_events a WHERE a.event_type='github_app.pr_public_surface_published' AND a.target_key = p.repo_full_name || '#' || p.number)", - "timeColumns": [] - } - ] - }, - - { - "id": 7, - "type": "stat", - "title": "Open & blocked", - "gridPos": { "h": 4, "w": 4, "x": 20, "y": 1 }, - "fieldConfig": { - "defaults": { - "color": { "mode": "thresholds" }, - "unit": "short", - "thresholds": { - "mode": "absolute", - "steps": [ - { "color": "green", "value": null }, - { "color": "red", "value": 1 } - ] - } - } - }, - "options": { - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "colorMode": "value", - "graphMode": "none" - }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "rawQueryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='open' AND p.merge_blocked_reason IS NOT NULL AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "queryText": "SELECT COUNT(*) AS value FROM pull_requests p WHERE p.state='open' AND p.merge_blocked_reason IS NOT NULL AND ('$repo'='__all__' OR p.repo_full_name='$repo')", - "timeColumns": [] - } - ] - }, - - { - "id": 14, "type": "text", - "title": "", - "gridPos": { "h": 3, "w": 24, "x": 0, "y": 5 }, + "title": "Maintainer review dashboard disabled", + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 0 + }, "options": { "mode": "markdown", - "content": "> ⚠️ **Data source:** the *Reviewed PRs* counts/log and *Reviews posted* trend are gittensory's own activity and are **accurate**. The *Open / Merged / Closed* tiles count only PRs gittensory observed via webhooks — they do **not** mirror the full upstream GitHub census. → **For the accurate live census (open/merged/closed straight from the GitHub API) + open-PR triage, see the [Upstream PRs & issues (GitHub)](/d/gittensory-github) dashboard.**" + "content": "## Maintainer review dashboard disabled\n\nThis dashboard no longer queries the live Gittensory SQLite database from Grafana. Direct datasource access would bypass application authorization and expose private application tables. Use the application API or a separately redacted reporting database for maintainer review analytics." } - }, - - { - "id": 8, - "type": "row", - "title": "Per-repository breakdown (all repos)", - "gridPos": { "h": 1, "w": 24, "x": 0, "y": 8 } - }, - - { - "id": 9, - "type": "table", - "title": "Repositories", - "gridPos": { "h": 8, "w": 24, "x": 0, "y": 9 }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "options": { "showHeader": true, "cellHeight": "sm" }, - "fieldConfig": { - "defaults": { "custom": { "align": "auto", "filterable": true } }, - "overrides": [ - { - "matcher": { "id": "byName", "options": "Repository" }, - "properties": [ - { "id": "custom.width", "value": 280 }, - { - "id": "links", - "value": [ - { - "title": "Open repository on GitHub", - "url": "https://github.com/${__data.fields.Repository}", - "targetBlank": true - } - ] - } - ] - } - ] - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "timeColumns": [], - "rawQueryText": "SELECT p.repo_full_name AS \"Repository\", SUM(CASE WHEN p.state='open' THEN 1 ELSE 0 END) AS \"Open\", SUM(CASE WHEN p.merged_at IS NOT NULL THEN 1 ELSE 0 END) AS \"Merged\", SUM(CASE WHEN p.state='closed' AND p.merged_at IS NULL THEN 1 ELSE 0 END) AS \"Closed\", (SELECT COUNT(DISTINCT a.target_key) FROM audit_events a WHERE a.event_type='github_app.pr_public_surface_published' AND a.target_key LIKE p.repo_full_name || '#%') AS \"Reviewed\", SUM(CASE WHEN p.state='open' AND NOT EXISTS (SELECT 1 FROM audit_events a WHERE a.event_type='github_app.pr_public_surface_published' AND a.target_key = p.repo_full_name || '#' || p.number) THEN 1 ELSE 0 END) AS \"Awaiting\", SUM(CASE WHEN p.state='open' AND p.merge_blocked_reason IS NOT NULL THEN 1 ELSE 0 END) AS \"Blocked\" FROM pull_requests p GROUP BY p.repo_full_name ORDER BY \"Open\" DESC", - "queryText": "SELECT p.repo_full_name AS \"Repository\", SUM(CASE WHEN p.state='open' THEN 1 ELSE 0 END) AS \"Open\", SUM(CASE WHEN p.merged_at IS NOT NULL THEN 1 ELSE 0 END) AS \"Merged\", SUM(CASE WHEN p.state='closed' AND p.merged_at IS NULL THEN 1 ELSE 0 END) AS \"Closed\", (SELECT COUNT(DISTINCT a.target_key) FROM audit_events a WHERE a.event_type='github_app.pr_public_surface_published' AND a.target_key LIKE p.repo_full_name || '#%') AS \"Reviewed\", SUM(CASE WHEN p.state='open' AND NOT EXISTS (SELECT 1 FROM audit_events a WHERE a.event_type='github_app.pr_public_surface_published' AND a.target_key = p.repo_full_name || '#' || p.number) THEN 1 ELSE 0 END) AS \"Awaiting\", SUM(CASE WHEN p.state='open' AND p.merge_blocked_reason IS NOT NULL THEN 1 ELSE 0 END) AS \"Blocked\" FROM pull_requests p GROUP BY p.repo_full_name ORDER BY \"Open\" DESC", - "timeColumns": [] - } - ] - }, - - { - "id": 10, - "type": "row", - "title": "Reviewed PRs log · $repo", - "gridPos": { "h": 1, "w": 24, "x": 0, "y": 17 } - }, - - { - "id": 11, - "type": "table", - "title": "Reviewed pull requests", - "gridPos": { "h": 14, "w": 24, "x": 0, "y": 18 }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "options": { - "showHeader": true, - "cellHeight": "sm", - "sortBy": [{ "displayName": "Last reviewed", "desc": true }] - }, - "fieldConfig": { - "defaults": { "custom": { "align": "auto", "filterable": true } }, - "overrides": [ - { - "matcher": { "id": "byName", "options": "url" }, - "properties": [{ "id": "custom.hidden", "value": true }] - }, - { - "matcher": { "id": "byName", "options": "repo" }, - "properties": [{ "id": "custom.hidden", "value": true }] - }, - { - "matcher": { "id": "byName", "options": "PR" }, - "properties": [ - { "id": "custom.width", "value": 64 }, - { - "id": "links", - "value": [ - { - "title": "Open PR on GitHub", - "url": "${__data.fields.url}", - "targetBlank": true - } - ] - } - ] - }, - { - "matcher": { "id": "byName", "options": "Repo" }, - "properties": [ - { "id": "custom.width", "value": 130 }, - { - "id": "links", - "value": [ - { - "title": "Open repository on GitHub", - "url": "https://github.com/${__data.fields.repo}", - "targetBlank": true - } - ] - } - ] - }, - { - "matcher": { "id": "byName", "options": "Title" }, - "properties": [{ "id": "custom.width", "value": 360 }] - }, - { - "matcher": { "id": "byName", "options": "Author" }, - "properties": [ - { "id": "custom.width", "value": 130 }, - { - "id": "links", - "value": [ - { - "title": "Open author on GitHub", - "url": "https://github.com/${__data.fields.Author}", - "targetBlank": true - } - ] - } - ] - }, - { - "matcher": { "id": "byName", "options": "Closes" }, - "properties": [ - { "id": "custom.width", "value": 80 }, - { - "id": "links", - "value": [ - { - "title": "Open issue on GitHub", - "url": "https://github.com/${__data.fields.repo}/issues/${__data.fields.Closes}", - "targetBlank": true - } - ] - } - ] - }, - { - "matcher": { "id": "byName", "options": "Status" }, - "properties": [ - { "id": "custom.width", "value": 110 }, - { - "id": "custom.cellOptions", - "value": { "type": "color-background", "mode": "basic" } - }, - { - "id": "mappings", - "value": [ - { - "type": "value", - "options": { - "🟢 open": { "color": "blue", "index": 0 }, - "🟣 merged": { "color": "green", "index": 1 }, - "🔴 closed": { "color": "red", "index": 2 } - } - } - ] - } - ] - }, - { - "matcher": { "id": "byName", "options": "Outcome" }, - "properties": [ - { "id": "custom.width", "value": 90 }, - { "id": "custom.cellOptions", "value": { "type": "color-text" } }, - { - "id": "mappings", - "value": [ - { - "type": "value", - "options": { - "merged": { "color": "green", "index": 0 }, - "closed": { "color": "red", "index": 1 } - } - } - ] - } - ] - } - ] - }, - "targets": [ - { - "refId": "A", - "queryType": "table", - "timeColumns": ["Last reviewed"], - "rawQueryText": "SELECT p.number AS \"PR\", p.html_url AS \"url\", p.repo_full_name AS \"repo\", substr(p.repo_full_name, instr(p.repo_full_name,'/')+1) AS \"Repo\", p.title AS \"Title\", p.author_login AS \"Author\", CASE WHEN p.merged_at IS NOT NULL THEN '🟣 merged' WHEN p.state='closed' THEN '🔴 closed' ELSE '🟢 open' END AS \"Status\", COALESCE(o.decision,'—') AS \"Outcome\", TRIM(REPLACE(REPLACE(REPLACE(p.linked_issues_json,'[',''),']',''),'\"','')) AS \"Closes\", r.last_reviewed AS \"Last reviewed\" FROM pull_requests p JOIN (SELECT target_key, MAX(created_at) AS last_reviewed FROM audit_events WHERE event_type='github_app.pr_public_surface_published' GROUP BY target_key) r ON r.target_key = p.repo_full_name || '#' || p.number LEFT JOIN (SELECT target_id, decision FROM review_audit WHERE event_type='pr_outcome') o ON o.target_id = p.repo_full_name || '#' || p.number WHERE ('$repo'='__all__' OR p.repo_full_name='$repo') ORDER BY r.last_reviewed DESC LIMIT 300", - "queryText": "SELECT p.number AS \"PR\", p.html_url AS \"url\", p.repo_full_name AS \"repo\", substr(p.repo_full_name, instr(p.repo_full_name,'/')+1) AS \"Repo\", p.title AS \"Title\", p.author_login AS \"Author\", CASE WHEN p.merged_at IS NOT NULL THEN '🟣 merged' WHEN p.state='closed' THEN '🔴 closed' ELSE '🟢 open' END AS \"Status\", COALESCE(o.decision,'—') AS \"Outcome\", TRIM(REPLACE(REPLACE(REPLACE(p.linked_issues_json,'[',''),']',''),'\"','')) AS \"Closes\", r.last_reviewed AS \"Last reviewed\" FROM pull_requests p JOIN (SELECT target_key, MAX(created_at) AS last_reviewed FROM audit_events WHERE event_type='github_app.pr_public_surface_published' GROUP BY target_key) r ON r.target_key = p.repo_full_name || '#' || p.number LEFT JOIN (SELECT target_id, decision FROM review_audit WHERE event_type='pr_outcome') o ON o.target_id = p.repo_full_name || '#' || p.number WHERE ('$repo'='__all__' OR p.repo_full_name='$repo') ORDER BY r.last_reviewed DESC LIMIT 300" - } - ] - }, - - { - "id": 12, - "type": "timeseries", - "title": "Reviews posted per day · $repo", - "gridPos": { "h": 8, "w": 24, "x": 0, "y": 32 }, - "datasource": { - "type": "frser-sqlite-datasource", - "uid": "gittensory-db" - }, - "fieldConfig": { - "defaults": { - "custom": { "drawStyle": "bars", "fillOpacity": 60, "lineWidth": 1 }, - "color": { "mode": "fixed", "fixedColor": "purple" }, - "unit": "short" - }, - "overrides": [] - }, - "options": { - "legend": { "showLegend": false }, - "tooltip": { "mode": "single" } - }, - "targets": [ - { - "refId": "A", - "queryType": "time series", - "timeColumns": ["time"], - "rawQueryText": "SELECT strftime('%s', date(created_at)) AS time, COUNT(*) AS \"reviews posted\" FROM audit_events WHERE event_type='github_app.pr_public_surface_published' AND ('$repo'='__all__' OR target_key LIKE '$repo' || '#%') GROUP BY date(created_at) ORDER BY time", - "queryText": "SELECT strftime('%s', date(created_at)) AS time, COUNT(*) AS \"reviews posted\" FROM audit_events WHERE event_type='github_app.pr_public_surface_published' AND ('$repo'='__all__' OR target_key LIKE '$repo' || '#%') GROUP BY date(created_at) ORDER BY time" - } - ] - }, - - { - "id": 13, - "type": "timeseries", - "title": "Open-PR backlog per repo (Prometheus trend)", - "gridPos": { "h": 8, "w": 24, "x": 0, "y": 40 }, - "description": "Sampled from the gittensory_repo_prs gauges at each /metrics scrape — retains backlog history the point-in-time SQLite panels can't.", - "datasource": { "type": "prometheus", "uid": "prometheus" }, - "fieldConfig": { - "defaults": { - "custom": { - "drawStyle": "line", - "fillOpacity": 10, - "lineWidth": 2, - "showPoints": "never" - }, - "unit": "short" - }, - "overrides": [] - }, - "options": { - "legend": { - "showLegend": true, - "placement": "bottom", - "displayMode": "table", - "calcs": ["lastNotNull", "max"] - }, - "tooltip": { "mode": "multi" } - }, - "targets": [ - { - "refId": "A", - "datasource": { "type": "prometheus", "uid": "prometheus" }, - "expr": "gittensory_repo_prs{state=\"open\"}", - "legendFormat": "{{repo}}" - } - ] } ] } diff --git a/grafana/dashboards/resource-hub.json b/grafana/dashboards/resource-hub.json index 58172f3a0..20a6b96b0 100644 --- a/grafana/dashboards/resource-hub.json +++ b/grafana/dashboards/resource-hub.json @@ -47,7 +47,7 @@ "gridPos": { "h": 13, "w": 12, "x": 0, "y": 0 }, "options": { "mode": "markdown", - "content": "## 🧠 AI providers\n- **Claude Code / Codex** — subscription CLIs, the review brain. Health: app boot log `selfhost_ai_provider`.\n- **Ollama** — embeddings (`bge-m3`) for RAG · [API root](http://localhost:11434) · `docker exec gittensory-ollama-1 ollama list`\n\n## 🔎 Vector store (RAG)\n- **Qdrant** — [Dashboard](http://localhost:6333/dashboard) · [Collections API](http://localhost:6333/collections)\n- Embeddings indexed per repo; see the *RAG indexing* doc.\n\n## ⚙️ Engine / API\n- **gittensory app** — [/ ](http://localhost:8787/) · [/ready](http://localhost:8787/ready) · [/metrics](http://localhost:8787/metrics)\n- Internal jobs: `POST /v1/internal/jobs/rag-index` (bearer `INTERNAL_JOB_TOKEN`)\n\n## 💾 Data\n- **SQLite** (default) at `/data/gittensory.sqlite` — surfaced here via the *GittensoryDB* datasource.\n- **Postgres/pgvector** (optional `--profile postgres`).\n\n> Links assume the default published ports on the Docker host. If you run Grafana on a remote host, replace `localhost` with that host, and publish the service `ports:` you want to reach." + "content": "## 🧠 AI providers\n- **Claude Code / Codex** — subscription CLIs, the review brain. Health: app boot log `selfhost_ai_provider`.\n- **Ollama** — embeddings (`bge-m3`) for RAG · [API root](http://localhost:11434) · `docker exec gittensory-ollama-1 ollama list`\n\n## 🔎 Vector store (RAG)\n- **Qdrant** — [Dashboard](http://localhost:6333/dashboard) · [Collections API](http://localhost:6333/collections)\n- Embeddings indexed per repo; see the *RAG indexing* doc.\n\n## ⚙️ Engine / API\n- **gittensory app** — [/ ](http://localhost:8787/) · [/ready](http://localhost:8787/ready) · [/metrics](http://localhost:8787/metrics)\n- Internal jobs: `POST /v1/internal/jobs/rag-index` (bearer `INTERNAL_JOB_TOKEN`)\n\n## 💾 Data\n- **SQLite** (default) at `/data/gittensory.sqlite` — not mounted into Grafana; use an explicitly redacted reporting database for dashboard analytics.\n- **Postgres/pgvector** (optional `--profile postgres`).\n\n> Links assume the default published ports on the Docker host. If you run Grafana on a remote host, replace `localhost` with that host, and publish the service `ports:` you want to reach." } }, diff --git a/grafana/provisioning/datasources/sqlite.yml b/grafana/provisioning/datasources/sqlite.yml index 17347ca09..c3b9dc4fb 100644 --- a/grafana/provisioning/datasources/sqlite.yml +++ b/grafana/provisioning/datasources/sqlite.yml @@ -1,14 +1,5 @@ -# Maintainer-facing datasource: the app's SQLite DB (pull_requests / review_targets / review_audit), so the -# dashboards can show real PR/review rows — titles, links, authors, verdicts, per-repo counts — not just -# infra metrics. Read-only in practice (the plugin runs SELECTs); the DB volume is mounted at /appdb in compose. -# Only loaded when the frser-sqlite-datasource plugin is installed (GF_INSTALL_PLUGINS in the grafana service). +# Intentionally no SQLite datasource is provisioned. Grafana must not receive direct access to +# the live application database; dashboards should use Prometheus/GitHub or a separately redacted +# reporting database if one is added in the future. apiVersion: 1 -datasources: - - name: GittensoryDB - type: frser-sqlite-datasource - uid: gittensory-db - access: proxy - isDefault: false - editable: false - jsonData: - path: /appdb/gittensory.sqlite +datasources: []