mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-23 19:46:42 +02:00
♻️ refactor: migrate calendar, picture, nutriphi, planta, questions, skilltree to shared-api-client
- Update all web apps to use @manacore/shared-api-client
- Remove calendar's local base-client.ts (duplicate of shared package)
- Calendar: update todos.ts and birthdays.ts to use shared client
- Maintain backward compatibility with existing patterns:
- picture: fetchApi, uploadFile, uploadFiles functions
- nutriphi: apiClient class with throw-based errors
- planta: fetchApi function with {data, error} format
- questions/skilltree: apiClient with setAccessToken pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
75b5fb2fae
commit
1e5175e522
16 changed files with 354 additions and 429 deletions
|
|
@ -36,6 +36,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@nutriphi/shared": "workspace:*",
|
||||
"@manacore/shared-api-client": "workspace:*",
|
||||
"@manacore/shared-auth": "workspace:*",
|
||||
"@manacore/shared-auth-ui": "workspace:*",
|
||||
"@manacore/shared-branding": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -1,68 +1,65 @@
|
|||
/**
|
||||
* API Client for NutriPhi backend
|
||||
* Uses @manacore/shared-api-client for consistent error handling
|
||||
*/
|
||||
|
||||
import { createApiClient, type ApiResult } from '@manacore/shared-api-client';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { PUBLIC_BACKEND_URL } from '$env/static/public';
|
||||
|
||||
const BASE_URL = PUBLIC_BACKEND_URL || 'http://localhost:3023';
|
||||
|
||||
/**
|
||||
* NutriPhi API client instance
|
||||
* - Auto token handling via authStore.getAccessToken()
|
||||
* - Consistent ApiResult<T> response format
|
||||
*/
|
||||
const api = createApiClient({
|
||||
baseUrl: BASE_URL,
|
||||
apiPrefix: '/api/v1',
|
||||
getAuthToken: () => authStore.getAccessToken(),
|
||||
timeout: 30000,
|
||||
debug: import.meta.env.DEV,
|
||||
});
|
||||
|
||||
/**
|
||||
* Legacy ApiClient class wrapper for backward compatibility
|
||||
* Maintains throw-based error handling for existing code
|
||||
*/
|
||||
class ApiClient {
|
||||
private async getHeaders(): Promise<HeadersInit> {
|
||||
const token = await authStore.getAccessToken();
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
async get<T>(path: string): Promise<T> {
|
||||
const response = await fetch(`${BASE_URL}/api/v1${path}`, {
|
||||
method: 'GET',
|
||||
headers: await this.getHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
const result = await api.get<T>(path);
|
||||
if (result.error) {
|
||||
throw new Error(result.error.message);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
async post<T>(path: string, data: unknown): Promise<T> {
|
||||
const response = await fetch(`${BASE_URL}/api/v1${path}`, {
|
||||
method: 'POST',
|
||||
headers: await this.getHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
const result = await api.post<T>(path, data);
|
||||
if (result.error) {
|
||||
throw new Error(result.error.message);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
async patch<T>(path: string, data: unknown): Promise<T> {
|
||||
const response = await fetch(`${BASE_URL}/api/v1${path}`, {
|
||||
method: 'PATCH',
|
||||
headers: await this.getHeaders(),
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
const result = await api.patch<T>(path, data);
|
||||
if (result.error) {
|
||||
throw new Error(result.error.message);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
return result.data as T;
|
||||
}
|
||||
|
||||
async delete(path: string): Promise<void> {
|
||||
const response = await fetch(`${BASE_URL}/api/v1${path}`, {
|
||||
method: 'DELETE',
|
||||
headers: await this.getHeaders(),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API Error: ${response.status}`);
|
||||
const result = await api.delete<void>(path);
|
||||
if (result.error) {
|
||||
throw new Error(result.error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const apiClient = new ApiClient();
|
||||
|
||||
// Re-export types for convenience
|
||||
export type { ApiResult };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue