@@ -69,19 +69,28 @@ impl FromRequestParts<AppState> for Session {
|
||||
.get_user(&session_data.access_token)
|
||||
.await
|
||||
{
|
||||
let orgs = state
|
||||
// Preserve existing orgs on failure — a transient gRPC error
|
||||
// should not wipe the cached org list.
|
||||
let previous_orgs = session_data
|
||||
.user
|
||||
.as_ref()
|
||||
.map(|u| u.orgs.clone())
|
||||
.unwrap_or_default();
|
||||
let orgs = match state
|
||||
.platform_client
|
||||
.list_my_organisations(&session_data.access_token)
|
||||
.await
|
||||
.ok()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|o| CachedOrg {
|
||||
organisation_id: o.organisation_id,
|
||||
name: o.name,
|
||||
role: o.role,
|
||||
})
|
||||
.collect();
|
||||
{
|
||||
Ok(fresh) => fresh
|
||||
.into_iter()
|
||||
.map(|o| CachedOrg {
|
||||
organisation_id: o.organisation_id,
|
||||
name: o.name,
|
||||
role: o.role,
|
||||
})
|
||||
.collect(),
|
||||
Err(_) => previous_orgs,
|
||||
};
|
||||
session_data.user = Some(CachedUser {
|
||||
user_id: user.user_id.clone(),
|
||||
username: user.username.clone(),
|
||||
@@ -99,11 +108,46 @@ impl FromRequestParts<AppState> for Session {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Throttle last_seen_at writes: only update if older than 5 minutes
|
||||
let now = chrono::Utc::now();
|
||||
if now - session_data.last_seen_at > chrono::Duration::minutes(5) {
|
||||
session_data.last_seen_at = now;
|
||||
let _ = state.sessions.update(&session_id, session_data.clone()).await;
|
||||
// Backfill: if we have a user but empty orgs, try to fetch them.
|
||||
// This handles the case where list_my_organisations failed during login.
|
||||
let needs_org_backfill = session_data
|
||||
.user
|
||||
.as_ref()
|
||||
.is_some_and(|u| u.orgs.is_empty());
|
||||
|
||||
if needs_org_backfill {
|
||||
if let Ok(orgs) = state
|
||||
.platform_client
|
||||
.list_my_organisations(&session_data.access_token)
|
||||
.await
|
||||
{
|
||||
if !orgs.is_empty() {
|
||||
if let Some(ref mut user) = session_data.user {
|
||||
tracing::info!(
|
||||
user_id = %user.user_id,
|
||||
org_count = orgs.len(),
|
||||
"backfilled empty org list"
|
||||
);
|
||||
user.orgs = orgs
|
||||
.into_iter()
|
||||
.map(|o| CachedOrg {
|
||||
organisation_id: o.organisation_id,
|
||||
name: o.name,
|
||||
role: o.role,
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
session_data.last_seen_at = chrono::Utc::now();
|
||||
let _ = state.sessions.update(&session_id, session_data.clone()).await;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Throttle last_seen_at writes: only update if older than 5 minutes
|
||||
let now = chrono::Utc::now();
|
||||
if now - session_data.last_seen_at > chrono::Duration::minutes(5) {
|
||||
session_data.last_seen_at = now;
|
||||
let _ = state.sessions.update(&session_id, session_data.clone()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user