feat: add workspace foundation

This commit is contained in:
a.tolmachev
2026-03-29 21:45:53 +03:00
parent d3ab565fff
commit d757adb192
19 changed files with 743 additions and 109 deletions
+4
View File
@@ -6,6 +6,10 @@ pub enum RegistryError {
Storage(#[from] sqlx::Error),
#[error(transparent)]
Serialization(#[from] serde_json::Error),
#[error("workspace {workspace_id} was not found")]
WorkspaceNotFound { workspace_id: String },
#[error("workspace with slug {slug} already exists")]
WorkspaceSlugAlreadyExists { slug: String },
#[error("operation {operation_id} already exists")]
OperationAlreadyExists { operation_id: String },
#[error("operation {operation_id} was not found")]
+5 -5
View File
@@ -5,10 +5,10 @@ mod postgres;
pub use error::RegistryError;
pub use model::{
CreateVersionRequest, CreateYamlImportJobRequest, DescriptorKind, DescriptorMetadata,
OperationSampleMetadata, OperationSummary, OperationVersionRecord, PublishRequest,
RegistryOperation, SampleKind, SaveAuthProfileRequest, SaveDescriptorMetadataRequest,
SaveSampleMetadataRequest, YamlImportJob, YamlImportJobCompletion, YamlImportJobId,
YamlImportJobStatus,
CreateVersionRequest, CreateWorkspaceRequest, CreateYamlImportJobRequest, DescriptorKind,
DescriptorMetadata, OperationSampleMetadata, OperationSummary, OperationVersionRecord,
PublishRequest, RegistryOperation, SampleKind, SaveAuthProfileRequest,
SaveDescriptorMetadataRequest, SaveSampleMetadataRequest, UpdateWorkspaceRequest,
WorkspaceRecord, YamlImportJob, YamlImportJobCompletion, YamlImportJobId, YamlImportJobStatus,
};
pub use postgres::PostgresRegistry;
+77 -2
View File
@@ -1,10 +1,48 @@
use sqlx::{PgPool, query};
pub async fn apply_postgres(pool: &PgPool) -> Result<(), sqlx::Error> {
query(
"create table if not exists workspaces (
id text primary key,
slug text not null unique,
display_name text not null,
status text not null,
settings_json jsonb not null default '{}'::jsonb,
created_at timestamptz not null,
updated_at timestamptz not null
)",
)
.execute(pool)
.await?;
query(
"insert into workspaces (
id,
slug,
display_name,
status,
settings_json,
created_at,
updated_at
) values (
'ws_default',
'default',
'Default Workspace',
'active',
'{}'::jsonb,
now(),
now()
)
on conflict (id) do nothing",
)
.execute(pool)
.await?;
query(
"create table if not exists operations (
id text primary key,
name text not null unique,
workspace_id text null references workspaces(id) on delete cascade,
name text not null,
display_name text not null,
protocol text not null,
status text not null,
@@ -18,6 +56,24 @@ pub async fn apply_postgres(pool: &PgPool) -> Result<(), sqlx::Error> {
.execute(pool)
.await?;
query("alter table operations add column if not exists workspace_id text null references workspaces(id) on delete cascade")
.execute(pool)
.await?;
query("update operations set workspace_id = 'ws_default' where workspace_id is null")
.execute(pool)
.await?;
query("alter table operations alter column workspace_id set not null")
.execute(pool)
.await?;
query("alter table operations drop constraint if exists operations_name_key")
.execute(pool)
.await?;
query(
"create unique index if not exists operations_workspace_name_idx on operations(workspace_id, name)",
)
.execute(pool)
.await?;
query(
"create table if not exists operation_versions (
operation_id text not null references operations(id) on delete cascade,
@@ -89,7 +145,8 @@ pub async fn apply_postgres(pool: &PgPool) -> Result<(), sqlx::Error> {
query(
"create table if not exists auth_profiles (
id text primary key,
name text not null unique,
workspace_id text null references workspaces(id) on delete cascade,
name text not null,
kind text not null,
config_json jsonb not null,
created_at timestamptz not null,
@@ -99,6 +156,24 @@ pub async fn apply_postgres(pool: &PgPool) -> Result<(), sqlx::Error> {
.execute(pool)
.await?;
query("alter table auth_profiles add column if not exists workspace_id text null references workspaces(id) on delete cascade")
.execute(pool)
.await?;
query("update auth_profiles set workspace_id = 'ws_default' where workspace_id is null")
.execute(pool)
.await?;
query("alter table auth_profiles alter column workspace_id set not null")
.execute(pool)
.await?;
query("alter table auth_profiles drop constraint if exists auth_profiles_name_key")
.execute(pool)
.await?;
query(
"create unique index if not exists auth_profiles_workspace_name_idx on auth_profiles(workspace_id, name)",
)
.execute(pool)
.await?;
query(
"create table if not exists yaml_import_jobs (
id text primary key,
+21 -1
View File
@@ -1,6 +1,6 @@
use crank_core::{
AuthProfile, DescriptorId, ExportMode, Operation, OperationId, OperationStatus, Protocol,
SampleId,
SampleId, Workspace, WorkspaceId,
};
use crank_mapping::MappingSet;
use crank_schema::Schema;
@@ -40,9 +40,15 @@ define_registry_id!(YamlImportJobId);
pub type RegistryOperation = Operation<Schema, MappingSet>;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct WorkspaceRecord {
pub workspace: Workspace,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct OperationSummary {
pub id: OperationId,
pub workspace_id: WorkspaceId,
pub name: String,
pub display_name: String,
pub protocol: Protocol,
@@ -57,6 +63,7 @@ pub struct OperationSummary {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct OperationVersionRecord {
pub operation_id: OperationId,
pub workspace_id: WorkspaceId,
pub version: u32,
pub status: OperationStatus,
pub change_note: Option<String>,
@@ -138,6 +145,7 @@ pub struct YamlImportJobCompletion {
#[derive(Clone, Debug, PartialEq)]
pub struct CreateVersionRequest<'a> {
pub workspace_id: &'a WorkspaceId,
pub snapshot: &'a RegistryOperation,
pub change_note: Option<&'a str>,
pub created_by: Option<&'a str>,
@@ -145,6 +153,7 @@ pub struct CreateVersionRequest<'a> {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PublishRequest<'a> {
pub workspace_id: &'a WorkspaceId,
pub operation_id: &'a OperationId,
pub version: u32,
pub published_at: &'a str,
@@ -162,9 +171,20 @@ pub struct CreateYamlImportJobRequest<'a> {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SaveAuthProfileRequest<'a> {
pub workspace_id: &'a WorkspaceId,
pub profile: &'a AuthProfile,
}
#[derive(Clone, Debug, PartialEq)]
pub struct CreateWorkspaceRequest<'a> {
pub workspace: &'a Workspace,
}
#[derive(Clone, Debug, PartialEq)]
pub struct UpdateWorkspaceRequest<'a> {
pub workspace: &'a Workspace,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SaveSampleMetadataRequest<'a> {
pub sample: &'a OperationSampleMetadata,
+224 -27
View File
@@ -1,4 +1,4 @@
use crank_core::{AuthProfile, OperationId, OperationStatus};
use crank_core::{AuthProfile, OperationId, OperationStatus, Workspace, WorkspaceId};
use serde::{Serialize, de::DeserializeOwned};
use serde_json::Value;
use sqlx::{
@@ -11,11 +11,11 @@ use crate::{
error::RegistryError,
migrations,
model::{
CreateVersionRequest, CreateYamlImportJobRequest, DescriptorMetadata,
OperationSampleMetadata, OperationSummary, OperationVersionRecord, PublishRequest,
RegistryOperation, SaveAuthProfileRequest, SaveDescriptorMetadataRequest,
SaveSampleMetadataRequest, YamlImportJob, YamlImportJobCompletion, YamlImportJobId,
YamlImportJobStatus,
CreateVersionRequest, CreateWorkspaceRequest, CreateYamlImportJobRequest,
DescriptorMetadata, OperationSampleMetadata, OperationSummary, OperationVersionRecord,
PublishRequest, RegistryOperation, SaveAuthProfileRequest, SaveDescriptorMetadataRequest,
SaveSampleMetadataRequest, UpdateWorkspaceRequest, WorkspaceRecord, YamlImportJob,
YamlImportJobCompletion, YamlImportJobId, YamlImportJobStatus,
},
};
@@ -38,6 +38,126 @@ impl PostgresRegistry {
Ok(())
}
pub async fn list_workspaces(&self) -> Result<Vec<WorkspaceRecord>, RegistryError> {
let rows = sqlx::query(
"select
id,
slug,
display_name,
status,
settings_json,
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as created_at,
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as updated_at
from workspaces
order by slug asc",
)
.fetch_all(&self.pool)
.await?;
rows.iter().map(map_workspace_record).collect()
}
pub async fn get_workspace(
&self,
workspace_id: &WorkspaceId,
) -> Result<Option<WorkspaceRecord>, RegistryError> {
let row = sqlx::query(
"select
id,
slug,
display_name,
status,
settings_json,
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as created_at,
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as updated_at
from workspaces
where id = $1",
)
.bind(workspace_id.as_str())
.fetch_optional(&self.pool)
.await?;
row.as_ref().map(map_workspace_record).transpose()
}
pub async fn create_workspace(
&self,
request: CreateWorkspaceRequest<'_>,
) -> Result<(), RegistryError> {
let result = sqlx::query(
"insert into workspaces (
id,
slug,
display_name,
status,
settings_json,
created_at,
updated_at
) values (
$1, $2, $3, $4, $5, $6::timestamptz, $7::timestamptz
)",
)
.bind(request.workspace.id.as_str())
.bind(&request.workspace.slug)
.bind(&request.workspace.display_name)
.bind(serialize_enum_text(&request.workspace.status, "status")?)
.bind(Json(request.workspace.settings.clone()))
.bind(&request.workspace.created_at)
.bind(&request.workspace.updated_at)
.execute(&self.pool)
.await;
match result {
Ok(_) => Ok(()),
Err(sqlx::Error::Database(error))
if error.constraint() == Some("workspaces_slug_key") =>
{
Err(RegistryError::WorkspaceSlugAlreadyExists {
slug: request.workspace.slug.clone(),
})
}
Err(error) => Err(RegistryError::Storage(error)),
}
}
pub async fn update_workspace(
&self,
request: UpdateWorkspaceRequest<'_>,
) -> Result<(), RegistryError> {
let result = sqlx::query(
"update workspaces
set slug = $1,
display_name = $2,
status = $3,
settings_json = $4,
updated_at = $5::timestamptz
where id = $6",
)
.bind(&request.workspace.slug)
.bind(&request.workspace.display_name)
.bind(serialize_enum_text(&request.workspace.status, "status")?)
.bind(Json(request.workspace.settings.clone()))
.bind(&request.workspace.updated_at)
.bind(request.workspace.id.as_str())
.execute(&self.pool)
.await;
match result {
Ok(result) if result.rows_affected() == 0 => Err(RegistryError::WorkspaceNotFound {
workspace_id: request.workspace.id.as_str().to_owned(),
}),
Ok(_) => Ok(()),
Err(sqlx::Error::Database(error))
if error.constraint() == Some("workspaces_slug_key") =>
{
Err(RegistryError::WorkspaceSlugAlreadyExists {
slug: request.workspace.slug.clone(),
})
}
Err(error) => Err(RegistryError::Storage(error)),
}
}
async fn connect_in_schema(
database_url: &str,
schema: Option<&str>,
@@ -60,6 +180,7 @@ impl PostgresRegistry {
pub async fn create_operation(
&self,
workspace_id: &WorkspaceId,
snapshot: &RegistryOperation,
created_by: Option<&str>,
) -> Result<(), RegistryError> {
@@ -70,7 +191,11 @@ impl PostgresRegistry {
});
}
if self.get_operation_summary(&snapshot.id).await?.is_some() {
if self
.get_operation_summary(workspace_id, &snapshot.id)
.await?
.is_some()
{
return Err(RegistryError::OperationAlreadyExists {
operation_id: snapshot.id.as_str().to_owned(),
});
@@ -81,6 +206,7 @@ impl PostgresRegistry {
sqlx::query(
"insert into operations (
id,
workspace_id,
name,
display_name,
protocol,
@@ -91,13 +217,14 @@ impl PostgresRegistry {
updated_at,
published_at
) values (
$1, $2, $3, $4, $5, $6, $7,
$8::timestamptz,
$1, $2, $3, $4, $5, $6, $7, $8,
$9::timestamptz,
$10::timestamptz
$10::timestamptz,
$11::timestamptz
)",
)
.bind(snapshot.id.as_str())
.bind(workspace_id.as_str())
.bind(&snapshot.name)
.bind(&snapshot.display_name)
.bind(serialize_enum_text(&snapshot.protocol, "protocol")?)
@@ -125,7 +252,10 @@ impl PostgresRegistry {
&self,
request: CreateVersionRequest<'_>,
) -> Result<(), RegistryError> {
let Some(summary) = self.get_operation_summary(&request.snapshot.id).await? else {
let Some(summary) = self
.get_operation_summary(request.workspace_id, &request.snapshot.id)
.await?
else {
return Err(RegistryError::OperationNotFound {
operation_id: request.snapshot.id.as_str().to_owned(),
});
@@ -170,10 +300,14 @@ impl PostgresRegistry {
Ok(())
}
pub async fn list_operations(&self) -> Result<Vec<OperationSummary>, RegistryError> {
pub async fn list_operations(
&self,
workspace_id: &WorkspaceId,
) -> Result<Vec<OperationSummary>, RegistryError> {
let rows = sqlx::query(
"select
id,
workspace_id,
name,
display_name,
protocol,
@@ -184,8 +318,10 @@ impl PostgresRegistry {
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as updated_at,
to_char(published_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as published_at
from operations
where workspace_id = $1
order by name asc",
)
.bind(workspace_id.as_str())
.fetch_all(&self.pool)
.await?;
@@ -194,11 +330,13 @@ impl PostgresRegistry {
pub async fn get_operation_summary(
&self,
workspace_id: &WorkspaceId,
operation_id: &OperationId,
) -> Result<Option<OperationSummary>, RegistryError> {
let row = sqlx::query(
"select
id,
workspace_id,
name,
display_name,
protocol,
@@ -209,8 +347,9 @@ impl PostgresRegistry {
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as updated_at,
to_char(published_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as published_at
from operations
where id = $1",
where workspace_id = $1 and id = $2",
)
.bind(workspace_id.as_str())
.bind(operation_id.as_str())
.fetch_optional(&self.pool)
.await?;
@@ -220,12 +359,14 @@ impl PostgresRegistry {
pub async fn get_operation_version(
&self,
workspace_id: &WorkspaceId,
operation_id: &OperationId,
version: u32,
) -> Result<Option<OperationVersionRecord>, RegistryError> {
let row = sqlx::query(
"select
o.id,
o.workspace_id,
o.name,
o.display_name,
o.protocol,
@@ -249,8 +390,9 @@ impl PostgresRegistry {
ov.created_by
from operation_versions ov
join operations o on o.id = ov.operation_id
where ov.operation_id = $1 and ov.version = $2",
where o.workspace_id = $1 and ov.operation_id = $2 and ov.version = $3",
)
.bind(workspace_id.as_str())
.bind(operation_id.as_str())
.bind(to_db_version(version))
.fetch_optional(&self.pool)
@@ -261,11 +403,13 @@ impl PostgresRegistry {
pub async fn list_operation_versions(
&self,
workspace_id: &WorkspaceId,
operation_id: &OperationId,
) -> Result<Vec<OperationVersionRecord>, RegistryError> {
let rows = sqlx::query(
"select
o.id,
o.workspace_id,
o.name,
o.display_name,
o.protocol,
@@ -289,9 +433,10 @@ impl PostgresRegistry {
ov.created_by
from operation_versions ov
join operations o on o.id = ov.operation_id
where ov.operation_id = $1
where o.workspace_id = $1 and ov.operation_id = $2
order by ov.version asc",
)
.bind(workspace_id.as_str())
.bind(operation_id.as_str())
.fetch_all(&self.pool)
.await?;
@@ -304,7 +449,7 @@ impl PostgresRegistry {
request: PublishRequest<'_>,
) -> Result<(), RegistryError> {
if self
.get_operation_version(request.operation_id, request.version)
.get_operation_version(request.workspace_id, request.operation_id, request.version)
.await?
.is_none()
{
@@ -373,6 +518,7 @@ impl PostgresRegistry {
let row = sqlx::query(
"select
o.id,
o.workspace_id,
o.name,
o.display_name,
o.protocol,
@@ -413,6 +559,7 @@ impl PostgresRegistry {
let rows = sqlx::query(
"select
o.id,
o.workspace_id,
o.name,
o.display_name,
o.protocol,
@@ -455,19 +602,22 @@ impl PostgresRegistry {
sqlx::query(
"insert into auth_profiles (
id,
workspace_id,
name,
kind,
config_json,
created_at,
updated_at
) values ($1, $2, $3, $4, $5::timestamptz, $6::timestamptz)
) values ($1, $2, $3, $4, $5, $6::timestamptz, $7::timestamptz)
on conflict(id) do update set
workspace_id = excluded.workspace_id,
name = excluded.name,
kind = excluded.kind,
config_json = excluded.config_json,
updated_at = excluded.updated_at",
)
.bind(request.profile.id.as_str())
.bind(request.workspace_id.as_str())
.bind(&request.profile.name)
.bind(serialize_enum_text(&request.profile.kind, "kind")?)
.bind(Json(serialize_json_value(&request.profile.config)?))
@@ -481,19 +631,22 @@ impl PostgresRegistry {
pub async fn get_auth_profile(
&self,
workspace_id: &WorkspaceId,
auth_profile_id: &crank_core::AuthProfileId,
) -> Result<Option<AuthProfile>, RegistryError> {
let row = sqlx::query(
"select
id,
workspace_id,
name,
kind,
config_json,
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as created_at,
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as updated_at
from auth_profiles
where id = $1",
where workspace_id = $1 and id = $2",
)
.bind(workspace_id.as_str())
.bind(auth_profile_id.as_str())
.fetch_optional(&self.pool)
.await?;
@@ -501,18 +654,24 @@ impl PostgresRegistry {
row.as_ref().map(map_auth_profile).transpose()
}
pub async fn list_auth_profiles(&self) -> Result<Vec<AuthProfile>, RegistryError> {
pub async fn list_auth_profiles(
&self,
workspace_id: &WorkspaceId,
) -> Result<Vec<AuthProfile>, RegistryError> {
let rows = sqlx::query(
"select
id,
workspace_id,
name,
kind,
config_json,
to_char(created_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as created_at,
to_char(updated_at at time zone 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') as updated_at
from auth_profiles
where workspace_id = $1
order by name asc",
)
.bind(workspace_id.as_str())
.fetch_all(&self.pool)
.await?;
@@ -837,9 +996,24 @@ fn assert_immutable_fields(
Ok(())
}
fn map_workspace_record(row: &PgRow) -> Result<WorkspaceRecord, RegistryError> {
Ok(WorkspaceRecord {
workspace: Workspace {
id: WorkspaceId::new(row.try_get::<String, _>("id")?),
slug: row.try_get("slug")?,
display_name: row.try_get("display_name")?,
status: deserialize_enum_text(&row.try_get::<String, _>("status")?, "status")?,
settings: row.try_get::<Json<Value>, _>("settings_json")?.0,
created_at: row.try_get("created_at")?,
updated_at: row.try_get("updated_at")?,
},
})
}
fn map_operation_summary(row: &PgRow) -> Result<OperationSummary, RegistryError> {
Ok(OperationSummary {
id: OperationId::new(row.try_get::<String, _>("id")?),
workspace_id: WorkspaceId::new(row.try_get::<String, _>("workspace_id")?),
name: row.try_get("name")?,
display_name: row.try_get("display_name")?,
protocol: deserialize_enum_text(&row.try_get::<String, _>("protocol")?, "protocol")?,
@@ -865,6 +1039,7 @@ fn map_operation_version_record(row: &PgRow) -> Result<OperationVersionRecord, R
Ok(OperationVersionRecord {
operation_id: operation_id.clone(),
workspace_id: WorkspaceId::new(row.try_get::<String, _>("workspace_id")?),
version,
status,
change_note: row.try_get("change_note")?,
@@ -918,6 +1093,7 @@ fn map_operation_version_record(row: &PgRow) -> Result<OperationVersionRecord, R
fn map_auth_profile(row: &PgRow) -> Result<AuthProfile, RegistryError> {
Ok(AuthProfile {
id: crank_core::AuthProfileId::new(row.try_get::<String, _>("id")?),
workspace_id: WorkspaceId::new(row.try_get::<String, _>("workspace_id")?),
name: row.try_get("name")?,
kind: deserialize_enum_text(&row.try_get::<String, _>("kind")?, "kind")?,
config: deserialize_json_value(row.try_get::<Json<Value>, _>("config_json")?.0)?,
@@ -1042,7 +1218,7 @@ mod tests {
ApiKeyHeaderAuthConfig, AuthConfig, AuthKind, AuthProfile, ConfigExport, ExecutionConfig,
ExportMode, GeneratedDraft, GeneratedDraftStatus, HttpMethod, OperationId, OperationStatus,
Protocol, RestTarget, RetryPolicy, Samples, SecretRef, Target, ToolDescription,
ToolExample,
ToolExample, WorkspaceId,
};
use crank_mapping::{MappingRule, MappingSet};
use crank_schema::{Schema, SchemaKind};
@@ -1059,6 +1235,10 @@ mod tests {
},
};
fn test_workspace_id() -> WorkspaceId {
WorkspaceId::new("ws_default")
}
#[tokio::test]
async fn stores_versions_and_published_operations() {
let database = TestDatabase::new().await;
@@ -1066,7 +1246,7 @@ mod tests {
let operation_v1 = test_operation("op_rest_01", 1, OperationStatus::Draft);
registry
.create_operation(&operation_v1, Some("alice"))
.create_operation(&test_workspace_id(), &operation_v1, Some("alice"))
.await
.unwrap();
@@ -1074,6 +1254,7 @@ mod tests {
registry
.create_version(CreateVersionRequest {
workspace_id: &test_workspace_id(),
snapshot: &operation_v2,
change_note: Some("add output mapping"),
created_by: Some("alice"),
@@ -1083,6 +1264,7 @@ mod tests {
registry
.publish_operation(PublishRequest {
workspace_id: &test_workspace_id(),
operation_id: &operation_v2.id,
version: operation_v2.version,
published_at: "2026-03-25T12:10:00Z",
@@ -1092,12 +1274,12 @@ mod tests {
.unwrap();
let summary = registry
.get_operation_summary(&operation_v2.id)
.get_operation_summary(&test_workspace_id(), &operation_v2.id)
.await
.unwrap()
.unwrap();
let versions = registry
.list_operation_versions(&operation_v2.id)
.list_operation_versions(&test_workspace_id(), &operation_v2.id)
.await
.unwrap();
let published = registry
@@ -1126,11 +1308,15 @@ mod tests {
let registry = database.registry().await;
let operation = test_operation("op_rest_02", 1, OperationStatus::Draft);
registry.create_operation(&operation, None).await.unwrap();
registry
.create_operation(&test_workspace_id(), &operation, None)
.await
.unwrap();
let invalid = test_operation("op_rest_02", 3, OperationStatus::Draft);
let error = registry
.create_version(CreateVersionRequest {
workspace_id: &test_workspace_id(),
snapshot: &invalid,
change_note: None,
created_by: None,
@@ -1156,10 +1342,14 @@ mod tests {
let registry = database.registry().await;
let operation = test_operation("op_rest_03", 1, OperationStatus::Draft);
registry.create_operation(&operation, None).await.unwrap();
registry
.create_operation(&test_workspace_id(), &operation, None)
.await
.unwrap();
let auth_profile = AuthProfile {
id: "auth_crank".into(),
workspace_id: test_workspace_id(),
name: "Crank API key".to_owned(),
kind: AuthKind::ApiKeyHeader,
config: AuthConfig::ApiKeyHeader(ApiKeyHeaderAuthConfig {
@@ -1172,6 +1362,7 @@ mod tests {
registry
.save_auth_profile(SaveAuthProfileRequest {
workspace_id: &test_workspace_id(),
profile: &auth_profile,
})
.await
@@ -1211,7 +1402,10 @@ mod tests {
.await
.unwrap();
let auth_profiles = registry.list_auth_profiles().await.unwrap();
let auth_profiles = registry
.list_auth_profiles(&test_workspace_id())
.await
.unwrap();
let samples = registry
.list_sample_metadata(&operation.id, 1)
.await
@@ -1235,7 +1429,10 @@ mod tests {
let job_id = YamlImportJobId::new("job_yaml_01");
let operation = test_operation("op_rest_04", 1, OperationStatus::Draft);
registry.create_operation(&operation, None).await.unwrap();
registry
.create_operation(&test_workspace_id(), &operation, None)
.await
.unwrap();
registry
.create_yaml_import_job(CreateYamlImportJobRequest {