Sadie is Postgres-only. The full, authoritative schema is packages/db/src/schema.ts: roughly 1.6k lines of Drizzle table definitions with typed JSONB columns via .$type<T>(). This page groups the tables by domain and calls out notable shapes; for column-level detail, read the file.
| Table | Notes |
|---|
users | Better-Auth-compatible (id, email, emailVerified, name, image) plus Sadie fields (displayName, avatarColor, role). One row per deployment. This is a single-user product. |
sessions | Cookie sessions. Indexed on token. |
accounts | Better-Auth account rows; reserved for future SSO. |
verifications | Better-Auth verification tokens. Unused today. |
| Table | Notes |
|---|
conversations | sadieEmotion column carries one of seven emotions; set per-message and persisted on the conversation. |
messages | status is `streaming |
chat_context_attachments | Removable context chips: kind is `discourse |
| Table | Notes |
|---|
studio_workspaces | A user can have many workspaces. colorToken picks the Clay accent. |
documents | Tiptap + Yjs. ydocState is base64-encoded binary Yjs update. wikiEntryId set when the draft is filed into Memory. |
comments | Text-anchored via anchorFrom/anchorTo integer offsets. |
studio_collaborator_grants | Local-only collaborator grants; no email send yet. |
| Table | Notes |
|---|
sources | Library of everything Sadie reads. kind covers notes, docs, past posts, articles, RSS, newsletters, Notion, Obsidian, Readwise, uploads. weighting is optional: `personal_library |
source_weightings | Audit trail when weighting changes. |
| Table | Notes |
|---|
feeds | Per-user tracked handle (x_account, rss, newsletter). |
feed_items | Per-user items. Retained for backward compat with code that queries by feed id. |
global_feed_items | Deduplicated across users, keyed by (source, externalId). One X API call per handle, fanned out to all subscribers. |
user_feed_item_links | Join table from user feeds to global_feed_items. |
feed_theme_counts | Rolling theme aggregates for feed-to-wiki promotion. |
| Table | Notes |
|---|
wiki_entries | kind is `person |
wiki_patch_events | Provenance trail. Before/after hashes, trigger kind, source ID. Idempotent by (wikiEntryId, afterHash). |
wiki_link_candidates | Candidate cross-links awaiting review before becoming durable graph edges. |
knowledge_nodes | Graph nodes. kind is `wiki |
knowledge_edges | relation is `mentions |
| Table | Notes |
|---|
soul_state | Typed items: `audience |
voice_portrait | 8-dimension voice model with exemplars, systemPrompt, rewriteAdjustments per dimension. |
soul_narrative | Six prose sections: work_context, personal_context, top_of_mind, three tiers of brief_history_*. |
preference_candidates | Observed preferences before promotion to Soul. Three kind-families: legacy generic, substance, voice. |
rewrite_events | Captured when the user edits Sadie’s output. dimensionDeltas array feeds voice adjustments. |
| Table | Notes |
|---|
briefs | Editorial syntheses. anchorWikiIds and sourceFeedItemIds track provenance. status is `draft |
| Table | Notes |
|---|
discourse_opportunities | Today cards. Carry whyNow, whyYou, whoTalking (DiscourseVoice[]), angles (DiscourseAngle[] with confidence, engagementScore, topCritique), rank, accent. status is `active |
| Table | Notes |
|---|
policies | Deterministic guardrails. kind is `regex |
policy_violations | Audit trail per match. |
| Table | Notes |
|---|
agent_versions | Immutable config snapshots. config JSONB holds prompts, weights, policies, catalog. parentVersionId forms the lineage. status is `committed |
compile_runs | Audit log for every background job. kind covers onboarding, incremental, lint, discourse_refresh, soul_promotion, soul_decay, agent_evolution. |
compile_cursors | Per-user watermarks for incremental processing. |
lint_findings | Wiki health-check surface. kind enumerates orphan, stale, weak provenance, contradiction, missing page, low linkage, soul contradiction, soul decayed. |
| Table | Notes |
|---|
sadie_settings | JSONB payload with persona defaults, cadences, AI provider preference, encrypted userApiKeys, engagement weights, XP weights, currentAgentVersionId. |
onboarding_state | step tracks progress through the 8-step flow. data JSONB accumulates calibration, rewrite drills, scenario checks, and learned writing weights. |
| Table | Notes |
|---|
activity | Everything the user does in the app, keyed by (kind, subjectKind, subjectId). Feeds the agent evolution XP calculation and the Memory activity timeline. |
Many columns use .$type<T>() to brand their JSONB with a TypeScript type. Compile-time only; Postgres still stores real JSONB and can index into it. Notable types:
SadieSettingsPayload. Everything in sadie_settings.payload.
AgentConfig. Prompts + weights + policies + catalog per version.
VoiceDimension[] / VoiceExemplar[]. Voice portrait contents.
NarrativeSection[]. Soul narrative.
OnboardingData. Calibration + distillation state.
DiscourseAngle[] / DiscourseVoice[]. Today card shapes.
See packages/db/src/schema.ts for every branded type. Drizzle returns these as typed values; the database stores them as plain JSONB.