feat: add integrations

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
2026-03-09 22:34:04 +01:00
parent 646581ff44
commit a6401e3b79
26 changed files with 3207 additions and 244 deletions

View File

@@ -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;
}
}
}