Fix workspace selection and secret modal layout
This commit is contained in:
@@ -272,17 +272,23 @@ impl PostgresRegistry {
|
||||
};
|
||||
let memberships = self.list_workspaces_for_user(&user_id).await?;
|
||||
let stored_workspace_id = row.current_workspace_id.map(WorkspaceId::new);
|
||||
let current_workspace_id = stored_workspace_id
|
||||
.filter(|workspace_id| {
|
||||
memberships
|
||||
.iter()
|
||||
.any(|membership| membership.workspace.id == *workspace_id)
|
||||
})
|
||||
.or_else(|| {
|
||||
memberships
|
||||
.first()
|
||||
.map(|membership| membership.workspace.id.clone())
|
||||
});
|
||||
let default_workspace_id = memberships
|
||||
.iter()
|
||||
.find(|membership| membership.workspace.id.as_str() == "ws_default")
|
||||
.map(|membership| membership.workspace.id.clone());
|
||||
let current_workspace_id = default_workspace_id.or_else(|| {
|
||||
stored_workspace_id
|
||||
.filter(|workspace_id| {
|
||||
memberships
|
||||
.iter()
|
||||
.any(|membership| membership.workspace.id == *workspace_id)
|
||||
})
|
||||
.or_else(|| {
|
||||
memberships
|
||||
.first()
|
||||
.map(|membership| membership.workspace.id.clone())
|
||||
})
|
||||
});
|
||||
|
||||
Ok(Some(SessionRecord {
|
||||
session_id: UserSessionId::new(row.id),
|
||||
|
||||
@@ -38,22 +38,22 @@ impl PostgresRegistry {
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
) -> Result<Vec<WorkspaceMembershipRecord>, RegistryError> {
|
||||
let rows = sqlx::query!(
|
||||
let rows = sqlx::query(
|
||||
"select
|
||||
w.id,
|
||||
w.slug,
|
||||
w.display_name,
|
||||
w.status,
|
||||
w.settings_json,
|
||||
w.created_at as \"created_at!: time::OffsetDateTime\",
|
||||
w.updated_at as \"updated_at!: time::OffsetDateTime\",
|
||||
w.created_at,
|
||||
w.updated_at,
|
||||
m.role
|
||||
from memberships m
|
||||
join workspaces w on w.id = m.workspace_id
|
||||
where m.user_id = $1
|
||||
order by w.slug asc",
|
||||
user_id.as_str(),
|
||||
order by (w.id = 'ws_default') desc, w.slug asc",
|
||||
)
|
||||
.bind(user_id.as_str())
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
@@ -61,15 +61,18 @@ impl PostgresRegistry {
|
||||
.map(|row| {
|
||||
Ok(WorkspaceMembershipRecord {
|
||||
workspace: Workspace {
|
||||
id: WorkspaceId::new(row.id),
|
||||
slug: row.slug,
|
||||
display_name: row.display_name,
|
||||
status: deserialize_enum_text(&row.status, "status")?,
|
||||
settings: row.settings_json,
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at,
|
||||
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("settings_json")?,
|
||||
created_at: row.try_get("created_at")?,
|
||||
updated_at: row.try_get("updated_at")?,
|
||||
},
|
||||
role: deserialize_enum_text(&row.role, "role")?,
|
||||
role: deserialize_enum_text(&row.try_get::<String, _>("role")?, "role")?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -24,7 +24,8 @@ use crank_registry::{
|
||||
DescriptorMetadata, OperationSampleMetadata, PlatformApiKeyRecord, PostgresRegistry,
|
||||
PublishAgentRequest, PublishRequest, RegistryError, RegistryOperation, SampleKind,
|
||||
SaveAuthProfileRequest, SaveDescriptorMetadataRequest, SaveSampleMetadataRequest,
|
||||
WorkspaceRecord, YamlImportJobCompletion, YamlImportJobId, YamlImportJobStatus,
|
||||
UpdateWorkspaceRequest, WorkspaceRecord, YamlImportJobCompletion, YamlImportJobId,
|
||||
YamlImportJobStatus,
|
||||
};
|
||||
|
||||
fn test_workspace_id() -> WorkspaceId {
|
||||
@@ -151,6 +152,85 @@ async fn manages_workspace_read_paths() {
|
||||
database.cleanup().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn lists_default_workspace_first_for_community_sessions() {
|
||||
let database = TestDatabase::new().await;
|
||||
let registry = database.registry().await;
|
||||
let default_workspace = Workspace {
|
||||
id: WorkspaceId::new("ws_default"),
|
||||
slug: "solo".to_owned(),
|
||||
display_name: "Solo".to_owned(),
|
||||
status: crank_core::WorkspaceStatus::Active,
|
||||
settings: json!({}),
|
||||
created_at: timestamp("2026-03-25T12:00:00Z"),
|
||||
updated_at: timestamp("2026-03-25T12:00:00Z"),
|
||||
};
|
||||
let legacy_workspace = Workspace {
|
||||
id: WorkspaceId::new("ws_growth_lab"),
|
||||
slug: "growth-lab".to_owned(),
|
||||
display_name: "Growth Lab".to_owned(),
|
||||
status: crank_core::WorkspaceStatus::Active,
|
||||
settings: json!({}),
|
||||
created_at: timestamp("2026-03-25T12:01:00Z"),
|
||||
updated_at: timestamp("2026-03-25T12:01:00Z"),
|
||||
};
|
||||
let user_id = registry
|
||||
.upsert_bootstrap_user("community-owner@example.com", "Owner", "hashed-password")
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
registry
|
||||
.create_workspace(CreateWorkspaceRequest {
|
||||
workspace: &legacy_workspace,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
registry
|
||||
.update_workspace(UpdateWorkspaceRequest {
|
||||
workspace: &default_workspace,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
registry
|
||||
.ensure_membership(&legacy_workspace.id, &user_id, MembershipRole::Owner)
|
||||
.await
|
||||
.unwrap();
|
||||
registry
|
||||
.ensure_membership(&default_workspace.id, &user_id, MembershipRole::Owner)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let workspaces = registry.list_workspaces_for_user(&user_id).await.unwrap();
|
||||
|
||||
assert_eq!(workspaces[0].workspace.id, WorkspaceId::new("ws_default"));
|
||||
assert_eq!(workspaces[0].workspace.slug, "solo");
|
||||
|
||||
let session_id = UserSessionId::new("sess_workspace_default_first");
|
||||
let secret_hash = "test-secret-hash";
|
||||
registry
|
||||
.create_user_session(
|
||||
&session_id,
|
||||
&user_id,
|
||||
Some(&legacy_workspace.id),
|
||||
secret_hash,
|
||||
×tamp("2027-03-25T13:00:00Z"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let session = registry
|
||||
.get_user_session(&session_id, secret_hash)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
session.current_workspace_id,
|
||||
Some(WorkspaceId::new("ws_default"))
|
||||
);
|
||||
|
||||
database.cleanup().await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn manages_user_profile_and_workspace_access_reads() {
|
||||
let database = TestDatabase::new().await;
|
||||
|
||||
Reference in New Issue
Block a user