feat(frontend): session mutation + documents API client and types
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
import { http, HttpResponse } from "msw";
|
import { http, HttpResponse } from "msw";
|
||||||
import { server } from "../test/msw";
|
import { server } from "../test/msw";
|
||||||
import { createSession, listSessions } from "./sessions";
|
import { createSession, listSessions } from "./sessions";
|
||||||
|
import {
|
||||||
|
renameSession, setSessionGroup, archiveSession, unarchiveSession,
|
||||||
|
deleteSession, getSessionDocuments,
|
||||||
|
} from "./sessions";
|
||||||
|
|
||||||
test("createSession POSTs only {question} and returns the id", async () => {
|
test("createSession POSTs only {question} and returns the id", async () => {
|
||||||
let body: unknown = null;
|
let body: unknown = null;
|
||||||
@@ -19,3 +23,44 @@ test("listSessions GETs the array", async () => {
|
|||||||
const rows = await listSessions();
|
const rows = await listSessions();
|
||||||
expect(rows[0].id).toBe("s1");
|
expect(rows[0].id).toBe("s1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("renameSession POSTs {name}", async () => {
|
||||||
|
let body: unknown = null;
|
||||||
|
server.use(http.post("http://localhost:8787/sessions/s1/rename", async ({ request }) => {
|
||||||
|
body = await request.json();
|
||||||
|
return new HttpResponse(null, { status: 204 });
|
||||||
|
}));
|
||||||
|
await renameSession("s1", "Nome");
|
||||||
|
expect(body).toEqual({ name: "Nome" });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("setSessionGroup POSTs {group}", async () => {
|
||||||
|
let body: unknown = null;
|
||||||
|
server.use(http.post("http://localhost:8787/sessions/s1/group", async ({ request }) => {
|
||||||
|
body = await request.json();
|
||||||
|
return new HttpResponse(null, { status: 204 });
|
||||||
|
}));
|
||||||
|
await setSessionGroup("s1", "G");
|
||||||
|
expect(body).toEqual({ group: "G" });
|
||||||
|
});
|
||||||
|
|
||||||
|
test("archive / unarchive / delete hit the right verbs+paths", async () => {
|
||||||
|
const hits: string[] = [];
|
||||||
|
server.use(
|
||||||
|
http.post("http://localhost:8787/sessions/s1/archive", () => { hits.push("archive"); return new HttpResponse(null, { status: 204 }); }),
|
||||||
|
http.post("http://localhost:8787/sessions/s1/unarchive", () => { hits.push("unarchive"); return new HttpResponse(null, { status: 204 }); }),
|
||||||
|
http.delete("http://localhost:8787/sessions/s1", () => { hits.push("delete"); return new HttpResponse(null, { status: 204 }); }),
|
||||||
|
);
|
||||||
|
await archiveSession("s1");
|
||||||
|
await unarchiveSession("s1");
|
||||||
|
await deleteSession("s1");
|
||||||
|
expect(hits).toEqual(["archive", "unarchive", "delete"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("getSessionDocuments GETs the array", async () => {
|
||||||
|
server.use(http.get("http://localhost:8787/sessions/s1/documents", () =>
|
||||||
|
HttpResponse.json([{ phase: "—", key: "question", title: "t", format: "text", content: "q" }]),
|
||||||
|
));
|
||||||
|
const docs = await getSessionDocuments("s1");
|
||||||
|
expect(docs[0].key).toBe("question");
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { apiFetch } from "./client";
|
import { apiFetch } from "./client";
|
||||||
import type { SessionSummary, UiResponse } from "./types";
|
import type { SessionSummary, SessionDocument, UiResponse } from "./types";
|
||||||
|
|
||||||
export const createSession = (i: { question: string; name?: string }) =>
|
export const createSession = (i: { question: string; name?: string }) =>
|
||||||
apiFetch<{ id: string }>("/sessions", { method: "POST", body: JSON.stringify(i) });
|
apiFetch<{ id: string }>("/sessions", { method: "POST", body: JSON.stringify(i) });
|
||||||
@@ -26,3 +26,21 @@ export const closeSession = (id: string) =>
|
|||||||
|
|
||||||
export const resumeSession = (id: string) =>
|
export const resumeSession = (id: string) =>
|
||||||
apiFetch<void>(`/sessions/${id}/resume`, { method: "POST" });
|
apiFetch<void>(`/sessions/${id}/resume`, { method: "POST" });
|
||||||
|
|
||||||
|
export const renameSession = (id: string, name: string) =>
|
||||||
|
apiFetch<void>(`/sessions/${id}/rename`, { method: "POST", body: JSON.stringify({ name }) });
|
||||||
|
|
||||||
|
export const setSessionGroup = (id: string, group: string) =>
|
||||||
|
apiFetch<void>(`/sessions/${id}/group`, { method: "POST", body: JSON.stringify({ group }) });
|
||||||
|
|
||||||
|
export const archiveSession = (id: string) =>
|
||||||
|
apiFetch<void>(`/sessions/${id}/archive`, { method: "POST" });
|
||||||
|
|
||||||
|
export const unarchiveSession = (id: string) =>
|
||||||
|
apiFetch<void>(`/sessions/${id}/unarchive`, { method: "POST" });
|
||||||
|
|
||||||
|
export const deleteSession = (id: string) =>
|
||||||
|
apiFetch<void>(`/sessions/${id}`, { method: "DELETE" });
|
||||||
|
|
||||||
|
export const getSessionDocuments = (id: string) =>
|
||||||
|
apiFetch<SessionDocument[]>(`/sessions/${id}/documents`);
|
||||||
|
|||||||
@@ -47,6 +47,17 @@ export interface SessionSummary {
|
|||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string | null;
|
updated_at: string | null;
|
||||||
author: string | null;
|
author: string | null;
|
||||||
|
name: string | null;
|
||||||
|
group: string | null;
|
||||||
|
archived: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SessionDocument {
|
||||||
|
phase: string;
|
||||||
|
key: string;
|
||||||
|
title: string;
|
||||||
|
format: "markdown" | "sql" | "schema-linking" | "decisions" | "text";
|
||||||
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PreviewResult {
|
export interface PreviewResult {
|
||||||
|
|||||||
Reference in New Issue
Block a user