fix(auth): defer environment context fetch until token is available

This commit is contained in:
2026-02-25 20:58:14 +03:00
parent 4bad4ab4e2
commit 4d5b9e88dd
2 changed files with 27 additions and 10 deletions

View File

@@ -4,6 +4,7 @@
// @LAYER: UI-State // @LAYER: UI-State
import { derived, get, writable } from "svelte/store"; import { derived, get, writable } from "svelte/store";
import { browser } from "$app/environment";
import { api } from "$lib/api.js"; import { api } from "$lib/api.js";
const INITIAL_STATE = { const INITIAL_STATE = {
@@ -18,12 +19,12 @@ const SELECTED_ENV_KEY = "selected_env_id";
const contextStore = writable(INITIAL_STATE); const contextStore = writable(INITIAL_STATE);
function getStoredSelectedEnvId() { function getStoredSelectedEnvId() {
if (typeof window === "undefined") return ""; if (!browser) return "";
return localStorage.getItem(SELECTED_ENV_KEY) || ""; return localStorage.getItem(SELECTED_ENV_KEY) || "";
} }
function persistSelectedEnvId(envId) { function persistSelectedEnvId(envId) {
if (typeof window === "undefined") return; if (!browser) return;
if (!envId) { if (!envId) {
localStorage.removeItem(SELECTED_ENV_KEY); localStorage.removeItem(SELECTED_ENV_KEY);
return; return;
@@ -31,6 +32,11 @@ function persistSelectedEnvId(envId) {
localStorage.setItem(SELECTED_ENV_KEY, envId); localStorage.setItem(SELECTED_ENV_KEY, envId);
} }
function hasAuthToken() {
if (!browser) return false;
return Boolean(localStorage.getItem("auth_token"));
}
function resolveSelectedEnvId(environments, preferredEnvId) { function resolveSelectedEnvId(environments, preferredEnvId) {
if (!Array.isArray(environments) || environments.length === 0) return ""; if (!Array.isArray(environments) || environments.length === 0) return "";
if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) { if (preferredEnvId && environments.some((env) => env.id === preferredEnvId)) {
@@ -53,6 +59,16 @@ function applySelectedEnvId(selectedEnvId) {
} }
async function refreshEnvironmentContext(preferredEnvId = "") { async function refreshEnvironmentContext(preferredEnvId = "") {
if (!hasAuthToken()) {
contextStore.update((state) => ({
...state,
isLoading: false,
isLoaded: false,
error: null,
}));
return;
}
contextStore.update((state) => ({ ...state, isLoading: true, error: null })); contextStore.update((state) => ({ ...state, isLoading: true, error: null }));
try { try {
const environments = await api.getEnvironmentsList(); const environments = await api.getEnvironmentsList();
@@ -71,6 +87,15 @@ async function refreshEnvironmentContext(preferredEnvId = "") {
error: null, error: null,
})); }));
} catch (error) { } catch (error) {
if (error?.status === 401) {
contextStore.update((state) => ({
...state,
isLoading: false,
isLoaded: false,
error: null,
}));
return;
}
console.error( console.error(
"[environmentContext][Coherence:Failed] Failed to refresh environments", "[environmentContext][Coherence:Failed] Failed to refresh environments",
error, error,

View File

@@ -23,7 +23,6 @@
@INVARIANT: Login route bypasses shell; all other routes are wrapped by ProtectedRoute. @INVARIANT: Login route bypasses shell; all other routes are wrapped by ProtectedRoute.
--> -->
<script> <script>
import { onMount } from 'svelte';
import '../app.css'; import '../app.css';
import Navbar from '../components/Navbar.svelte'; import Navbar from '../components/Navbar.svelte';
import Footer from '../components/Footer.svelte'; import Footer from '../components/Footer.svelte';
@@ -36,7 +35,6 @@
import AssistantChatPanel from '$lib/components/assistant/AssistantChatPanel.svelte'; import AssistantChatPanel from '$lib/components/assistant/AssistantChatPanel.svelte';
import { t } from '$lib/i18n'; import { t } from '$lib/i18n';
import { import {
initializeEnvironmentContext,
isProductionContextStore, isProductionContextStore,
selectedEnvironmentStore selectedEnvironmentStore
} from '$lib/stores/environmentContext.js'; } from '$lib/stores/environmentContext.js';
@@ -47,12 +45,6 @@
$: isExpanded = $sidebarStore?.isExpanded || true; $: isExpanded = $sidebarStore?.isExpanded || true;
$: isProductionContext = $isProductionContextStore; $: isProductionContext = $isProductionContextStore;
$: selectedEnvironment = $selectedEnvironmentStore; $: selectedEnvironment = $selectedEnvironmentStore;
onMount(async () => {
if (!isLoginPage) {
await initializeEnvironmentContext();
}
});
</script> </script>
<Toast /> <Toast />