feat(rename): complete searchSpace to workspace transition across frontend and backend

- Introduced a comprehensive specification for renaming `searchSpace` to `workspace` in `surfsense_web` and `surfsense_desktop`, ensuring all TypeScript identifiers, React props, and local data structures are updated.
- Implemented migration shims for persisted local state to prevent data loss during the transition.
- Updated observability metrics and IPC channels to reflect the new naming convention.
- Removed legacy `active-search-space` module and replaced it with `active-workspace` to maintain consistency.
- Ensured no behavioral changes or data loss for users during the renaming process.
This commit is contained in:
Anish Sarkar 2026-07-06 15:12:40 +05:30
parent 2a020629c5
commit a8c1fb660d
259 changed files with 5480 additions and 2285 deletions

View file

@ -146,7 +146,7 @@ export function EditorPanelContent({
documentId,
localFilePath,
memoryScope,
searchSpaceId,
workspaceId,
title,
onClose,
}: {
@ -154,7 +154,7 @@ export function EditorPanelContent({
documentId?: number;
localFilePath?: string;
memoryScope?: "user" | "team";
searchSpaceId?: number;
workspaceId?: number;
title: string | null;
onClose?: () => void;
}) {
@ -186,14 +186,14 @@ export function EditorPanelContent({
}
try {
const mounts = (await electronAPI.getAgentFilesystemMounts(
searchSpaceId
workspaceId
)) as AgentFilesystemMount[];
return normalizeLocalVirtualPathForEditor(candidatePath, mounts);
} catch {
return candidatePath;
}
},
[electronAPI, searchSpaceId]
[electronAPI, workspaceId]
);
const plateMaxBytes = editorDoc?.editor_plate_max_bytes ?? LARGE_DOCUMENT_THRESHOLD;
@ -234,7 +234,7 @@ export function EditorPanelContent({
const resolvedLocalPath = await resolveLocalVirtualPath(localFilePath);
const readResult = await electronAPI.readAgentLocalFileText(
resolvedLocalPath,
searchSpaceId
workspaceId
);
if (!readResult.ok) {
throw new Error(readResult.error || "Failed to read local file");
@ -257,7 +257,7 @@ export function EditorPanelContent({
if (!memoryScope) throw new Error("Missing memory context");
const { document, limits } = await fetchMemoryEditorDocument({
scope: memoryScope,
searchSpaceId,
workspaceId,
title,
signal: controller.signal,
});
@ -271,12 +271,12 @@ export function EditorPanelContent({
return;
}
if (!documentId || !searchSpaceId) {
if (!documentId || !workspaceId) {
throw new Error("Missing document context");
}
const response = await authenticatedFetch(
buildBackendUrl(
`/api/v1/workspaces/${searchSpaceId}/documents/${documentId}/editor-content`
`/api/v1/workspaces/${workspaceId}/documents/${documentId}/editor-content`
),
{ method: "GET" }
);
@ -323,7 +323,7 @@ export function EditorPanelContent({
localFilePath,
memoryScope,
resolveLocalVirtualPath,
searchSpaceId,
workspaceId,
title,
]);
@ -382,7 +382,7 @@ export function EditorPanelContent({
const writeResult = await electronAPI.writeAgentLocalFileText(
resolvedLocalPath,
contentToSave,
searchSpaceId
workspaceId
);
if (!writeResult.ok) {
throw new Error(writeResult.error || "Failed to save local file");
@ -395,7 +395,7 @@ export function EditorPanelContent({
if (!memoryScope) throw new Error("Missing memory context");
const { markdown: savedContent, limits } = await saveMemoryMarkdown({
scope: memoryScope,
searchSpaceId,
workspaceId,
markdown: markdownRef.current,
});
markdownRef.current = savedContent;
@ -408,11 +408,11 @@ export function EditorPanelContent({
return true;
}
if (!searchSpaceId || !documentId) {
if (!workspaceId || !documentId) {
throw new Error("Missing document context");
}
const response = await authenticatedFetch(
buildBackendUrl(`/api/v1/workspaces/${searchSpaceId}/documents/${documentId}/save`),
buildBackendUrl(`/api/v1/workspaces/${workspaceId}/documents/${documentId}/save`),
{
method: "POST",
headers: { "Content-Type": "application/json" },
@ -460,7 +460,7 @@ export function EditorPanelContent({
plateMaxBytes,
plateMaxLines,
resolveLocalVirtualPath,
searchSpaceId,
workspaceId,
]
);
@ -515,12 +515,12 @@ export function EditorPanelContent({
}, [editorDoc?.source_markdown]);
const handleDownloadMarkdown = useCallback(async () => {
if (!searchSpaceId || !documentId) return;
if (!workspaceId || !documentId) return;
setDownloading(true);
try {
const response = await authenticatedFetch(
buildBackendUrl(
`/api/v1/workspaces/${searchSpaceId}/documents/${documentId}/download-markdown`
`/api/v1/workspaces/${workspaceId}/documents/${documentId}/download-markdown`
),
{ method: "GET" }
);
@ -542,7 +542,7 @@ export function EditorPanelContent({
} finally {
setDownloading(false);
}
}, [documentId, editorDoc?.title, searchSpaceId]);
}, [documentId, editorDoc?.title, workspaceId]);
const largeDocAlert = viewerMode === "monaco" && !isLocalFileMode && editorDoc && (
<Alert className="m-4 shrink-0">
@ -890,7 +890,7 @@ function DesktopEditorPanel() {
const hasTarget =
panelState.kind === "document"
? !!panelState.documentId && !!panelState.searchSpaceId
? !!panelState.documentId && !!panelState.workspaceId
: panelState.kind === "local_file"
? !!panelState.localFilePath
: !!panelState.memoryScope;
@ -903,7 +903,7 @@ function DesktopEditorPanel() {
documentId={panelState.documentId ?? undefined}
localFilePath={panelState.localFilePath ?? undefined}
memoryScope={panelState.memoryScope ?? undefined}
searchSpaceId={panelState.searchSpaceId ?? undefined}
workspaceId={panelState.workspaceId ?? undefined}
title={panelState.title}
onClose={closePanel}
/>
@ -919,7 +919,7 @@ function MobileEditorDrawer() {
const hasTarget =
panelState.kind === "document"
? !!panelState.documentId && !!panelState.searchSpaceId
? !!panelState.documentId && !!panelState.workspaceId
: !!panelState.memoryScope;
if (!hasTarget) return null;
@ -943,7 +943,7 @@ function MobileEditorDrawer() {
documentId={panelState.documentId ?? undefined}
localFilePath={panelState.localFilePath ?? undefined}
memoryScope={panelState.memoryScope ?? undefined}
searchSpaceId={panelState.searchSpaceId ?? undefined}
workspaceId={panelState.workspaceId ?? undefined}
title={panelState.title}
/>
</div>
@ -957,7 +957,7 @@ export function EditorPanel() {
const isDesktop = useMediaQuery("(min-width: 1024px)");
const hasTarget =
panelState.kind === "document"
? !!panelState.documentId && !!panelState.searchSpaceId
? !!panelState.documentId && !!panelState.workspaceId
: panelState.kind === "local_file"
? !!panelState.localFilePath
: !!panelState.memoryScope;
@ -977,7 +977,7 @@ export function MobileEditorPanel() {
const isDesktop = useMediaQuery("(min-width: 1024px)");
const hasTarget =
panelState.kind === "document"
? !!panelState.documentId && !!panelState.searchSpaceId
? !!panelState.documentId && !!panelState.workspaceId
: panelState.kind === "local_file"
? !!panelState.localFilePath
: !!panelState.memoryScope;

View file

@ -24,10 +24,10 @@ interface MemoryReadResponse {
limits?: MemoryLimits;
}
function getMemoryPath(scope: MemoryScope, searchSpaceId?: number | null) {
function getMemoryPath(scope: MemoryScope, workspaceId?: number | null) {
if (scope === "user") return "/api/v1/users/me/memory";
if (!searchSpaceId) throw new Error("Missing search space context");
return `/api/v1/workspaces/${searchSpaceId}/memory`;
if (!workspaceId) throw new Error("Missing workspace context");
return `/api/v1/workspaces/${workspaceId}/memory`;
}
export function getMemoryLimitState(length: number, limits?: MemoryLimits | null) {
@ -53,16 +53,16 @@ export function getMemoryLimitState(length: number, limits?: MemoryLimits | null
export async function fetchMemoryEditorDocument({
scope,
searchSpaceId,
workspaceId,
title,
signal,
}: {
scope: MemoryScope;
searchSpaceId?: number | null;
workspaceId?: number | null;
title?: string | null;
signal?: AbortSignal;
}) {
const response = await authenticatedFetch(buildBackendUrl(getMemoryPath(scope, searchSpaceId)), {
const response = await authenticatedFetch(buildBackendUrl(getMemoryPath(scope, workspaceId)), {
method: "GET",
signal,
});
@ -87,14 +87,14 @@ export async function fetchMemoryEditorDocument({
export async function saveMemoryMarkdown({
scope,
searchSpaceId,
workspaceId,
markdown,
}: {
scope: MemoryScope;
searchSpaceId?: number | null;
workspaceId?: number | null;
markdown: string;
}) {
const response = await authenticatedFetch(buildBackendUrl(getMemoryPath(scope, searchSpaceId)), {
const response = await authenticatedFetch(buildBackendUrl(getMemoryPath(scope, workspaceId)), {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ memory_md: markdown }),