// ─── API Client mit Authentifizierungs-Interceptor ─── export class ApiClient { constructor() { this.token = sessionStorage.getItem('ibkr_token') || ''; this.onUnauthorized = null; } setToken(token) { this.token = token; if (token) { sessionStorage.setItem('ibkr_token', token); } else { sessionStorage.removeItem('ibkr_token'); } } hasToken() { return !!this.token; } async request(url, options = {}) { const headers = { 'Accept': 'application/json', ...options.headers }; if (this.token) { headers['Authorization'] = `Bearer ${this.token}`; } if (options.body && typeof options.body === 'object' && !(options.body instanceof FormData)) { headers['Content-Type'] = 'application/json'; options.body = JSON.stringify(options.body); } try { const response = await fetch(url, { ...options, headers }); if (response.status === 401) { if (this.onUnauthorized) { this.onUnauthorized(); } throw new Error('Authentifizierung erforderlich (401)'); } if (!response.ok) { let errMessage = `HTTP ${response.status}`; try { const errData = await response.json(); if (errData.error || errData.message) { errMessage = errData.error || errData.message; } } catch (_) {} throw new Error(errMessage); } const contentType = response.headers.get('content-type') || ''; if (contentType.includes('application/json')) { return await response.json(); } return response; } catch (err) { throw err; } } get(url) { return this.request(url, { method: 'GET' }); } post(url, body) { return this.request(url, { method: 'POST', body }); } } export const api = new ApiClient();