refactor(web): extract shared API client factory, fix types, use crypto.randomUUID
- Created api-helpers.ts with shared getAccessToken() + createNotesApiClient() - Removed duplicate API client factory from notes-client.ts, review-client.ts, saved-views-client.ts (3 copies → 1 shared module) - Added reviewedBy/reviewedAt/reviewNote fields to review-client NoteAgentActionDoc type to match backend response shape - Search page: use crypto.randomUUID() for saved view IDs instead of Date.now() to prevent collisions on rapid saves Verification: web typecheck + 6/6 tests pass.
This commit is contained in:
parent
c6aa775cd3
commit
c2202e9e52
@ -46,7 +46,7 @@ export default function SearchPage() {
|
|||||||
if (!query.trim()) return;
|
if (!query.trim()) return;
|
||||||
try {
|
try {
|
||||||
const view = await createSavedView({
|
const view = await createSavedView({
|
||||||
id: `sv-${Date.now()}`,
|
id: crypto.randomUUID(),
|
||||||
name: query.trim().slice(0, 60),
|
name: query.trim().slice(0, 60),
|
||||||
scope: "search",
|
scope: "search",
|
||||||
query: query.trim(),
|
query: query.trim(),
|
||||||
|
|||||||
20
web/src/lib/api-helpers.ts
Normal file
20
web/src/lib/api-helpers.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { createApiClient } from "@bytelyst/api-client";
|
||||||
|
import { NOTES_API_URL, PRODUCT_ID } from "@/lib/product-config";
|
||||||
|
|
||||||
|
export function getAccessToken(): string | null {
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return localStorage.getItem(`${PRODUCT_ID}_access_token`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createNotesApiClient() {
|
||||||
|
return createApiClient({
|
||||||
|
baseUrl: NOTES_API_URL,
|
||||||
|
getToken: getAccessToken,
|
||||||
|
defaultHeaders: {
|
||||||
|
"x-product-id": PRODUCT_ID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { createApiClient } from "@bytelyst/api-client";
|
|
||||||
import { extractSuggestedTasks } from "@/lib/extraction-client";
|
import { extractSuggestedTasks } from "@/lib/extraction-client";
|
||||||
import { NOTES_API_URL, PRODUCT_ID } from "@/lib/product-config";
|
import { PRODUCT_ID } from "@/lib/product-config";
|
||||||
|
import { createNotesApiClient } from "@/lib/api-helpers";
|
||||||
import type { AgentTimelineItem, ArtifactSummary, LinkedNote, NoteDetail, NoteSummary, NoteTask, WorkspaceSummary } from "@/lib/types";
|
import type { AgentTimelineItem, ArtifactSummary, LinkedNote, NoteDetail, NoteSummary, NoteTask, WorkspaceSummary } from "@/lib/types";
|
||||||
|
|
||||||
type NoteDoc = {
|
type NoteDoc = {
|
||||||
@ -90,23 +90,6 @@ type NoteRelationshipListResponse = {
|
|||||||
items: NoteRelationshipDoc[];
|
items: NoteRelationshipDoc[];
|
||||||
};
|
};
|
||||||
|
|
||||||
function getAccessToken(): string | null {
|
|
||||||
if (typeof window === "undefined") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return localStorage.getItem(`${PRODUCT_ID}_access_token`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNotesApiClient() {
|
|
||||||
return createApiClient({
|
|
||||||
baseUrl: NOTES_API_URL,
|
|
||||||
getToken: getAccessToken,
|
|
||||||
defaultHeaders: {
|
|
||||||
"x-product-id": PRODUCT_ID,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildWorkspaceMap(workspaces: WorkspaceDoc[]) {
|
function buildWorkspaceMap(workspaces: WorkspaceDoc[]) {
|
||||||
return new Map(workspaces.map((workspace) => [workspace.id, workspace]));
|
return new Map(workspaces.map((workspace) => [workspace.id, workspace]));
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { createApiClient } from "@bytelyst/api-client";
|
import { createNotesApiClient } from "@/lib/api-helpers";
|
||||||
import { NOTES_API_URL, PRODUCT_ID } from "@/lib/product-config";
|
|
||||||
import type { AgentTimelineItem, ApprovalQueueItem } from "@/lib/types";
|
import type { AgentTimelineItem, ApprovalQueueItem } from "@/lib/types";
|
||||||
import { listWorkspaceSummaries } from "@/lib/notes-client";
|
import { listWorkspaceSummaries } from "@/lib/notes-client";
|
||||||
|
|
||||||
@ -15,6 +14,9 @@ type NoteAgentActionDoc = {
|
|||||||
reason?: string;
|
reason?: string;
|
||||||
beforeSummary?: string;
|
beforeSummary?: string;
|
||||||
afterSummary?: string;
|
afterSummary?: string;
|
||||||
|
reviewedBy?: string;
|
||||||
|
reviewedAt?: string;
|
||||||
|
reviewNote?: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,23 +24,6 @@ type NoteAgentActionListResponse = {
|
|||||||
items: NoteAgentActionDoc[];
|
items: NoteAgentActionDoc[];
|
||||||
};
|
};
|
||||||
|
|
||||||
function getAccessToken(): string | null {
|
|
||||||
if (typeof window === "undefined") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return localStorage.getItem(`${PRODUCT_ID}_access_token`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNotesApiClient() {
|
|
||||||
return createApiClient({
|
|
||||||
baseUrl: NOTES_API_URL,
|
|
||||||
getToken: getAccessToken,
|
|
||||||
defaultHeaders: {
|
|
||||||
"x-product-id": PRODUCT_ID,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toSeverity(actionType: NoteAgentActionDoc["actionType"]): ApprovalQueueItem["severity"] {
|
function toSeverity(actionType: NoteAgentActionDoc["actionType"]): ApprovalQueueItem["severity"] {
|
||||||
if (actionType === "update" || actionType === "extract_tasks") {
|
if (actionType === "update" || actionType === "extract_tasks") {
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { createApiClient } from "@bytelyst/api-client";
|
import { createNotesApiClient } from "@/lib/api-helpers";
|
||||||
import { NOTES_API_URL, PRODUCT_ID } from "@/lib/product-config";
|
|
||||||
|
|
||||||
export interface SavedView {
|
export interface SavedView {
|
||||||
id: string;
|
id: string;
|
||||||
@ -20,19 +19,6 @@ interface SavedViewListResponse {
|
|||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccessToken(): string | null {
|
|
||||||
if (typeof window === "undefined") return null;
|
|
||||||
return localStorage.getItem(`${PRODUCT_ID}_access_token`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNotesApiClient() {
|
|
||||||
return createApiClient({
|
|
||||||
baseUrl: NOTES_API_URL,
|
|
||||||
getToken: getAccessToken,
|
|
||||||
defaultHeaders: { "x-product-id": PRODUCT_ID },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function listSavedViews(scope?: SavedView["scope"]): Promise<SavedView[]> {
|
export async function listSavedViews(scope?: SavedView["scope"]): Promise<SavedView[]> {
|
||||||
const api = createNotesApiClient();
|
const api = createNotesApiClient();
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user