Files
meguri/src/models.rs
T
Aleksandr BogomiakovandClaude 38105c65c2 Merge NEXT: planning, generation map and portable configuration on top of the OIDC access model
NEXT predates the access work, so the identity layer follows master: access comes from
configured groups, instance administrators replace the site administration, and accounts are
created by SSO or by an administrator. Kept from NEXT: manual publication with the Review
changes panel and shared generator drafts, portable import/export (meguri/v2), the layered
generation map with binding provenance, JSM provider changes, contact/approval semantics and
the account-owned Person. Dropped: site administration, local sign-up, and the mandatory
unique email with its contact/account migrations. The manual-publication migration is
renumbered m_0010 after m_0009_access.

Accounts without an email still get a Person in every workspace they reach, a changed sign-in
email updates the account's person, and an account that loses access keeps its linked person so
schedules stay valid. Instance administrators may use Sync and shared drafts.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-07 16:06:10 +01:00

165 lines
4.3 KiB
Rust

//! Cot ORM models. UUIDs and typed documents use portable string storage in Cot 0.7.
use chrono::{DateTime, Utc};
use cot::db::{Auto, model};
#[derive(Debug, Clone)]
#[model(table_name = "users")]
pub struct UserRow {
pub language: Option<String>,
pub demo_deleted_at: Option<DateTime<Utc>>,
#[model(primary_key)]
pub id: String,
#[model(unique)]
pub username: String,
pub display_name: String,
pub country: String,
pub timezone: Option<String>,
/// None for accounts that sign in only through SSO or whose bootstrap access was removed.
pub password_hash: Option<String>,
pub created_at: DateTime<Utc>,
pub email: Option<String>,
pub instance_admin: bool,
pub bootstrap: bool,
/// JSON array of group names that map to workspace roles through the instance configuration.
pub groups: String,
}
#[derive(Debug, Clone)]
#[model(table_name = "external_identities")]
pub struct ExternalIdentityRow {
#[model(primary_key)]
pub id: String,
pub issuer: String,
pub subject: String,
pub user_id: String,
}
#[derive(Debug, Clone)]
#[model(table_name = "sessions")]
pub struct SessionRow {
#[model(primary_key)]
pub token_hash: String,
pub user_id: String,
pub csrf: String,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
#[model(table_name = "workspaces")]
pub struct WorkspaceRow {
pub demo_deleted_at: Option<DateTime<Utc>>,
#[model(primary_key)]
pub id: String,
pub document: String,
pub revision: i64,
pub created_at: DateTime<Utc>,
/// Stable identifier from the instance configuration; None for legacy workspaces.
pub key: Option<String>,
pub disabled_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
#[model(table_name = "workspace_members")]
pub struct WorkspaceMemberRow {
#[model(primary_key)]
pub id: String,
pub workspace_id: String,
pub user_id: String,
pub permissions: String,
pub is_owner: bool,
}
#[derive(Debug, Clone)]
#[model(table_name = "workspace_history")]
pub struct HistoryRow {
#[model(primary_key)]
pub id: String,
pub workspace_id: String,
pub revision: i64,
pub document: String,
pub effective_at: DateTime<Utc>,
pub actor_id: Option<String>,
}
#[derive(Debug, Clone)]
#[model(table_name = "audit_events")]
pub struct AuditRow {
#[model(primary_key)]
pub id: Auto<i64>,
pub workspace_id: String,
pub actor_id: Option<String>,
pub action: String,
pub details: String,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
#[model(table_name = "sync_jobs")]
pub struct SyncJobRow {
pub authorized_revision: Option<i64>,
pub authorized_document: Option<String>,
pub published_document: Option<String>,
#[model(primary_key)]
pub workspace_id: String,
pub requested_revision: i64,
pub published_revision: Option<i64>,
pub state: String,
pub attempts: i32,
pub next_attempt: DateTime<Utc>,
pub last_error: Option<String>,
pub last_success: Option<DateTime<Utc>>,
pub window_end: Option<DateTime<Utc>>,
pub lease_token: Option<String>,
pub lease_until: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
#[model(table_name = "provider_objects")]
pub struct ProviderObjectRow {
#[model(primary_key)]
pub id: String,
pub workspace_id: String,
pub object_key: String,
pub remote_id: String,
pub content: String,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
#[model(table_name = "oidc_flows")]
pub struct OidcFlowRow {
#[model(primary_key)]
pub state_hash: String,
pub nonce: String,
pub verifier: String,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
#[model(table_name = "instance_state")]
pub struct InstanceStateRow {
#[model(primary_key)]
pub key: String,
pub value: String,
}
#[derive(Debug, Clone)]
#[model(table_name = "workspace_drafts")]
pub struct WorkspaceDraftRow {
#[model(primary_key)]
pub workspace_id: String,
pub revision: i64,
pub payload: String,
}
#[derive(Debug, Clone)]
#[model(table_name = "instance_audit")]
pub struct InstanceAuditRow {
#[model(primary_key)]
pub id: Auto<i64>,
pub actor_id: Option<String>,
pub action: String,
pub details: String,
pub created_at: DateTime<Utc>,
}