Skip to main content

Database Map

SABLE's Supabase project (fvngkfrmienkltuwtoxa) holds roughly ninety tables defined across the migrations in supabase/migrations/. This page is the map between domains — for field-level detail on any one table, see Schema Reference. Read the migration comment lines when you need the reasoning behind a column; they are written as documentation, not just as change history.

The spine: orgs, people, clients, projects​

Everything else hangs off four tables:

  • orgs — the tenant boundary. Nearly every RLS policy filters on org_id = current_org_id().
  • people — one row per authenticated user, linked to their Supabase auth_user_id, carrying role (admin, lead, or a scoped consultant role).
  • clients — the canonical account record, plus client_external_refs (stable external identities such as a HubSpot company ID, so connector matching survives a display-name change) and client_aliases (name variants a connector might see).
  • projects — the unit everything else attaches to: client_id, code, slug, asana_gid, toggl_project_id, budget and actuals fields, rate_card_id. project_members and project_categories refine who can see a project and how it is grouped.

client_memberships connects a people row to the clients/projects it can see; can_see_project() is the RLS helper nearly every policy calls to answer that question in one place.

Evidence: sources, decisions, promises, tasks​

The four tables the connectors and the chat layer write into and read out of:

  • sources — one row per meeting transcript, email, document, or other origin record. Fathom transcripts land in body. type, occurred_at, and external_id make each source idempotently re-syncable.
  • decisions, promises, tasks — the extracted units of evidence, each linked back to the sources row that produced them.
  • signals and external_contacts — attribution inputs: known vendor/client tokens and known people, so the extractor and the calendar/email routers have something firmer than a label match to attribute a meeting or message to a project. projects.email_tags adds subject-line tags (such as bgm) that file an email or meeting by its subject; see Inbound.

Knowledge and retrieval​

  • documents — the catalog row for anything ingested from Drive, an upload, or an email attachment: storage path, classification, extraction status.
  • knowledge_chunks — the chunked, embedded (Voyage voyage-4) text search and chat retrieval query against, via the match_knowledge_chunks_scoped RPC.
  • retrieval_events and rag_eval_questions / rag_eval_runs — retrieval logging and the offline evaluation harness for tuning retrieval quality.

Approvals and drafts​

  • approvals — the single queue every proposed write or draft passes through: asana_task_create, weekly_update, scope_change, sow_draft, client_readout, deliverable_release, prompt_update, email_draft, scope_flag, sow_estimate. Status transitions (pending → approved/rejected → executed) are the audit trail.
  • deliverable_drafts, deliverable_reviews, deliverable_revision_events, deliverable_evidence, deliverable_templates, deliverable_authoring_profiles, deliverable_canonical_targets — the deliverable-drafting pipeline: a draft, its evidence citations, its review history, the profile (section rubric, standing facts, canonical export target) it was authored against.
  • sable_prompt_versions and sable_skills — every staged/promoted prompt version and the learned skills registry the learning loop folds rules into.

Connectors and scheduling​

  • connector_checkpoints — one row per connector marking how far it has synced; report readiness reads these to decide whether a connector's evidence is fresh enough to include.
  • calendar_events, calendar_busy, calendar_availability_status, calendar_event_project_overrides — the Calendar connector's cache and manual attribution overrides.
  • gmail_messages — the Gmail connector's cache (see the Gmail connector status note).
  • trigger_runs — every Trigger.dev task execution's recorded start/complete/fail state, written by trigger/lib/supabase.ts helpers (createTriggerRun, completeTriggerRun, failTriggerRun).

Customer portal​

The customer portal has its own table family, defined in the collaboration, resource-activation and Essentials migrations. See Find customer portal tables for columns.

  • client_memberships, portal_access_invitations, portal_client_visits — who may enter a client's workspace and when they last did.
  • client_updates, client_requests, client_request_events, client_request_attachments, client_milestones, client_milestone_events — what the customer sees and does.
  • deliverables, deliverable_versions, deliverable_review_states, deliverable_reviews, deliverable_release_receipts — released deliverables and their reviews.
  • portal_resource_publications, portal_resource_publication_events, portal_update_publication_receipts — the record of what was shared, and its withdrawal history.
  • portal_touchpoints, portal_preparations — scheduled customer meetings and starter-package preparation.
  • portal_notification_outbox, portal_notifications, portal_notification_preferences, portal_notification_deliveries — the inbox and email delivery.
  • portal_policies — one row per client: which tabs the customer sees, the landing tab, and the automatic-sharing and weekly-draft settings.
  • portal_links — the lead's important links for a client.

Portfolio and finance​

  • portfolio_import_rows, portfolio_import_runs, portfolio_ledger_entries, portfolio_reconciliations, portfolio_reference_entries — the portfolio-health and reconciliation pipeline behind /api/portfolio-health. The import tables are audit history from the retired Drive workbook import (/api/portfolio-import returns 410 since 14 Oct 2026).
  • budget_lines, rate_cards, estimate_cases — budget and rate inputs, plus persisted outcome estimate cases from /api/estimate-cases.
  • contract_obligations — obligations tracked against a client contract.

Feedback, ideas, and operating lessons​

  • feedback_reports, feedback_attachments, feedback_events, feedback_rate_limits — the in-app feedback widget's records, screenshots, and per-person rate limiting.
  • ideas, clarity_gaps, operating_lessons — proposed rules/skills and gaps surfaced to leads before they become a prompt_update approval.

Env Manager​

A self-contained domain used by the environment-manifest tooling, not the product app: env_apps, env_repos, env_platform_targets, env_var_requirements, env_manifest_ingests, env_reconciliation_runs, env_reconciliation_diffs, secret_providers, secret_vault_refs, secret_deployments, secret_audit_log, shared_credentials. See Env Manager.

Interviews, kickoff, and onboarding capture​

kickoff_briefs, interview_questions, interview_responses, stakeholder_interviews, candidates — the structured capture behind the Kickoff and Interview screens, synthesized by the interview-synthesize Edge Function.

Operational and audit tables​

activity_events, audit, ai_usage, scope_events, client_requests, client_updates, data_access_requests, account_creation_requests, board_runs, board_state, board_feedback, reminders, secret_audit_log. These back the Admin Costs screen and the retired Control Tower and Account Health screens (both now redirect elsewhere), and give every board run, account creation, and scope change a row to point to when something needs explaining after the fact.

board_answers holds a lead's answer to a question the board asked (a Reconciliation & QA item or a SABLE Question), saved from Home chat. Every answer still in force is frozen into the scheduled report's evidence snapshot, and the board applies it silently instead of asking again. An answer stays in force until a newer answer to the same question replaces it, someone withdraws it, or newer evidence contradicts it. The snapshot carries the newest 100 answers in force; the report task logs a warning if there are more. Server-written only; no client policies.

How to explore it yourself​

supabase db diff # from supabase, against a linked project

Or open the Supabase MCP server (configured in .mcp.json, approved via /mcp in a Claude Code session started from repository root) and query information_schema.tables directly rather than re-deriving structure from migration filenames alone — the migrations show history, not always the current shape after later alter table statements.

Where the code lives​

  • supabase/migrations/*.sql — the source of truth; read the comment lines.
  • docs-site/docs/reference/schema.md — field-level detail for the tables most often queried from application code.
  • trigger/lib/supabase.ts — the shared Trigger Supabase client and trigger_runs helpers.