Data Model

This page maps Ragz's core entities and how they relate — useful background before reading RBAC or Roles & Permissions, and the entities that Security Model's tenant isolation and ACL rules actually operate over.

The tree

Organization
└── Workspace                    (= a department)
    ├── WorkspaceMember          (user + role: owner | manager | contributor | viewer)
    ├── Folder                   (navigation only — no ACL of its own)
    ├── Document                 (+ versions, + acl_group_ids)
    ├── Group / UserGroup        (org-scoped; referenced by Document.acl_group_ids)
    ├── Chat
    │   └── Message              (tree-structured: edits/regenerates branch)
    │       ├── Citation         (document + version + section + page, or a web URL)
    │       └── ChatAttachment
    └── MetadataField            (admin-defined per-workspace document metadata)
 
Organization
├── UsageRecord                  (per org/user/workspace usage ledger)
├── OrgQuota / UserQuota
└── RoleTemplate                 (global, superadmin-composed permission bundles)
 
(org-independent)
└── Secret                       (envelope-encrypted provider keys — see Security Model)

Organizations and workspaces

An Organization is the top-level tenant boundary — every org-owned row in Postgres, and every Qdrant point, carries an org_id, and TenantContext (see Security Model) is what makes that boundary actually hold at query time.

A Workspace is a department: its own embedding model, retrieval tuning (top_k, min_score, rerank on/off), chunking strategy, system-prompt override, and feature toggles (web search, generative UI, strict-mode validation). Documents, chats, and folders all belong to exactly one workspace.

Membership and roles

TablePurpose
WorkspaceMemberTies a user to a workspace with a role: owner, manager, contributor, or viewer
Group / UserGroupOrg-scoped groups, independent of workspace membership — the unit that Document.acl_group_ids restricts against
RoleTemplate / RoleTemplateVersionSuperadmin-composed, org-independent named permission bundles that org admins assign to role="user" accounts; versioned, with a draft → active → archived lifecycle

owner and manager are the two workspace roles that act as department admin for that workspace — document ACL management, workspace settings, and member management. contributor can upload and chat; viewer can chat and read but not upload. This role only ever governs workspace-scoped actions — org-level admin/superadmin standing is separate (see Roles & Permissions) and two permissions, documents.acl.bypass and audit.read/audit.export, are carved out from automatic admin grants entirely — they require an explicit role-template grant even for an org admin.

Documents

A Document belongs to a workspace and optionally a Folder (navigation only — folders carry no ACL of their own; each document keeps its own independent acl_group_ids regardless of which folder it sits in).

  • Versioning: lineage_id groups every version of "the same document"; version increments; supersedes_document_id points at the version it replaces; is_current + approved together decide whether retrieval can see it — per the product requirement that the latest approved version wins and superseded versions are ignored.
  • ACL: acl_group_ids is None for an unrestricted document, or a list of Group IDs — only members of those groups (plus admins) can retrieve from or open it. This is the field the Security Model's vector-query ACL enforcement reads, and the field that's blanked to null for plain users in API responses.
  • Status: queued → processing → indexed (or failed), tracked alongside an IngestJob row per stage (parse → chunk → embed → upsert).
  • Metadata: admin-defined MetadataFields per workspace (name, version, revision date, department, doc type, or custom fields) with values stored on Document.meta.

Chat

A Chat belongs to a workspace and a user. Its Messages form a tree, not a list: editing a message inserts a new sibling under the same parent (new sibling_index), and regenerating inserts a new assistant sibling under the same user message — so every past branch stays intact and selectable, not overwritten.

Each assistant Message carries:

  • grounding ("documents" vs "general" — set to "general" only on a labeled general-knowledge fallback, never silently)
  • grounding_score / completeness_score (set only when strict-mode validation ran)
  • blocks_json (structured generative-UI blocks, when the workspace has that feature enabled)

Each Citation row is one grounding reference on a message — document ID (nullable for a web citation), a chunk_ref, page, score, the [n] marker used in the rendered answer, section, and the document's version at citation time (deliberately not an FK to Document — deleting a document must never rewrite chat history). A ChatAttachment is a file a user attached to a specific turn (routed either inline or through retrieval).

Usage and quotas

Every billable action (chat completion, ingestion, embedding, rerank, web search) writes one UsageRecordorg_id, user_id, an optional workspace_id (pure reporting dimension, never part of aggregation), token counts, and units for per-call features like rerank or web search. OrgQuota and UserQuota set the monthly ceilings this ledger is checked against.

Secrets

A Secret row is { name, ciphertext, nonce, key_version, fingerprint } — provider API keys and similar, envelope-encrypted under the KEK (see Security Model). There's no plaintext column and no org scoping on this table itself; access to use a secret is gated by the route/service layer, not by a tenancy column.

Where RBAC attaches

DecisionReads
Can this request touch org X's data at all?TenantContext.org_id
Can this user act in workspace Y?WorkspaceMember.role for that (user, workspace) pair
Can this user retrieve/open document Z?Document.acl_group_idsTenantContext.group_ids (or admin)
Can this user perform a specific privileged action?TenantContext.permissions, sourced from role + any assigned RoleTemplate

See RBAC for the full authorization walkthrough and Roles & Permissions for the permission catalog.