Make project service resilient with timeout and localStorage fallback
cgen-0a88274abfc64dc5b2fc449daf876ffe
This commit is contained in:
parent
85340a094f
commit
38367daebe
1 changed files with 97 additions and 37 deletions
|
|
@ -243,68 +243,128 @@ export const aethexUserService = {
|
|||
// Project Services
|
||||
export const aethexProjectService = {
|
||||
async getUserProjects(userId: string): Promise<AethexProject[]> {
|
||||
const { data, error } = await supabase
|
||||
.from("projects")
|
||||
.select("*")
|
||||
.eq("user_id", userId)
|
||||
.order("created_at", { ascending: false });
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from("projects")
|
||||
.select("*")
|
||||
.eq("user_id", userId)
|
||||
.order("created_at", { ascending: false });
|
||||
|
||||
if (error) {
|
||||
console.warn("Error fetching projects:", error);
|
||||
return [];
|
||||
if (!error && Array.isArray(data)) {
|
||||
return data as AethexProject[];
|
||||
}
|
||||
|
||||
if (error) console.warn("Error fetching projects:", error);
|
||||
} catch (err) {
|
||||
console.warn("Exception fetching projects, using local fallback:", err);
|
||||
}
|
||||
|
||||
return data as AethexProject[];
|
||||
try {
|
||||
const raw = localStorage.getItem("mock_projects");
|
||||
const all = raw ? (JSON.parse(raw) as AethexProject[]) : [];
|
||||
return all.filter((p) => p.user_id === userId).sort((a, b) => (b.created_at || "").localeCompare(a.created_at || ""));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
async createProject(
|
||||
project: Omit<AethexProject, "id" | "created_at" | "updated_at">,
|
||||
): Promise<AethexProject | null> {
|
||||
const { data, error } = await supabase
|
||||
.from("projects")
|
||||
.insert(project)
|
||||
.select()
|
||||
.single();
|
||||
try {
|
||||
const supabasePromise = supabase
|
||||
.from("projects")
|
||||
.insert(project)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
console.warn("Error creating project:", error);
|
||||
throw error;
|
||||
const timeout = new Promise<any>((resolve) =>
|
||||
setTimeout(() => resolve({ data: null, error: new Error("timeout") }), 6000)
|
||||
);
|
||||
|
||||
const { data, error } = await (Promise.race([supabasePromise as any, timeout]) as Promise<any>);
|
||||
|
||||
if (!error && data) {
|
||||
return data as AethexProject;
|
||||
}
|
||||
|
||||
if (error) console.warn("Create project failed or timed out, using local fallback:", error?.message || error);
|
||||
} catch (err: any) {
|
||||
console.warn("Create project exception, using local fallback:", err?.message || err);
|
||||
}
|
||||
|
||||
return data as AethexProject;
|
||||
const now = new Date().toISOString();
|
||||
const localProject: AethexProject = {
|
||||
...(project as any),
|
||||
id: `local_${Date.now()}_${Math.random().toString(36).slice(2)}`,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
} as AethexProject;
|
||||
|
||||
try {
|
||||
const raw = localStorage.getItem("mock_projects");
|
||||
const list: AethexProject[] = raw ? JSON.parse(raw) : [];
|
||||
list.unshift(localProject);
|
||||
localStorage.setItem("mock_projects", JSON.stringify(list));
|
||||
} catch {}
|
||||
|
||||
return localProject;
|
||||
},
|
||||
|
||||
async updateProject(
|
||||
projectId: string,
|
||||
updates: Partial<AethexProject>,
|
||||
): Promise<AethexProject | null> {
|
||||
const { data, error } = await supabase
|
||||
.from("projects")
|
||||
.update(updates)
|
||||
.eq("id", projectId)
|
||||
.select()
|
||||
.single();
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from("projects")
|
||||
.update(updates)
|
||||
.eq("id", projectId)
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
console.warn("Error updating project:", error);
|
||||
throw error;
|
||||
if (!error && data) return data as AethexProject;
|
||||
if (error) console.warn("Error updating project:", error);
|
||||
} catch (err) {
|
||||
console.warn("Exception updating project, using local fallback:", err);
|
||||
}
|
||||
|
||||
return data as AethexProject;
|
||||
try {
|
||||
const raw = localStorage.getItem("mock_projects");
|
||||
const list: AethexProject[] = raw ? JSON.parse(raw) : [];
|
||||
const idx = list.findIndex((p) => (p as any).id === projectId);
|
||||
if (idx >= 0) {
|
||||
const updated = { ...list[idx], ...updates, updated_at: new Date().toISOString() } as AethexProject;
|
||||
list[idx] = updated;
|
||||
localStorage.setItem("mock_projects", JSON.stringify(list));
|
||||
return updated;
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
async deleteProject(projectId: string): Promise<boolean> {
|
||||
const { error } = await supabase
|
||||
.from("projects")
|
||||
.delete()
|
||||
.eq("id", projectId);
|
||||
|
||||
if (error) {
|
||||
console.warn("Error deleting project:", error);
|
||||
return false;
|
||||
try {
|
||||
const { error } = await supabase
|
||||
.from("projects")
|
||||
.delete()
|
||||
.eq("id", projectId);
|
||||
if (!error) return true;
|
||||
if (error) console.warn("Error deleting project:", error);
|
||||
} catch (err) {
|
||||
console.warn("Exception deleting project, using local fallback:", err);
|
||||
}
|
||||
|
||||
return true;
|
||||
try {
|
||||
const raw = localStorage.getItem("mock_projects");
|
||||
const list: AethexProject[] = raw ? JSON.parse(raw) : [];
|
||||
const next = list.filter((p) => (p as any).id !== projectId);
|
||||
localStorage.setItem("mock_projects", JSON.stringify(next));
|
||||
return true;
|
||||
} catch {}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
async getAllProjects(limit = 10): Promise<AethexProject[]> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue