Skip to content

Commit a1e10ba

Browse files
committed
feat: enhance project response handling with normalization for API compatibility
1 parent ad9185b commit a1e10ba

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

packages/ui-vite/src/lib/api.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,38 @@ export interface ProjectsResponse {
5959
available: Project[];
6060
}
6161

62+
// Axum HTTP server returns { projects, current_project_id } instead of { current, available }
63+
// so we normalize both shapes for the UI layer.
64+
export interface ProjectsListResponse {
65+
projects?: Project[];
66+
current_project_id?: string | null;
67+
currentProjectId?: string | null;
68+
current?: Project | null;
69+
available?: Project[];
70+
}
71+
72+
export function normalizeProjectsResponse(
73+
data: ProjectsResponse | ProjectsListResponse
74+
): ProjectsResponse {
75+
if ('projects' in data) {
76+
const projects = data.projects || [];
77+
const currentId = data.current_project_id || data.currentProjectId || null;
78+
const current = currentId
79+
? projects.find((project) => project.id === currentId) || null
80+
: null;
81+
82+
return {
83+
current,
84+
available: projects,
85+
};
86+
}
87+
88+
return {
89+
current: data.current || null,
90+
available: data.available || [],
91+
};
92+
}
93+
6294
class APIError extends Error {
6395
status: number;
6496

@@ -118,8 +150,8 @@ export const api = {
118150
},
119151

120152
async getProjects(): Promise<ProjectsResponse> {
121-
const data = await fetchAPI<ProjectsResponse>('/api/projects');
122-
return data;
153+
const data = await fetchAPI<ProjectsResponse | ProjectsListResponse>('/api/projects');
154+
return normalizeProjectsResponse(data);
123155
},
124156

125157
async switchProject(projectId: string): Promise<void> {

packages/ui-vite/src/lib/backend-adapter.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
// Backend adapter pattern for web (HTTP) vs desktop (Tauri IPC)
22
// This allows the same UI code to work in both browser and Tauri contexts
33

4-
import type { Spec, SpecDetail, Stats, DependencyGraph, Project, ProjectsResponse } from './api';
4+
import type {
5+
Spec,
6+
SpecDetail,
7+
Stats,
8+
DependencyGraph,
9+
Project,
10+
ProjectsResponse,
11+
ProjectsListResponse,
12+
} from './api';
13+
import { normalizeProjectsResponse } from './api';
514

615
export interface ListParams {
716
status?: string;
@@ -57,7 +66,8 @@ export class HttpBackendAdapter implements BackendAdapter {
5766
}
5867

5968
async getProjects(): Promise<ProjectsResponse> {
60-
return this.fetchAPI<ProjectsResponse>('/api/projects');
69+
const data = await this.fetchAPI<ProjectsResponse | ProjectsListResponse>('/api/projects');
70+
return normalizeProjectsResponse(data);
6171
}
6272

6373
async switchProject(projectId: string): Promise<void> {

0 commit comments

Comments
 (0)