31 lines
3.0 KiB
Rust
31 lines
3.0 KiB
Rust
use cot::db::migrations::{MigrationContext, MigrationDependency, Operation, migration_op};
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub struct Migration;
|
|
impl cot::db::migrations::Migration for Migration {
|
|
const APP_NAME: &'static str = "meguri";
|
|
const MIGRATION_NAME: &'static str = "m_0008_workspaces";
|
|
const DEPENDENCIES: &'static [MigrationDependency] =
|
|
&[MigrationDependency::migration("meguri", "m_0007_language")];
|
|
const OPERATIONS: &'static [Operation] = &[Operation::custom(upgrade).build()];
|
|
}
|
|
#[migration_op]
|
|
async fn upgrade(context: MigrationContext<'_>) -> cot::db::Result<()> {
|
|
context.db.raw(r#"DO $$ BEGIN
|
|
IF EXISTS(SELECT 1 FROM meguri__tenants) OR EXISTS(SELECT 1 FROM meguri__teams) THEN
|
|
RAISE EXCEPTION 'Workspace schema requires a fresh database. Existing tenant/team data was not changed.';
|
|
END IF;
|
|
DROP TABLE meguri__provider_objects,meguri__sync_jobs,meguri__audit_events,meguri__team_history,meguri__team_members,meguri__tenant_members,meguri__teams,meguri__tenants;
|
|
CREATE TABLE meguri__workspaces(id text PRIMARY KEY,document text NOT NULL CHECK(jsonb_typeof(document::jsonb)='object'),revision bigint NOT NULL,created_at timestamptz NOT NULL,demo_deleted_at timestamptz);
|
|
CREATE TABLE meguri__workspace_members(id text PRIMARY KEY,workspace_id text NOT NULL REFERENCES meguri__workspaces(id),user_id text NOT NULL REFERENCES meguri__users(id),permissions text NOT NULL CHECK(jsonb_typeof(permissions::jsonb)='array'),is_owner boolean NOT NULL,UNIQUE(workspace_id,user_id));
|
|
CREATE TABLE meguri__workspace_history(id text PRIMARY KEY,workspace_id text NOT NULL REFERENCES meguri__workspaces(id),revision bigint NOT NULL,document text NOT NULL,effective_at timestamptz NOT NULL,actor_id text,UNIQUE(workspace_id,revision));
|
|
CREATE TABLE meguri__audit_events(id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,workspace_id text NOT NULL REFERENCES meguri__workspaces(id),actor_id text,action text NOT NULL,details text NOT NULL,created_at timestamptz NOT NULL);
|
|
CREATE TABLE meguri__sync_jobs(workspace_id text PRIMARY KEY REFERENCES meguri__workspaces(id),requested_revision bigint NOT NULL,published_revision bigint,state text NOT NULL,attempts integer NOT NULL,next_attempt timestamptz NOT NULL,last_error text,last_success timestamptz,window_end timestamptz,lease_token text,lease_until timestamptz);
|
|
CREATE TABLE meguri__provider_objects(id text PRIMARY KEY,workspace_id text NOT NULL REFERENCES meguri__workspaces(id),object_key text NOT NULL,remote_id text NOT NULL,content text NOT NULL,updated_at timestamptz NOT NULL,UNIQUE(workspace_id,object_key));
|
|
CREATE INDEX workspace_sync_due ON meguri__sync_jobs(next_attempt);
|
|
CREATE INDEX workspace_audit ON meguri__audit_events(workspace_id,id DESC);
|
|
CREATE INDEX workspace_history_time ON meguri__workspace_history(workspace_id,effective_at);
|
|
CREATE UNIQUE INDEX workspace_jsm_destination ON meguri__workspaces((document::jsonb->'integration'->>'cloud_id'),(document::jsonb->'integration'->>'team_id')) WHERE document::jsonb->'integration'->>'provider'='jsm';
|
|
END $$;"#).await?;
|
|
Ok(())
|
|
}
|