DocDoeAI / src /lib /api /student-workspace.ts
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
4.03 kB
import { ApiError, apiDelete, apiFetch } from "@/lib/api/client";
import type { StudyChatEvidence } from "@/lib/api/chat";
export type WorkspaceClass = {
id: string;
name: string;
subject: string;
board: string | null;
grade: string | null;
availability: "curated" | "notes_only" | "locked" | "coming_soon";
chapter_count: number;
href: string | null;
updated_at: string;
};
export type WorkspaceTask = {
id: string;
title: string;
subject: string | null;
kind:
| "new_lesson"
| "continue_lesson"
| "revision"
| "mistake_repair"
| "quiz"
| "pyq_practice"
| "board_answer_practice"
| "recap"
| "continue_course"
| "chat_follow_up"
| "lesson"
| "practice"
| "test"
| "note"
| "upload"
| "repair";
status: "pending" | "completed" | "missed" | "skipped";
duration_minutes: number | null;
due_at: string | null;
href: string | null;
source_id: string | null;
created_at: string;
completed_at: string | null;
};
export type WorkspaceNote = {
id: string;
title: string;
body: string;
subject: string | null;
topic: string | null;
source_id: string | null;
source_label: string | null;
chat_session_id?: string | null;
source_message_id?: string | null;
evidence?: StudyChatEvidence | null;
favorite: boolean;
created_at: string;
updated_at: string;
};
export type WorkspaceTestAttempt = {
id: string;
title: string;
subject: string | null;
score: number;
max_score: number;
correct_answers: number;
total_questions: number;
source_id: string | null;
completed_at: string;
};
export type WorkspacePyqAnalysis = {
id: string;
file_name: string;
subject: string | null;
year: number | null;
total_questions: number;
source_id: string | null;
summary: string | null;
analyzed_at: string;
};
export type WorkspaceBookmark = {
id: string;
kind: "lesson" | "note" | "chat" | "roadmap" | "test" | "pyq" | "source";
title: string;
href: string;
description: string | null;
context_id: string | null;
created_at: string;
};
export type WorkspaceNotification = {
id: string;
title: string;
body: string;
kind: "info" | "success" | "warning" | "action";
href: string | null;
created_at: string;
read_at: string | null;
};
export type StudentWorkspaceData = {
classes: WorkspaceClass[];
tasks: WorkspaceTask[];
notes: WorkspaceNote[];
test_attempts: WorkspaceTestAttempt[];
pyq_analyses: WorkspacePyqAnalysis[];
bookmarks: WorkspaceBookmark[];
notifications: WorkspaceNotification[];
preferences: {
language: string | null;
compact_mode: boolean;
assistant_enabled: boolean;
study_reminders_enabled: boolean;
dismissed_notification_ids: string[];
};
};
export type StudentWorkspaceRecord = {
id: string;
user_id: string;
revision: number;
data: StudentWorkspaceData;
created_at: string;
updated_at: string;
};
export const EMPTY_STUDENT_WORKSPACE: StudentWorkspaceData = {
classes: [],
tasks: [],
notes: [],
test_attempts: [],
pyq_analyses: [],
bookmarks: [],
notifications: [],
preferences: {
language: null,
compact_mode: false,
assistant_enabled: true,
study_reminders_enabled: true,
dismissed_notification_ids: [],
},
};
export async function getStudentWorkspace(): Promise<StudentWorkspaceRecord | null> {
try {
return await apiFetch<StudentWorkspaceRecord | null>(
"/student-workspace/me?optional=true",
);
} catch (error) {
if (error instanceof ApiError && error.status === 404) return null;
throw error;
}
}
export function saveStudentWorkspace(
data: StudentWorkspaceData,
expectedRevision: number,
): Promise<StudentWorkspaceRecord> {
return apiFetch<StudentWorkspaceRecord>("/student-workspace/me", {
method: "PUT",
body: JSON.stringify({ expected_revision: expectedRevision, data }),
});
}
export function deleteStudentWorkspace(): Promise<void> {
return apiDelete<void>("/student-workspace/me");
}