Skip to content
Open
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
51 changes: 44 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1071,12 +1071,6 @@ jobs:
- name: Setup Node and dependencies for drift manifest
uses: ./.github/actions/setup-node-cached

- name: Run Caring Contacts Database & RLS Tests
if: needs.changes.outputs.db_changed == 'true' || needs.changes.outputs.static_heavy_changed == 'true'
env:
CARING_CONTACTS_DATABASE_URL: postgres://postgres:postgres@127.0.0.1:54322/postgres
run: npm run caring-contacts:db:test

- name: Pull the pinned drift manifest image
run: docker pull supabase/postgres:17.6.1.127@sha256:be60aee15997daca475b710b734bc6bfe52cd544dcd7e9fd2ff58210b6747d83

Expand Down Expand Up @@ -1113,6 +1107,41 @@ jobs:
| sort -u \
| xargs -r docker save -o /tmp/supabase-docker-cache/images.tar

caring-contacts-db:
name: Caring Contacts database
needs: changes
if: >
(needs.changes.outputs.db_changed == 'true' ||
needs.changes.outputs.static_heavy_changed == 'true') &&
github.event.pull_request.draft != true
runs-on: ubuntu-24.04
timeout-minutes: 10
services:
postgres:
image: postgres:17@sha256:e38411452a464af89e5adadb8d223bf53b898d47d6ef918b2d58c08707350449
env:
POSTGRES_PASSWORD: postgres
ports:
- 54329:5432
options: >-
--health-cmd "pg_isready -U postgres -d postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 10
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup Node and dependencies
uses: ./.github/actions/setup-node-cached

- name: Run Caring Contacts Database & RLS Tests
env:
CARING_CONTACTS_DATABASE_URL: postgres://postgres:postgres@127.0.0.1:54329/postgres
run: npm run caring-contacts:db:test

pr-required:
name: PR required
needs:
Expand All @@ -1128,6 +1157,7 @@ jobs:
ui-critical,
lighthouse-budget,
db-reset-verify,
caring-contacts-db,
]
# #095: keep `if: always()` — a skipped required check counts as PASSING
# on GitHub, so `!cancelled()` would cancel-to-green a hand-cancelled tip.
Expand Down Expand Up @@ -1158,6 +1188,7 @@ jobs:
UI_RESULT: ${{ needs.ui-critical.result }}
LIGHTHOUSE_RESULT: ${{ needs.lighthouse-budget.result }}
DB_RESULT: ${{ needs.db-reset-verify.result }}
CARING_CONTACTS_DB_RESULT: ${{ needs.caring-contacts-db.result }}
run: |
set -euo pipefail

Expand Down Expand Up @@ -1219,7 +1250,7 @@ jobs:
require_success "changes" "$CHANGES_RESULT"
require_success "static-pr" "$STATIC_RESULT"

# safety/coverage/build/ui-critical*/db-reset-verify additionally skip on draft PRs
# safety/coverage/build/ui-critical*/db-reset-verify/caring-contacts-db additionally skip on draft PRs
# (see their own job `if:` conditions) to stop draft pushes from booking a full heavy
# CI matrix. PR_DRAFT is folded into the same "was this job in scope" check as the
# *_CHANGED flags so a draft PR reports skipped-and-fine here instead of a false
Expand Down Expand Up @@ -1275,6 +1306,12 @@ jobs:
require_skipped_or_success "db-reset-verify" "$DB_RESULT"
fi

if { [ "$DB_CHANGED" = "true" ] || [ "$STATIC_HEAVY_CHANGED" = "true" ]; } && [ "$PR_DRAFT" != "true" ]; then
require_success "caring-contacts-db" "$CARING_CONTACTS_DB_RESULT"
else
require_skipped_or_success "caring-contacts-db" "$CARING_CONTACTS_DB_RESULT"
fi

# A real break is always the headline. Every failure is listed, not just the first, and a
# concurrent cancellation is demoted to context so it cannot read as an excuse.
if [ ${#failures[@]} -gt 0 ]; then
Expand Down
2 changes: 1 addition & 1 deletion docs/codebase-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ names it by href, never by import), so the dashboard references no chunk exclusi

### Schema tables

`documents`, `document_pages`, `document_images`, `document_chunks`, `document_embedding_fields`, `document_index_units`, `document_table_facts`, `document_labels`, `document_summaries`, `document_sections`, `document_memory_cards`, `document_index_quality`, `document_title_words`, `document_publication_approvals`, `ingestion_jobs`, `ingestion_job_stages`, `indexing_v3_agent_jobs`, `import_batches`, `image_caption_cache`, `rag_queries`, `rag_query_misses`, `rag_aliases`, `rag_response_cache`, `rag_retrieval_logs`, `rag_visual_eval_cases`, `rag_visual_eval_runs`, `rag_answer_feedback`, `clinical_registry_records`, `clinical_registry_record_sources`, `clinical_quality_feedback_triage`, `clinical_quality_feedback_triage_events`, `medication_records`, `differential_records`, `source_review_events`, `user_favourites`, `user_favourite_sets`, `user_preferences`, `api_rate_limits`, `api_rate_limit_subjects`, `audit_logs`, `storage_cleanup_jobs`
`documents`, `document_pages`, `document_images`, `document_chunks`, `document_embedding_fields`, `document_index_units`, `document_table_facts`, `document_labels`, `document_summaries`, `document_sections`, `document_memory_cards`, `document_index_quality`, `document_title_words`, `document_publication_approvals`, `document_corpus_access_state`, `document_corpus_access_snapshots`, `ingestion_jobs`, `ingestion_job_stages`, `indexing_v3_agent_jobs`, `import_batches`, `image_caption_cache`, `rag_queries`, `rag_query_misses`, `rag_aliases`, `rag_response_cache`, `rag_retrieval_logs`, `rag_visual_eval_cases`, `rag_visual_eval_runs`, `rag_answer_feedback`, `clinical_registry_records`, `clinical_registry_record_sources`, `clinical_quality_feedback_triage`, `clinical_quality_feedback_triage_events`, `medication_records`, `differential_records`, `source_review_events`, `user_favourites`, `user_favourite_sets`, `user_preferences`, `api_rate_limits`, `api_rate_limit_subjects`, `audit_logs`, `storage_cleanup_jobs`

**Storage buckets:** `clinical-documents`, `clinical-images` (private)

Expand Down
179 changes: 176 additions & 3 deletions supabase/drift-manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"generated_at": "2026-08-23T08:52:32.433Z",
"generated_at": "2026-08-25T16:44:53.791Z",
"generator": "scripts/generate-drift-manifest.ts",
"postgres_image": "supabase/postgres:17.6.1.127@sha256:be60aee15997daca475b710b734bc6bfe52cd544dcd7e9fd2ff58210b6747d83",
"schema_sha256": "33eb07e0797e3605aec88ecdd130ed3a6a88e68ffb2c96f1bd7c1e6a4d3005dd",
"replay_seconds": 18,
"schema_sha256": "e53377d848c15693be107f9e1492fd55c86b89728c0504dfff97c3fbd89bb351",
"replay_seconds": 27,
"snapshot": {
"views": [
{
Expand Down Expand Up @@ -1013,6 +1013,118 @@
"rls_forced": false,
"rls_enabled": true
},
{
"acl": [
"postgres=arwdDxtm/postgres",
"service_role=r/postgres"
],
"name": "document_corpus_access_snapshots",
"columns": [
{
"name": "activation_id",
"type": "uuid",
"default": null,
"identity": "",
"not_null": true,
"generated": ""
},
{
"name": "captured_at",
"type": "timestamp with time zone",
"default": "now()",
"identity": "",
"not_null": true,
"generated": ""
},
{
"name": "document_id",
"type": "uuid",
"default": null,
"identity": "",
"not_null": true,
"generated": ""
},
{
"name": "owner_id",
"type": "uuid",
"default": null,
"identity": "",
"not_null": false,
"generated": ""
},
{
"name": "public_corpus_present",
"type": "boolean",
"default": null,
"identity": "",
"not_null": true,
"generated": ""
},
{
"name": "public_corpus_value",
"type": "jsonb",
"default": null,
"identity": "",
"not_null": false,
"generated": ""
}
],
"reloptions": null,
"rls_forced": false,
"rls_enabled": true
},
{
"acl": [
"postgres=arwdDxtm/postgres",
"service_role=r/postgres"
],
"name": "document_corpus_access_state",
"columns": [
{
"name": "activated_at",
"type": "timestamp with time zone",
"default": null,
"identity": "",
"not_null": false,
"generated": ""
},
{
"name": "activation_id",
"type": "uuid",
"default": null,
"identity": "",
"not_null": false,
"generated": ""
},
{
"name": "mode",
"type": "text",
"default": null,
"identity": "",
"not_null": true,
"generated": ""
},
{
"name": "singleton",
"type": "boolean",
"default": "true",
"identity": "",
"not_null": true,
"generated": ""
},
{
"name": "updated_at",
"type": "timestamp with time zone",
"default": "now()",
"identity": "",
"not_null": true,
"generated": ""
}
],
"reloptions": null,
"rls_forced": false,
"rls_enabled": true
},
{
"acl": [
"postgres=arwdDxtm/postgres",
Expand Down Expand Up @@ -5168,6 +5280,24 @@
"table": "document_chunks",
"def_hash": "89b1e9c636e8e3228a1bf4bcb416a931"
},
{
"def": "CREATE INDEX document_corpus_access_snapshots_document_id_idx ON public.document_corpus_access_snapshots USING btree (document_id)",
"name": "document_corpus_access_snapshots_document_id_idx",
"table": "document_corpus_access_snapshots",
"def_hash": "a0a2903411efc0859f5bc27cab3269c7"
},
{
"def": "CREATE UNIQUE INDEX document_corpus_access_snapshots_pkey ON public.document_corpus_access_snapshots USING btree (activation_id, document_id)",
"name": "document_corpus_access_snapshots_pkey",
"table": "document_corpus_access_snapshots",
"def_hash": "0ab2d736c5c599a4358e7c2e80252fb6"
},
{
"def": "CREATE UNIQUE INDEX document_corpus_access_state_pkey ON public.document_corpus_access_state USING btree (singleton)",
"name": "document_corpus_access_state_pkey",
"table": "document_corpus_access_state",
"def_hash": "97bb274c865d8e3bc00c23f3b299ad2c"
},
{
"def": "CREATE UNIQUE INDEX document_embedding_fields_dedup_idx ON public.document_embedding_fields USING btree (document_id, source_chunk_id, field_type, content_hash)",
"name": "document_embedding_fields_dedup_idx",
Expand Down Expand Up @@ -7761,6 +7891,14 @@
"def_hash": "85df52de66e4e89d4a328b81a3a87c90",
"signature": "public.search_schema_health()"
},
{
"acl": [
"postgres=X/postgres",
"service_role=X/postgres"
],
"def_hash": "8670d32d9286b89c09ce6117da24c5e0",
"signature": "public.set_document_corpus_access_mode(text)"
},
{
"acl": [
"postgres=X/postgres",
Expand Down Expand Up @@ -8116,6 +8254,41 @@
"name": "document_chunks_pkey",
"table": "document_chunks"
},
{
"def": "CHECK ((public_corpus_present OR (public_corpus_value IS NULL)))",
"name": "document_corpus_access_snapshots_check",
"table": "document_corpus_access_snapshots"
},
{
"def": "FOREIGN KEY (document_id) REFERENCES public.documents(id) ON DELETE CASCADE",
"name": "document_corpus_access_snapshots_document_id_fkey",
"table": "document_corpus_access_snapshots"
},
{
"def": "PRIMARY KEY (activation_id, document_id)",
"name": "document_corpus_access_snapshots_pkey",
"table": "document_corpus_access_snapshots"
},
{
"def": "CHECK (((mode = 'public'::text) = (activation_id IS NOT NULL)))",
"name": "document_corpus_access_state_check",
"table": "document_corpus_access_state"
},
{
"def": "CHECK ((mode = ANY (ARRAY['private'::text, 'public'::text])))",
"name": "document_corpus_access_state_mode_check",
"table": "document_corpus_access_state"
},
{
"def": "PRIMARY KEY (singleton)",
"name": "document_corpus_access_state_pkey",
"table": "document_corpus_access_state"
},
{
"def": "CHECK (singleton)",
"name": "document_corpus_access_state_singleton_check",
"table": "document_corpus_access_state"
},
{
"def": "CHECK ((length(btrim(content)) > 0))",
"name": "document_embedding_fields_content_not_blank",
Expand Down
Loading
Loading