feat: persist current workspace in user sessions

This commit is contained in:
a.tolmachev
2026-03-31 15:17:07 +03:00
parent 84f4437ce0
commit 86b61523bd
15 changed files with 331 additions and 57 deletions
+8
View File
@@ -67,6 +67,7 @@ pub async fn apply_postgres(pool: &PgPool) -> Result<(), sqlx::Error> {
"create table if not exists user_sessions (
id text primary key,
user_id text not null references users(id) on delete cascade,
current_workspace_id text null references workspaces(id) on delete set null,
secret_hash text not null,
status text not null,
expires_at timestamptz not null,
@@ -77,6 +78,13 @@ pub async fn apply_postgres(pool: &PgPool) -> Result<(), sqlx::Error> {
.execute(pool)
.await?;
query(
"alter table user_sessions
add column if not exists current_workspace_id text null references workspaces(id) on delete set null",
)
.execute(pool)
.await?;
query(
"insert into workspaces (
id,
+1
View File
@@ -72,6 +72,7 @@ pub struct SessionRecord {
pub session_id: UserSessionId,
pub user: User,
pub memberships: Vec<WorkspaceMembershipRecord>,
pub current_workspace_id: Option<WorkspaceId>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+39 -1
View File
@@ -257,6 +257,7 @@ impl PostgresRegistry {
&self,
session_id: &UserSessionId,
user_id: &UserId,
current_workspace_id: Option<&WorkspaceId>,
secret_hash: &str,
expires_at: &str,
) -> Result<(), RegistryError> {
@@ -264,6 +265,7 @@ impl PostgresRegistry {
"insert into user_sessions (
id,
user_id,
current_workspace_id,
secret_hash,
status,
expires_at,
@@ -273,14 +275,16 @@ impl PostgresRegistry {
$1,
$2,
$3,
$4,
'active',
$4::timestamptz,
$5::timestamptz,
now(),
now()
)",
)
.bind(session_id.as_str())
.bind(user_id.as_str())
.bind(current_workspace_id.map(|id| id.as_str()))
.bind(secret_hash)
.bind(expires_at)
.execute(&self.pool)
@@ -298,6 +302,7 @@ impl PostgresRegistry {
"select
s.id,
s.user_id,
s.current_workspace_id,
u.email,
u.display_name,
u.status,
@@ -328,11 +333,26 @@ impl PostgresRegistry {
created_at: row.try_get("created_at")?,
};
let memberships = self.list_workspaces_for_user(&user_id).await?;
let stored_workspace_id = row
.try_get::<Option<String>, _>("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())
});
Ok(Some(SessionRecord {
session_id: UserSessionId::new(row.try_get::<String, _>("id")?),
user,
memberships,
current_workspace_id,
}))
}
@@ -368,6 +388,24 @@ impl PostgresRegistry {
Ok(())
}
pub async fn set_user_session_current_workspace(
&self,
session_id: &UserSessionId,
workspace_id: &WorkspaceId,
) -> Result<(), RegistryError> {
sqlx::query(
"update user_sessions
set current_workspace_id = $2
where id = $1",
)
.bind(session_id.as_str())
.bind(workspace_id.as_str())
.execute(&self.pool)
.await?;
Ok(())
}
pub async fn user_has_workspace_access(
&self,
user_id: &UserId,