Skip to Content
ContributeBackendDatabase Models

Database Models

SQLAlchemy models live in app/models/ and inherit from a common Base. PostgreSQL is the backing store; migrations are managed with Alembic (alembic/).

Base Model

Every model inherits from Base, which provides:

  • id: UUID primary key (custom GUID type wrapping PostgreSQL’s uuid)
  • nano_id: short human-readable unique identifier
  • created_at / updated_at: timestamps, updated_at refreshed on modification
  • deleted_at: soft-delete marker with soft_delete() / restore() helpers (see Soft Deletion)

UUID primary keys are used instead of sequential integers for security and distribution in a multi-tenant environment.

Core Models

  • Useremail (unique), name, is_active, is_verified (admin/Polyphemus access gate), organization_id, and user_settings (JSONB preferences, see User Settings).
  • Organization — a tenant in the multi-tenant architecture: name, slug, is_active, plus domain and subscription fields.
  • Prompt — the input text sent to a model: content, expected_response, and FKs to behavior, category, topic, and source.
  • Test — pairs a Prompt (prompt_id) with metadata: priority, test_type_id, status_id, and owner/assignee. A test’s text comes from its linked prompt, not from its own columns.
  • TestSet — a named collection of tests (many-to-many with Test): name, description, status_id.
  • Model — an AI model configuration: name, model_name (provider identifier), model_type, endpoint, and provider_type (FK to a type lookup). API keys are stored encrypted.

Relationships

  • One-to-many: Organization → Users, User → Tests, Category → Prompts.
  • Many-to-many: Test ↔ TestSet (via an association table), and any model using TagsMixin ↔ Tag (polymorphic, via TaggedItem).

Mixins

Common behavior is composed from mixins in app/models/mixins.py:

  • OrganizationMixin / UserOwnedMixin — add organization_id / user_id FKs for tenancy and ownership.
  • ProjectMixin — nullable project_id; NULL means org-wide (visible in every project).
  • TagsMixin, CommentsMixin, FilesMixin, TasksMixin — polymorphic relationships keyed on entity_type + entity_id.
  • EmbeddableMixin — vector-embedding and full-text search support; subclasses implement to_searchable_text().

Multi-tenancy

Models with org-scoped data carry an organization_id. Tenant filtering is applied automatically by SQLAlchemy event listeners and enforced at the database level with row-level security (PostgreSQL policies keyed on the app.current_organization / app.current_user session variables). See Multi-tenancy.