feat(workspace): refactor search space handling to workspace

This commit is contained in:
Anish Sarkar 2026-07-06 10:04:17 +05:30
parent e92b7a34ed
commit c379ab1155
53 changed files with 268 additions and 169 deletions

View file

@ -74,7 +74,7 @@ export default function OnboardPage() {
</p> </p>
</div> </div>
<ModelProviderConnectionsPanel <ModelProviderConnectionsPanel
workspaceId={workspaceId} searchSpaceId={workspaceId}
connections={connections} connections={connections}
className="flex flex-col gap-6 text-left" className="flex flex-col gap-6 text-left"
footerAction={ footerAction={

View file

@ -34,6 +34,7 @@ import { useElectronAPI } from "@/hooks/use-platform";
import { documentsApiService } from "@/lib/apis/documents-api.service"; import { documentsApiService } from "@/lib/apis/documents-api.service";
import { getVirtualPathDisplay } from "@/lib/chat/virtual-path-display"; import { getVirtualPathDisplay } from "@/lib/chat/virtual-path-display";
import { type CitationUrlMap, preprocessCitationMarkdown } from "@/lib/citations/citation-parser"; import { type CitationUrlMap, preprocessCitationMarkdown } from "@/lib/citations/citation-parser";
import { getWorkspaceIdNumber } from "@/lib/route-params";
import { tryGetHostname } from "@/lib/url"; import { tryGetHostname } from "@/lib/url";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@ -188,13 +189,7 @@ function FilePathLink({ path, className }: { path: string; className?: string })
const openEditorPanel = useSetAtom(openEditorPanelAtom); const openEditorPanel = useSetAtom(openEditorPanelAtom);
const params = useParams(); const params = useParams();
const electronAPI = useElectronAPI(); const electronAPI = useElectronAPI();
const searchSpaceIdParam = params?.search_space_id; const resolvedSearchSpaceId = getWorkspaceIdNumber(params);
const parsedSearchSpaceId = Array.isArray(searchSpaceIdParam)
? Number(searchSpaceIdParam[0])
: Number(searchSpaceIdParam);
const resolvedSearchSpaceId = Number.isFinite(parsedSearchSpaceId)
? parsedSearchSpaceId
: undefined;
const { displayName, isFolder } = getVirtualPathDisplay(path); const { displayName, isFolder } = getVirtualPathDisplay(path);
const icon = isFolder ? <FolderIcon className="size-3.5" /> : <FileIcon className="size-3.5" />; const icon = isFolder ? <FolderIcon className="size-3.5" /> : <FileIcon className="size-3.5" />;

View file

@ -108,6 +108,7 @@ import { useElectronAPI } from "@/hooks/use-platform";
import { captureDisplayToPngDataUrl } from "@/lib/chat/display-media-capture"; import { captureDisplayToPngDataUrl } from "@/lib/chat/display-media-capture";
import { getMentionDocKey } from "@/lib/chat/mention-doc-key"; import { getMentionDocKey } from "@/lib/chat/mention-doc-key";
import { slideoutOpenedTickAtom } from "@/lib/layout-events"; import { slideoutOpenedTickAtom } from "@/lib/layout-events";
import { getWorkspaceIdNumber } from "@/lib/route-params";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { import {
DocumentMentionPicker, DocumentMentionPicker,
@ -458,7 +459,9 @@ const Composer: FC = () => {
const prevMentionedDocsRef = useRef<Map<string, MentionedDocumentInfo>>(new Map()); const prevMentionedDocsRef = useRef<Map<string, MentionedDocumentInfo>>(new Map());
const documentPickerRef = useRef<DocumentMentionPickerRef>(null); const documentPickerRef = useRef<DocumentMentionPickerRef>(null);
const promptPickerRef = useRef<PromptPickerRef>(null); const promptPickerRef = useRef<PromptPickerRef>(null);
const { search_space_id, chat_id } = useParams(); const params = useParams();
const workspaceId = getWorkspaceIdNumber(params);
const chat_id = params.chat_id;
const aui = useAui(); const aui = useAui();
// Desktop-only auto-focus; on mobile, programmatic focus would // Desktop-only auto-focus; on mobile, programmatic focus would
// summon the soft keyboard on every picker close / thread switch. // summon the soft keyboard on every picker close / thread switch.
@ -824,7 +827,6 @@ const Composer: FC = () => {
const handleDocumentsMention = useCallback( const handleDocumentsMention = useCallback(
(mentions: MentionedDocumentInfo[]) => { (mentions: MentionedDocumentInfo[]) => {
const parsedSearchSpaceId = Number(search_space_id);
const editorMentionedDocs = editorRef.current?.getMentionedDocuments() ?? []; const editorMentionedDocs = editorRef.current?.getMentionedDocuments() ?? [];
const editorDocKeys = new Set(editorMentionedDocs.map((doc) => getMentionDocKey(doc))); const editorDocKeys = new Set(editorMentionedDocs.map((doc) => getMentionDocKey(doc)));
@ -832,8 +834,8 @@ const Composer: FC = () => {
const key = getMentionDocKey(mention); const key = getMentionDocKey(mention);
if (editorDocKeys.has(key)) continue; if (editorDocKeys.has(key)) continue;
editorRef.current?.insertMentionChip(mention); editorRef.current?.insertMentionChip(mention);
if (Number.isFinite(parsedSearchSpaceId)) { if (workspaceId) {
promoteRecentMention(parsedSearchSpaceId, mention); promoteRecentMention(workspaceId, mention);
} }
// Track within the loop so a duplicate-in-batch can't double-insert. // Track within the loop so a duplicate-in-batch can't double-insert.
editorDocKeys.add(key); editorDocKeys.add(key);
@ -844,7 +846,7 @@ const Composer: FC = () => {
setMentionQuery(""); setMentionQuery("");
setSuggestionAnchorPoint(null); setSuggestionAnchorPoint(null);
}, },
[search_space_id] [workspaceId]
); );
useEffect(() => { useEffect(() => {
@ -893,7 +895,7 @@ const Composer: FC = () => {
<ComposerSuggestionPopoverContent side="top"> <ComposerSuggestionPopoverContent side="top">
<DocumentMentionPicker <DocumentMentionPicker
ref={documentPickerRef} ref={documentPickerRef}
searchSpaceId={Number(search_space_id)} searchSpaceId={workspaceId ?? 0}
enableChatMentions enableChatMentions
currentChatId={threadId} currentChatId={threadId}
onSelectionChange={handleDocumentsMention} onSelectionChange={handleDocumentsMention}
@ -959,7 +961,7 @@ const Composer: FC = () => {
</div> </div>
<ComposerAction <ComposerAction
isBlockedByOtherUser={isBlockedByOtherUser} isBlockedByOtherUser={isBlockedByOtherUser}
searchSpaceId={Number(search_space_id)} searchSpaceId={workspaceId ?? 0}
onChatModelSelected={handleChatModelSelected} onChatModelSelected={handleChatModelSelected}
/> />
<ConnectorIndicator showTrigger={false} /> <ConnectorIndicator showTrigger={false} />

View file

@ -26,6 +26,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import { getMentionDocKey } from "@/lib/chat/mention-doc-key"; import { getMentionDocKey } from "@/lib/chat/mention-doc-key";
import { parseMentionSegments } from "@/lib/chat/parse-mention-segments"; import { parseMentionSegments } from "@/lib/chat/parse-mention-segments";
import { getWorkspaceIdNumber } from "@/lib/route-params";
interface AuthorMetadata { interface AuthorMetadata {
displayName: string | null; displayName: string | null;
@ -75,13 +76,7 @@ const UserTextPart: FC = () => {
const openEditorPanel = useSetAtom(openEditorPanelAtom); const openEditorPanel = useSetAtom(openEditorPanelAtom);
const router = useRouter(); const router = useRouter();
const params = useParams(); const params = useParams();
const searchSpaceIdParam = params?.search_space_id; const resolvedSearchSpaceId = getWorkspaceIdNumber(params);
const parsedSearchSpaceId = Array.isArray(searchSpaceIdParam)
? Number(searchSpaceIdParam[0])
: Number(searchSpaceIdParam);
const resolvedSearchSpaceId = Number.isFinite(parsedSearchSpaceId)
? parsedSearchSpaceId
: undefined;
const handleOpenDoc = useCallback( const handleOpenDoc = useCallback(
(docId: number, title: string) => { (docId: number, title: string) => {

View file

@ -27,7 +27,7 @@ interface MemoryReadResponse {
function getMemoryPath(scope: MemoryScope, searchSpaceId?: number | null) { function getMemoryPath(scope: MemoryScope, searchSpaceId?: number | null) {
if (scope === "user") return "/api/v1/users/me/memory"; if (scope === "user") return "/api/v1/users/me/memory";
if (!searchSpaceId) throw new Error("Missing search space context"); if (!searchSpaceId) throw new Error("Missing search space context");
return `/api/v1/searchspaces/${searchSpaceId}/memory`; return `/api/v1/workspaces/${searchSpaceId}/memory`;
} }
export function getMemoryLimitState(length: number, limits?: MemoryLimits | null) { export function getMemoryLimitState(length: number, limits?: MemoryLimits | null) {

View file

@ -81,6 +81,7 @@ import { authenticatedFetch } from "@/lib/auth-fetch";
import { getMentionDocKey } from "@/lib/chat/mention-doc-key"; import { getMentionDocKey } from "@/lib/chat/mention-doc-key";
import { buildBackendUrl } from "@/lib/env-config"; import { buildBackendUrl } from "@/lib/env-config";
import { uploadFolderScan } from "@/lib/folder-sync-upload"; import { uploadFolderScan } from "@/lib/folder-sync-upload";
import { getWorkspaceIdNumber } from "@/lib/route-params";
import { getSupportedExtensionsSet } from "@/lib/supported-extensions"; import { getSupportedExtensionsSet } from "@/lib/supported-extensions";
import { queries } from "@/zero/queries/index"; import { queries } from "@/zero/queries/index";
import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel"; import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel";
@ -228,7 +229,7 @@ function AuthenticatedDocumentsSidebarBase({
const platformElectronAPI = useElectronAPI(); const platformElectronAPI = useElectronAPI();
const electronAPI = desktopFeaturesEnabled ? platformElectronAPI : null; const electronAPI = desktopFeaturesEnabled ? platformElectronAPI : null;
const { etlService } = useRuntimeConfig(); const { etlService } = useRuntimeConfig();
const searchSpaceId = Number(params.search_space_id); const searchSpaceId = getWorkspaceIdNumber(params) ?? 0;
const setConnectorDialogOpen = useSetAtom(connectorDialogOpenAtom); const setConnectorDialogOpen = useSetAtom(connectorDialogOpenAtom);
const openEditorPanel = useSetAtom(openEditorPanelAtom); const openEditorPanel = useSetAtom(openEditorPanelAtom);
const { data: agentFlags } = useAtomValue(agentFlagsAtom); const { data: agentFlags } = useAtomValue(agentFlagsAtom);
@ -828,7 +829,7 @@ function AuthenticatedDocumentsSidebarBase({
const endpoint = const endpoint =
doc.document_type === "USER_MEMORY" doc.document_type === "USER_MEMORY"
? buildBackendUrl("/api/v1/users/me/memory") ? buildBackendUrl("/api/v1/users/me/memory")
: buildBackendUrl(`/api/v1/searchspaces/${searchSpaceId}/memory`); : buildBackendUrl(`/api/v1/workspaces/${searchSpaceId}/memory`);
const response = await authenticatedFetch(endpoint, { method: "GET" }); const response = await authenticatedFetch(endpoint, { method: "GET" });
if (!response.ok) { if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: "Export failed" })); const errorData = await response.json().catch(() => ({ detail: "Export failed" }));
@ -1038,7 +1039,7 @@ function AuthenticatedDocumentsSidebarBase({
const endpoint = const endpoint =
doc.document_type === "USER_MEMORY" doc.document_type === "USER_MEMORY"
? buildBackendUrl("/api/v1/users/me/memory/reset") ? buildBackendUrl("/api/v1/users/me/memory/reset")
: buildBackendUrl(`/api/v1/searchspaces/${searchSpaceId}/memory/reset`); : buildBackendUrl(`/api/v1/workspaces/${searchSpaceId}/memory/reset`);
try { try {
const response = await authenticatedFetch(endpoint, { method: "POST" }); const response = await authenticatedFetch(endpoint, { method: "POST" });
if (!response.ok) { if (!response.ok) {

View file

@ -58,6 +58,7 @@ import { notificationsApiService } from "@/lib/apis/notifications-api.service";
import { convertRenderedToDisplay } from "@/lib/comments/utils"; import { convertRenderedToDisplay } from "@/lib/comments/utils";
import { getDocumentTypeLabel } from "@/lib/documents/document-type-labels"; import { getDocumentTypeLabel } from "@/lib/documents/document-type-labels";
import { cacheKeys } from "@/lib/query-client/cache-keys"; import { cacheKeys } from "@/lib/query-client/cache-keys";
import { getWorkspaceIdNumber } from "@/lib/route-params";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel"; import { SidebarSlideOutPanel } from "./SidebarSlideOutPanel";
@ -165,7 +166,7 @@ export function InboxSidebarContent({
const router = useRouter(); const router = useRouter();
const params = useParams(); const params = useParams();
const isMobile = !useMediaQuery("(min-width: 640px)"); const isMobile = !useMediaQuery("(min-width: 640px)");
const searchSpaceId = params?.search_space_id ? Number(params.search_space_id) : null; const searchSpaceId = getWorkspaceIdNumber(params) ?? null;
const [, setTargetCommentId] = useAtom(setTargetCommentIdAtom); const [, setTargetCommentId] = useAtom(setTargetCommentIdAtom);

View file

@ -10,6 +10,7 @@ import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { useIsAnonymous } from "@/contexts/anonymous-mode"; import { useIsAnonymous } from "@/contexts/anonymous-mode";
import { getWorkspaceIdParam } from "@/lib/route-params";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { SIDEBAR_MIN_WIDTH } from "../../hooks/useSidebarResize"; import { SIDEBAR_MIN_WIDTH } from "../../hooks/useSidebarResize";
import type { ChatItem, NavItem, PageUsage, SearchSpace, User } from "../../types/layout.types"; import type { ChatItem, NavItem, PageUsage, SearchSpace, User } from "../../types/layout.types";
@ -377,7 +378,7 @@ function SidebarUsageFooter({
onNavigate?: () => void; onNavigate?: () => void;
}) { }) {
const params = useParams(); const params = useParams();
const searchSpaceId = params?.search_space_id ?? ""; const searchSpaceId = getWorkspaceIdParam(params) ?? "";
const isAnonymous = useIsAnonymous(); const isAnonymous = useIsAnonymous();
if (isCollapsed) return null; if (isCollapsed) return null;

View file

@ -24,6 +24,7 @@ import {
ComposerSuggestionSeparator, ComposerSuggestionSeparator,
ComposerSuggestionSkeleton, ComposerSuggestionSkeleton,
} from "@/components/new-chat/composer-suggestion-popup"; } from "@/components/new-chat/composer-suggestion-popup";
import { getWorkspaceIdParam } from "@/lib/route-params";
export interface PromptPickerRef { export interface PromptPickerRef {
selectHighlighted: () => void; selectHighlighted: () => void;
@ -69,9 +70,7 @@ export const PromptPicker = forwardRef<PromptPickerRef, PromptPickerProps>(funct
const createPromptIndex = filtered.length; const createPromptIndex = filtered.length;
const totalItems = filtered.length + 1; const totalItems = filtered.length + 1;
const searchSpaceId = Array.isArray(params?.search_space_id) const searchSpaceId = getWorkspaceIdParam(params);
? params.search_space_id[0]
: params?.search_space_id;
const handleSelect = useCallback( const handleSelect = useCallback(
(index: number) => { (index: number) => {

View file

@ -11,7 +11,7 @@ export function I18nProvider({ children }: { children: React.ReactNode }) {
const { locale, messages } = useLocaleContext(); const { locale, messages } = useLocaleContext();
return ( return (
<NextIntlClientProvider messages={messages} locale={locale}> <NextIntlClientProvider messages={messages} locale={locale} timeZone="UTC">
{children} {children}
</NextIntlClientProvider> </NextIntlClientProvider>
); );

View file

@ -15,6 +15,7 @@ import { Spinner } from "@/components/ui/spinner";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { stripeApiService } from "@/lib/apis/stripe-api.service"; import { stripeApiService } from "@/lib/apis/stripe-api.service";
import { AppError } from "@/lib/error"; import { AppError } from "@/lib/error";
import { getWorkspaceIdNumber } from "@/lib/route-params";
import { queries } from "@/zero/queries"; import { queries } from "@/zero/queries";
const microsToDollars = (micros: number | null | undefined): string => { const microsToDollars = (micros: number | null | undefined): string => {
@ -38,7 +39,7 @@ export function AutoReloadSettings() {
const pathname = usePathname(); const pathname = usePathname();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const searchSpaceId = Number(params?.search_space_id); const searchSpaceId = getWorkspaceIdNumber(params) ?? 0;
const [enabled, setEnabled] = useState(false); const [enabled, setEnabled] = useState(false);
const [thresholdInput, setThresholdInput] = useState(""); const [thresholdInput, setThresholdInput] = useState("");

View file

@ -10,6 +10,7 @@ import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner"; import { Spinner } from "@/components/ui/spinner";
import { stripeApiService } from "@/lib/apis/stripe-api.service"; import { stripeApiService } from "@/lib/apis/stripe-api.service";
import { AppError } from "@/lib/error"; import { AppError } from "@/lib/error";
import { getWorkspaceIdNumber } from "@/lib/route-params";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { queries } from "@/zero/queries"; import { queries } from "@/zero/queries";
@ -37,7 +38,7 @@ const formatUsd = (micros: number) => {
export function BuyCreditsContent() { export function BuyCreditsContent() {
const params = useParams(); const params = useParams();
const searchSpaceId = Number(params?.search_space_id); const searchSpaceId = getWorkspaceIdNumber(params) ?? 0;
const [quantity, setQuantity] = useState(1); const [quantity, setQuantity] = useState(1);
// Raw text of the amount field so the user can clear it while typing; // Raw text of the amount field so the user can clear it while typing;
// committed back to a clamped integer on blur. // committed back to a clamped integer on blur.

View file

@ -20,6 +20,7 @@ import {
trackIncentiveTaskClicked, trackIncentiveTaskClicked,
trackIncentiveTaskCompleted, trackIncentiveTaskCompleted,
} from "@/lib/posthog/events"; } from "@/lib/posthog/events";
import { getWorkspaceIdParam } from "@/lib/route-params";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
// Compact dollar label for a task's reward (e.g. "+$0.03"). // Compact dollar label for a task's reward (e.g. "+$0.03").
@ -32,7 +33,7 @@ const formatRewardUsd = (micros: number) => {
export function EarnCreditsContent() { export function EarnCreditsContent() {
const params = useParams(); const params = useParams();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const searchSpaceId = params?.search_space_id ?? ""; const searchSpaceId = getWorkspaceIdParam(params) ?? "";
useEffect(() => { useEffect(() => {
trackIncentivePageViewed(); trackIncentivePageViewed();

View file

@ -126,6 +126,11 @@ export function ModelProviderConnectionsPanel({
// Each provider connect form builds its own credential payload; the backend // Each provider connect form builds its own credential payload; the backend
// resolver (`to_litellm`) forwards `extra.litellm_params` straight to LiteLLM. // resolver (`to_litellm`) forwards `extra.litellm_params` straight to LiteLLM.
function handleCreate(draft: ConnectionDraft) { function handleCreate(draft: ConnectionDraft) {
if (!Number.isFinite(searchSpaceId) || searchSpaceId <= 0) {
toast.error("Workspace is still loading. Please try again.");
return;
}
const models = connectionModelsForDraft(draft); const models = connectionModelsForDraft(draft);
const testModel = representativeTestModel(models); const testModel = representativeTestModel(models);
if (!testModel) { if (!testModel) {
@ -165,6 +170,11 @@ export function ModelProviderConnectionsPanel({
setProvider(providerId); setProvider(providerId);
setIsAddProviderOpen(true); setIsAddProviderOpen(true);
if (providerId === "vertex_ai") { if (providerId === "vertex_ai") {
if (!Number.isFinite(searchSpaceId) || searchSpaceId <= 0) {
toast.error("Workspace is still loading. Please try again.");
return;
}
previewModels.mutate( previewModels.mutate(
{ {
provider: providerId, provider: providerId,
@ -184,6 +194,11 @@ export function ModelProviderConnectionsPanel({
} }
function refreshConnectModels(draft: ConnectionDraft) { function refreshConnectModels(draft: ConnectionDraft) {
if (!Number.isFinite(searchSpaceId) || searchSpaceId <= 0) {
toast.error("Workspace is still loading. Please try again.");
return;
}
previewModels.mutate( previewModels.mutate(
{ {
provider, provider,

View file

@ -200,12 +200,18 @@ export const documentTitleRead = z.object({
}); });
export const searchDocumentTitlesRequest = z.object({ export const searchDocumentTitlesRequest = z.object({
queryParams: z.object({ queryParams: z
search_space_id: z.number(), .object({
title: z.string().optional(), search_space_id: z.number().optional(),
page: z.number().optional(), workspace_id: z.number().optional(),
page_size: z.number().optional(), title: z.string().optional(),
}), page: z.number().optional(),
page_size: z.number().optional(),
})
.refine((params) => params.search_space_id !== undefined || params.workspace_id !== undefined, {
message: "workspace_id is required",
path: ["search_space_id"],
}),
}); });
export const searchDocumentTitlesResponse = z.object({ export const searchDocumentTitlesResponse = z.object({

View file

@ -1,21 +1,32 @@
import { z } from "zod"; import { z } from "zod";
import { role } from "./roles.types"; import { role } from "./roles.types";
export const membership = z.object({ export const membership = z.preprocess(
id: z.number(), (value) => {
user_id: z.string(), if (typeof value === "object" && value !== null && !Array.isArray(value)) {
search_space_id: z.number(), const record = value as Record<string, unknown>;
role_id: z.number().nullable(), if (record.search_space_id === undefined && record.workspace_id !== undefined) {
is_owner: z.boolean(), return { ...record, search_space_id: record.workspace_id };
joined_at: z.string(), }
created_at: z.string(), }
role: role.nullable().optional(), return value;
user_email: z.string().nullable().optional(), },
user_display_name: z.string().nullable().optional(), z.object({
user_avatar_url: z.string().nullable().optional(), id: z.number(),
user_last_login: z.string().nullable().optional(), user_id: z.string(),
user_is_active: z.boolean().nullable().optional(), search_space_id: z.number(),
}); role_id: z.number().nullable(),
is_owner: z.boolean(),
joined_at: z.string(),
created_at: z.string(),
role: role.nullable().optional(),
user_email: z.string().nullable().optional(),
user_display_name: z.string().nullable().optional(),
user_avatar_url: z.string().nullable().optional(),
user_last_login: z.string().nullable().optional(),
user_is_active: z.boolean().nullable().optional(),
})
);
/** /**
* Get members * Get members
@ -69,13 +80,19 @@ export const getMyAccessRequest = z.object({
search_space_id: z.number(), search_space_id: z.number(),
}); });
export const getMyAccessResponse = z.object({ export const getMyAccessResponse = z
search_space_name: z.string(), .object({
search_space_id: z.number(), workspace_name: z.string(),
is_owner: z.boolean(), workspace_id: z.number(),
permissions: z.array(z.string()), is_owner: z.boolean(),
role_name: z.string().nullable(), permissions: z.array(z.string()),
}); role_name: z.string().nullable(),
})
.transform(({ workspace_id, workspace_name, ...rest }) => ({
...rest,
search_space_id: workspace_id,
search_space_name: workspace_name,
}));
export type Membership = z.infer<typeof membership>; export type Membership = z.infer<typeof membership>;
export type GetMembersRequest = z.infer<typeof getMembersRequest>; export type GetMembersRequest = z.infer<typeof getMembersRequest>;

View file

@ -1,6 +1,6 @@
import { z } from "zod"; import { z } from "zod";
export const role = z.object({ const roleBase = z.object({
id: z.number(), id: z.number(),
name: z.string().min(1).max(100), name: z.string().min(1).max(100),
description: z.string().max(500).nullable(), description: z.string().max(500).nullable(),
@ -11,12 +11,22 @@ export const role = z.object({
created_at: z.string(), created_at: z.string(),
}); });
export const role = z.preprocess((value) => {
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
const record = value as Record<string, unknown>;
if (record.search_space_id === undefined && record.workspace_id !== undefined) {
return { ...record, search_space_id: record.workspace_id };
}
}
return value;
}, roleBase);
/** /**
* Create role * Create role
*/ */
export const createRoleRequest = z.object({ export const createRoleRequest = z.object({
search_space_id: z.number(), search_space_id: z.number(),
data: role.pick({ data: roleBase.pick({
name: true, name: true,
description: true, description: true,
permissions: true, permissions: true,
@ -51,7 +61,7 @@ export const getRoleByIdResponse = role;
export const updateRoleRequest = z.object({ export const updateRoleRequest = z.object({
search_space_id: z.number(), search_space_id: z.number(),
role_id: z.number(), role_id: z.number(),
data: role data: roleBase
.pick({ .pick({
name: true, name: true,
description: true, description: true,

View file

@ -81,7 +81,7 @@ export const updateSearchSpaceApiAccessResponse = searchSpace.omit({
export const deleteSearchSpaceRequest = searchSpace.pick({ id: true }); export const deleteSearchSpaceRequest = searchSpace.pick({ id: true });
export const deleteSearchSpaceResponse = z.object({ export const deleteSearchSpaceResponse = z.object({
message: z.literal("Search space deleted successfully"), message: z.literal("Workspace deleted successfully"),
}); });
/** /**

View file

@ -108,7 +108,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
const response = await authenticatedFetch( const response = await authenticatedFetch(
buildBackendUrl("/api/v1/search-source-connectors", { buildBackendUrl("/api/v1/search-source-connectors", {
search_space_id: spaceId, workspace_id: spaceId,
}), }),
{ {
method: "GET", method: "GET",
@ -167,7 +167,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
try { try {
const response = await authenticatedFetch( const response = await authenticatedFetch(
buildBackendUrl("/api/v1/search-source-connectors", { buildBackendUrl("/api/v1/search-source-connectors", {
search_space_id: spaceId, workspace_id: spaceId,
}), }),
{ {
method: "POST", method: "POST",
@ -269,7 +269,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
try { try {
const response = await authenticatedFetch( const response = await authenticatedFetch(
buildBackendUrl(`/api/v1/search-source-connectors/${connectorId}/index`, { buildBackendUrl(`/api/v1/search-source-connectors/${connectorId}/index`, {
search_space_id: searchSpaceId, workspace_id: searchSpaceId,
start_date: startDate, start_date: startDate,
end_date: endDate, end_date: endDate,
}), }),

View file

@ -44,7 +44,7 @@ export type AgentPermissionRuleUpdate = z.infer<typeof AgentPermissionRuleUpdate
class AgentPermissionsApiService { class AgentPermissionsApiService {
list = async (searchSpaceId: number): Promise<AgentPermissionRule[]> => { list = async (searchSpaceId: number): Promise<AgentPermissionRule[]> => {
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${searchSpaceId}/agent/permissions/rules`, `/api/v1/workspaces/${searchSpaceId}/agent/permissions/rules`,
AgentPermissionRuleListSchema AgentPermissionRuleListSchema
); );
}; };
@ -58,7 +58,7 @@ class AgentPermissionsApiService {
throw new ValidationError(parsed.error.issues.map((i) => i.message).join(", ")); throw new ValidationError(parsed.error.issues.map((i) => i.message).join(", "));
} }
return baseApiService.post( return baseApiService.post(
`/api/v1/searchspaces/${searchSpaceId}/agent/permissions/rules`, `/api/v1/workspaces/${searchSpaceId}/agent/permissions/rules`,
AgentPermissionRuleSchema, AgentPermissionRuleSchema,
{ body: parsed.data } { body: parsed.data }
); );
@ -74,7 +74,7 @@ class AgentPermissionsApiService {
throw new ValidationError(parsed.error.issues.map((i) => i.message).join(", ")); throw new ValidationError(parsed.error.issues.map((i) => i.message).join(", "));
} }
return baseApiService.patch( return baseApiService.patch(
`/api/v1/searchspaces/${searchSpaceId}/agent/permissions/rules/${ruleId}`, `/api/v1/workspaces/${searchSpaceId}/agent/permissions/rules/${ruleId}`,
AgentPermissionRuleSchema, AgentPermissionRuleSchema,
{ body: parsed.data } { body: parsed.data }
); );
@ -82,7 +82,7 @@ class AgentPermissionsApiService {
remove = async (searchSpaceId: number, ruleId: number): Promise<void> => { remove = async (searchSpaceId: number, ruleId: number): Promise<void> => {
await baseApiService.delete( await baseApiService.delete(
`/api/v1/searchspaces/${searchSpaceId}/agent/permissions/rules/${ruleId}` `/api/v1/workspaces/${searchSpaceId}/agent/permissions/rules/${ruleId}`
); );
}; };
} }

View file

@ -37,7 +37,7 @@ class AutomationsApiService {
listAutomations = async (params: AutomationListParams) => { listAutomations = async (params: AutomationListParams) => {
const qs = new URLSearchParams({ const qs = new URLSearchParams({
search_space_id: String(params.search_space_id), workspace_id: String(params.search_space_id),
limit: String(params.limit), limit: String(params.limit),
offset: String(params.offset), offset: String(params.offset),
}); });
@ -50,7 +50,10 @@ class AutomationsApiService {
createAutomation = async (request: AutomationCreateRequest) => { createAutomation = async (request: AutomationCreateRequest) => {
const data = rejectIfInvalid(automationCreateRequest.safeParse(request)); const data = rejectIfInvalid(automationCreateRequest.safeParse(request));
return baseApiService.post(BASE, automation, { body: data }); const { search_space_id, ...body } = data;
return baseApiService.post(BASE, automation, {
body: { ...body, workspace_id: search_space_id },
});
}; };
updateAutomation = async (automationId: number, request: AutomationUpdateRequest) => { updateAutomation = async (automationId: number, request: AutomationUpdateRequest) => {
@ -66,7 +69,7 @@ class AutomationsApiService {
// Whether the search space's models are billable for automations (premium // Whether the search space's models are billable for automations (premium
// global or BYOK). Used to gate creation surfaces before submit. // global or BYOK). Used to gate creation surfaces before submit.
getModelEligibility = async (searchSpaceId: number) => { getModelEligibility = async (searchSpaceId: number) => {
const qs = new URLSearchParams({ search_space_id: String(searchSpaceId) }); const qs = new URLSearchParams({ workspace_id: String(searchSpaceId) });
return baseApiService.get(`${BASE}/model-eligibility?${qs.toString()}`, modelEligibility); return baseApiService.get(`${BASE}/model-eligibility?${qs.toString()}`, modelEligibility);
}; };

View file

@ -140,7 +140,7 @@ class ChatCommentsApiService {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (parsed.data.search_space_id !== undefined) { if (parsed.data.search_space_id !== undefined) {
params.set("search_space_id", String(parsed.data.search_space_id)); params.set("workspace_id", String(parsed.data.search_space_id));
} }
const queryString = params.toString(); const queryString = params.toString();

View file

@ -86,7 +86,7 @@ class ChatThreadsApiService {
} }
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${parsed.data.search_space_id}/snapshots`, `/api/v1/workspaces/${parsed.data.search_space_id}/snapshots`,
publicChatSnapshotsBySpaceResponse publicChatSnapshotsBySpaceResponse
); );
}; };

View file

@ -59,7 +59,7 @@ class ConnectorsApiService {
Object.entries(parsedRequest.data.queryParams) Object.entries(parsedRequest.data.queryParams)
.filter(([_, v]) => v !== undefined && v !== null) .filter(([_, v]) => v !== undefined && v !== null)
.map(([k, v]) => { .map(([k, v]) => {
return [k, String(v)]; return [k === "search_space_id" ? "workspace_id" : k, String(v)];
}) })
) )
: undefined; : undefined;
@ -113,7 +113,7 @@ class ConnectorsApiService {
Object.entries(queryParams) Object.entries(queryParams)
.filter(([_, v]) => v !== undefined && v !== null) .filter(([_, v]) => v !== undefined && v !== null)
.map(([k, v]) => { .map(([k, v]) => {
return [k, String(v)]; return [k === "search_space_id" ? "workspace_id" : k, String(v)];
}) })
); );
@ -187,7 +187,7 @@ class ConnectorsApiService {
Object.entries(queryParams) Object.entries(queryParams)
.filter(([_, v]) => v !== undefined && v !== null) .filter(([_, v]) => v !== undefined && v !== null)
.map(([k, v]) => { .map(([k, v]) => {
return [k, String(v)]; return [k === "search_space_id" ? "workspace_id" : k, String(v)];
}) })
); );
@ -314,7 +314,7 @@ class ConnectorsApiService {
const { search_space_id } = request.queryParams; const { search_space_id } = request.queryParams;
const queryString = new URLSearchParams({ const queryString = new URLSearchParams({
search_space_id: String(search_space_id), workspace_id: String(search_space_id),
}).toString(); }).toString();
return baseApiService.get<MCPConnectorRead[]>(`/api/v1/connectors/mcp?${queryString}`); return baseApiService.get<MCPConnectorRead[]>(`/api/v1/connectors/mcp?${queryString}`);
@ -334,7 +334,7 @@ class ConnectorsApiService {
const { data, queryParams } = request; const { data, queryParams } = request;
const queryString = new URLSearchParams({ const queryString = new URLSearchParams({
search_space_id: String(queryParams.search_space_id), workspace_id: String(queryParams.search_space_id),
}).toString(); }).toString();
return baseApiService.post<MCPConnectorRead>( return baseApiService.post<MCPConnectorRead>(

View file

@ -61,11 +61,12 @@ class DocumentsApiService {
const transformedQueryParams = parsedRequest.data.queryParams const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries( ? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => { Object.entries(parsedRequest.data.queryParams).map(([k, v]) => {
const key = k === "search_space_id" ? "workspace_id" : k;
// Handle array values (document_type) // Handle array values (document_type)
if (Array.isArray(v)) { if (Array.isArray(v)) {
return [k, v.join(",")]; return [key, v.join(",")];
} }
return [k, String(v)]; return [key, String(v)];
}) })
) )
: undefined; : undefined;
@ -106,8 +107,9 @@ class DocumentsApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
const { search_space_id, ...body } = parsedRequest.data;
return baseApiService.post(`/api/v1/documents`, createDocumentResponse, { return baseApiService.post(`/api/v1/documents`, createDocumentResponse, {
body: parsedRequest.data, body: { ...body, workspace_id: search_space_id },
}); });
}; };
@ -143,7 +145,7 @@ class DocumentsApiService {
for (const batch of batches) { for (const batch of batches) {
const formData = new FormData(); const formData = new FormData();
for (const file of batch) formData.append("files", file); for (const file of batch) formData.append("files", file);
formData.append("search_space_id", String(search_space_id)); formData.append("workspace_id", String(search_space_id));
formData.append("use_vision_llm", String(use_vision_llm)); formData.append("use_vision_llm", String(use_vision_llm));
formData.append("processing_mode", processing_mode); formData.append("processing_mode", processing_mode);
@ -191,7 +193,7 @@ class DocumentsApiService {
const { search_space_id, document_ids } = parsedRequest.data.queryParams; const { search_space_id, document_ids } = parsedRequest.data.queryParams;
const params = new URLSearchParams({ const params = new URLSearchParams({
search_space_id: String(search_space_id), workspace_id: String(search_space_id),
document_ids: document_ids.join(","), document_ids: document_ids.join(","),
}); });
@ -218,11 +220,12 @@ class DocumentsApiService {
const transformedQueryParams = parsedRequest.data.queryParams const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries( ? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => { Object.entries(parsedRequest.data.queryParams).map(([k, v]) => {
const key = k === "search_space_id" ? "workspace_id" : k;
// Handle array values (document_type) // Handle array values (document_type)
if (Array.isArray(v)) { if (Array.isArray(v)) {
return [k, v.join(",")]; return [key, v.join(",")];
} }
return [k, String(v)]; return [key, String(v)];
}) })
) )
: undefined; : undefined;
@ -254,7 +257,10 @@ class DocumentsApiService {
const transformedQueryParams = Object.fromEntries( const transformedQueryParams = Object.fromEntries(
Object.entries(parsedRequest.data.queryParams) Object.entries(parsedRequest.data.queryParams)
.filter(([, v]) => v !== undefined) .filter(([, v]) => v !== undefined)
.map(([k, v]) => [k, String(v)]) .map(([k, v]) => [
k === "search_space_id" || k === "workspace_id" ? "workspace_id" : k,
String(v),
])
); );
const queryParams = new URLSearchParams(transformedQueryParams).toString(); const queryParams = new URLSearchParams(transformedQueryParams).toString();
@ -268,7 +274,7 @@ class DocumentsApiService {
getDocumentByVirtualPath = async (request: { search_space_id: number; virtual_path: string }) => { getDocumentByVirtualPath = async (request: { search_space_id: number; virtual_path: string }) => {
const params = new URLSearchParams({ const params = new URLSearchParams({
search_space_id: String(request.search_space_id), workspace_id: String(request.search_space_id),
virtual_path: request.virtual_path, virtual_path: request.virtual_path,
}); });
return baseApiService.get( return baseApiService.get(
@ -295,7 +301,10 @@ class DocumentsApiService {
// Transform query params to be string values // Transform query params to be string values
const transformedQueryParams = parsedRequest.data.queryParams const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries( ? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => [k, String(v)]) Object.entries(parsedRequest.data.queryParams).map(([k, v]) => [
k === "search_space_id" ? "workspace_id" : k,
String(v),
])
) )
: undefined; : undefined;
@ -375,9 +384,10 @@ class DocumentsApiService {
} }
const { id, data } = parsedRequest.data; const { id, data } = parsedRequest.data;
const { search_space_id, ...body } = data;
return baseApiService.put(`/api/v1/documents/${id}`, updateDocumentResponse, { return baseApiService.put(`/api/v1/documents/${id}`, updateDocumentResponse, {
body: data, body: { ...body, workspace_id: search_space_id },
}); });
}; };
@ -406,8 +416,9 @@ class DocumentsApiService {
search_space_id: number; search_space_id: number;
files: { relative_path: string; mtime: number }[]; files: { relative_path: string; mtime: number }[];
}): Promise<{ files_to_upload: string[] }> => { }): Promise<{ files_to_upload: string[] }> => {
const { search_space_id, ...rest } = body;
return baseApiService.post(`/api/v1/documents/folder-mtime-check`, undefined, { return baseApiService.post(`/api/v1/documents/folder-mtime-check`, undefined, {
body, body: { ...rest, workspace_id: search_space_id },
}) as unknown as { files_to_upload: string[] }; }) as unknown as { files_to_upload: string[] };
}; };
@ -428,7 +439,7 @@ class DocumentsApiService {
formData.append("files", file); formData.append("files", file);
} }
formData.append("folder_name", metadata.folder_name); formData.append("folder_name", metadata.folder_name);
formData.append("search_space_id", String(metadata.search_space_id)); formData.append("workspace_id", String(metadata.search_space_id));
formData.append("relative_paths", JSON.stringify(metadata.relative_paths)); formData.append("relative_paths", JSON.stringify(metadata.relative_paths));
if (metadata.root_folder_id != null) { if (metadata.root_folder_id != null) {
formData.append("root_folder_id", String(metadata.root_folder_id)); formData.append("root_folder_id", String(metadata.root_folder_id));
@ -462,8 +473,9 @@ class DocumentsApiService {
root_folder_id: number | null; root_folder_id: number | null;
relative_paths: string[]; relative_paths: string[];
}): Promise<{ deleted_count: number }> => { }): Promise<{ deleted_count: number }> => {
const { search_space_id, ...rest } = body;
return baseApiService.post(`/api/v1/documents/folder-unlink`, undefined, { return baseApiService.post(`/api/v1/documents/folder-unlink`, undefined, {
body, body: { ...rest, workspace_id: search_space_id },
}) as unknown as { deleted_count: number }; }) as unknown as { deleted_count: number };
}; };
@ -473,14 +485,15 @@ class DocumentsApiService {
root_folder_id: number | null; root_folder_id: number | null;
all_relative_paths: string[]; all_relative_paths: string[];
}): Promise<{ deleted_count: number }> => { }): Promise<{ deleted_count: number }> => {
const { search_space_id, ...rest } = body;
return baseApiService.post(`/api/v1/documents/folder-sync-finalize`, undefined, { return baseApiService.post(`/api/v1/documents/folder-sync-finalize`, undefined, {
body, body: { ...rest, workspace_id: search_space_id },
}) as unknown as { deleted_count: number }; }) as unknown as { deleted_count: number };
}; };
getWatchedFolders = async (searchSpaceId: number) => { getWatchedFolders = async (searchSpaceId: number) => {
return baseApiService.get( return baseApiService.get(
`/api/v1/documents/watched-folders?search_space_id=${searchSpaceId}`, `/api/v1/documents/watched-folders?workspace_id=${searchSpaceId}`,
folderListResponse folderListResponse
); );
}; };

View file

@ -27,14 +27,14 @@ class FoldersApiService {
`Invalid request: ${parsed.error.issues.map((i) => i.message).join(", ")}` `Invalid request: ${parsed.error.issues.map((i) => i.message).join(", ")}`
); );
} }
return baseApiService.post("/api/v1/folders", folder, { body: parsed.data }); const { search_space_id, ...body } = parsed.data;
return baseApiService.post("/api/v1/folders", folder, {
body: { ...body, workspace_id: search_space_id },
});
}; };
listFolders = async (searchSpaceId: number) => { listFolders = async (searchSpaceId: number) => {
return baseApiService.get( return baseApiService.get(`/api/v1/folders?workspace_id=${searchSpaceId}`, folderListResponse);
`/api/v1/folders?search_space_id=${searchSpaceId}`,
folderListResponse
);
}; };
getFolder = async (folderId: number) => { getFolder = async (folderId: number) => {

View file

@ -9,7 +9,7 @@ const BASE = "/api/v1/image-generations";
class ImageGenerationsApiService { class ImageGenerationsApiService {
list = async (searchSpaceId: number, limit = 100) => { list = async (searchSpaceId: number, limit = 100) => {
const qs = new URLSearchParams({ const qs = new URLSearchParams({
search_space_id: String(searchSpaceId), workspace_id: String(searchSpaceId),
limit: String(limit), limit: String(limit),
}).toString(); }).toString();
return baseApiService.get(`${BASE}?${qs}`, imageGenerationList); return baseApiService.get(`${BASE}?${qs}`, imageGenerationList);

View file

@ -36,7 +36,7 @@ class InvitesApiService {
} }
return baseApiService.post( return baseApiService.post(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/invites`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/invites`,
createInviteResponse, createInviteResponse,
{ {
body: parsedRequest.data.data, body: parsedRequest.data.data,
@ -58,7 +58,7 @@ class InvitesApiService {
} }
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/invites`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/invites`,
getInvitesResponse getInvitesResponse
); );
}; };
@ -77,7 +77,7 @@ class InvitesApiService {
} }
return baseApiService.put( return baseApiService.put(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/invites/${parsedRequest.data.invite_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/invites/${parsedRequest.data.invite_id}`,
updateInviteResponse, updateInviteResponse,
{ {
body: parsedRequest.data.data, body: parsedRequest.data.data,
@ -99,7 +99,7 @@ class InvitesApiService {
} }
return baseApiService.delete( return baseApiService.delete(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/invites/${parsedRequest.data.invite_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/invites/${parsedRequest.data.invite_id}`,
deleteInviteResponse deleteInviteResponse
); );
}; };

View file

@ -36,11 +36,12 @@ class LogsApiService {
const transformedQueryParams = parsedRequest.data.queryParams const transformedQueryParams = parsedRequest.data.queryParams
? Object.fromEntries( ? Object.fromEntries(
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => { Object.entries(parsedRequest.data.queryParams).map(([k, v]) => {
const key = k === "search_space_id" ? "workspace_id" : k;
// Handle array values (document_type) // Handle array values (document_type)
if (Array.isArray(v)) { if (Array.isArray(v)) {
return [k, v.join(",")]; return [key, v.join(",")];
} }
return [k, String(v)]; return [key, String(v)];
}) })
) )
: undefined; : undefined;
@ -74,8 +75,9 @@ class LogsApiService {
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", "); const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
const { search_space_id, ...body } = parsedRequest.data;
return baseApiService.post(`/api/v1/logs`, createLogResponse, { return baseApiService.post(`/api/v1/logs`, createLogResponse, {
body: parsedRequest.data, body: { ...body, workspace_id: search_space_id },
}); });
}; };
@ -89,8 +91,9 @@ class LogsApiService {
const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", "); const errorMessage = parsedRequest.error.issues.map((issue) => issue.message).join(", ");
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
const { search_space_id, ...body } = parsedRequest.data;
return baseApiService.put(`/api/v1/logs/${logId}`, updateLogResponse, { return baseApiService.put(`/api/v1/logs/${logId}`, updateLogResponse, {
body: parsedRequest.data, body: search_space_id === undefined ? body : { ...body, workspace_id: search_space_id },
}); });
}; };
@ -118,7 +121,7 @@ class LogsApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
const { search_space_id, hours } = parsedRequest.data; const { search_space_id, hours } = parsedRequest.data;
const url = `/api/v1/logs/search-space/${search_space_id}/summary${hours ? `?hours=${hours}` : ""}`; const url = `/api/v1/logs/workspaces/${search_space_id}/summary${hours ? `?hours=${hours}` : ""}`;
return baseApiService.get(url, getLogSummaryResponse); return baseApiService.get(url, getLogSummaryResponse);
}; };
} }

View file

@ -33,7 +33,7 @@ class MembersApiService {
} }
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/members`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/members`,
getMembersResponse getMembersResponse
); );
}; };
@ -52,7 +52,7 @@ class MembersApiService {
} }
return baseApiService.put( return baseApiService.put(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/members/${parsedRequest.data.membership_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/members/${parsedRequest.data.membership_id}`,
updateMembershipResponse, updateMembershipResponse,
{ {
body: parsedRequest.data.data, body: parsedRequest.data.data,
@ -74,7 +74,7 @@ class MembersApiService {
} }
return baseApiService.delete( return baseApiService.delete(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/members/${parsedRequest.data.membership_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/members/${parsedRequest.data.membership_id}`,
deleteMembershipResponse deleteMembershipResponse
); );
}; };
@ -93,7 +93,7 @@ class MembersApiService {
} }
return baseApiService.delete( return baseApiService.delete(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/members/me`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/members/me`,
leaveSearchSpaceResponse leaveSearchSpaceResponse
); );
}; };
@ -112,7 +112,7 @@ class MembersApiService {
} }
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/my-access`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/my-access`,
getMyAccessResponse getMyAccessResponse
); );
}; };

View file

@ -46,7 +46,7 @@ class ModelConnectionsApiService {
getConnections = async (searchSpaceId: number): Promise<ConnectionRead[]> => { getConnections = async (searchSpaceId: number): Promise<ConnectionRead[]> => {
return baseApiService.get( return baseApiService.get(
`/api/v1/model-connections?search_space_id=${searchSpaceId}`, `/api/v1/model-connections?workspace_id=${searchSpaceId}`,
connectionListResponse connectionListResponse
); );
}; };
@ -56,8 +56,15 @@ class ModelConnectionsApiService {
if (!parsed.success) { if (!parsed.success) {
throw new ValidationError(parsed.error.issues.map((issue) => issue.message).join(", ")); throw new ValidationError(parsed.error.issues.map((issue) => issue.message).join(", "));
} }
const { search_space_id, ...body } = parsed.data;
if (
body.scope === "SEARCH_SPACE" &&
(!Number.isFinite(search_space_id) || (search_space_id ?? 0) <= 0)
) {
throw new ValidationError("workspace_id is required");
}
return baseApiService.post(`/api/v1/model-connections`, connectionRead, { return baseApiService.post(`/api/v1/model-connections`, connectionRead, {
body: parsed.data, body: { ...body, workspace_id: search_space_id },
}); });
}; };
@ -91,11 +98,18 @@ class ModelConnectionsApiService {
if (!parsed.success) { if (!parsed.success) {
throw new ValidationError(parsed.error.issues.map((issue) => issue.message).join(", ")); throw new ValidationError(parsed.error.issues.map((issue) => issue.message).join(", "));
} }
const { search_space_id, ...body } = parsed.data;
if (
body.scope === "SEARCH_SPACE" &&
(!Number.isFinite(search_space_id) || (search_space_id ?? 0) <= 0)
) {
throw new ValidationError("workspace_id is required");
}
return baseApiService.post( return baseApiService.post(
`/api/v1/model-connections/discover-preview`, `/api/v1/model-connections/discover-preview`,
modelPreviewListResponse, modelPreviewListResponse,
{ {
body: parsed.data, body: { ...body, workspace_id: search_space_id },
} }
); );
}; };
@ -107,8 +121,15 @@ class ModelConnectionsApiService {
if (!parsed.success) { if (!parsed.success) {
throw new ValidationError(parsed.error.issues.map((issue) => issue.message).join(", ")); throw new ValidationError(parsed.error.issues.map((issue) => issue.message).join(", "));
} }
const { search_space_id, ...body } = parsed.data;
if (
body.scope === "SEARCH_SPACE" &&
(!Number.isFinite(search_space_id) || (search_space_id ?? 0) <= 0)
) {
throw new ValidationError("workspace_id is required");
}
return baseApiService.post(`/api/v1/model-connections/test-preview`, verifyConnectionResponse, { return baseApiService.post(`/api/v1/model-connections/test-preview`, verifyConnectionResponse, {
body: parsed.data, body: { ...body, workspace_id: search_space_id },
}); });
}; };
@ -159,11 +180,11 @@ class ModelConnectionsApiService {
}; };
getModelRoles = async (searchSpaceId: number): Promise<ModelRoles> => { getModelRoles = async (searchSpaceId: number): Promise<ModelRoles> => {
return baseApiService.get(`/api/v1/search-spaces/${searchSpaceId}/model-roles`, modelRoles); return baseApiService.get(`/api/v1/workspaces/${searchSpaceId}/model-roles`, modelRoles);
}; };
updateModelRoles = async (searchSpaceId: number, roles: ModelRoles): Promise<ModelRoles> => { updateModelRoles = async (searchSpaceId: number, roles: ModelRoles): Promise<ModelRoles> => {
return baseApiService.put(`/api/v1/search-spaces/${searchSpaceId}/model-roles`, modelRoles, { return baseApiService.put(`/api/v1/workspaces/${searchSpaceId}/model-roles`, modelRoles, {
body: roles, body: roles,
}); });
}; };

View file

@ -42,7 +42,7 @@ class NotificationsApiService {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (queryParams.search_space_id !== undefined) { if (queryParams.search_space_id !== undefined) {
params.append("search_space_id", String(queryParams.search_space_id)); params.append("workspace_id", String(queryParams.search_space_id));
} }
if (queryParams.type) { if (queryParams.type) {
params.append("type", queryParams.type); params.append("type", queryParams.type);
@ -113,7 +113,7 @@ class NotificationsApiService {
getSourceTypes = async (searchSpaceId?: number): Promise<GetSourceTypesResponse> => { getSourceTypes = async (searchSpaceId?: number): Promise<GetSourceTypesResponse> => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (searchSpaceId !== undefined) { if (searchSpaceId !== undefined) {
params.append("search_space_id", String(searchSpaceId)); params.append("workspace_id", String(searchSpaceId));
} }
const queryString = params.toString(); const queryString = params.toString();
@ -136,7 +136,7 @@ class NotificationsApiService {
): Promise<GetUnreadCountResponse> => { ): Promise<GetUnreadCountResponse> => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (searchSpaceId !== undefined) { if (searchSpaceId !== undefined) {
params.append("search_space_id", String(searchSpaceId)); params.append("workspace_id", String(searchSpaceId));
} }
if (type) { if (type) {
params.append("type", type); params.append("type", type);
@ -159,7 +159,7 @@ class NotificationsApiService {
getBatchUnreadCounts = async (searchSpaceId?: number): Promise<GetBatchUnreadCountResponse> => { getBatchUnreadCounts = async (searchSpaceId?: number): Promise<GetBatchUnreadCountResponse> => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (searchSpaceId !== undefined) { if (searchSpaceId !== undefined) {
params.append("search_space_id", String(searchSpaceId)); params.append("workspace_id", String(searchSpaceId));
} }
const queryString = params.toString(); const queryString = params.toString();

View file

@ -17,7 +17,7 @@ const voiceOptionList = z.array(voiceOption);
class PodcastsApiService { class PodcastsApiService {
list = async (searchSpaceId: number, limit = 200) => { list = async (searchSpaceId: number, limit = 200) => {
const qs = new URLSearchParams({ const qs = new URLSearchParams({
search_space_id: String(searchSpaceId), workspace_id: String(searchSpaceId),
limit: String(limit), limit: String(limit),
}).toString(); }).toString();
return baseApiService.get(`${BASE}?${qs}`, podcastSummaryList); return baseApiService.get(`${BASE}?${qs}`, podcastSummaryList);

View file

@ -15,7 +15,7 @@ class PromptsApiService {
list = async (searchSpaceId?: number) => { list = async (searchSpaceId?: number) => {
const params = new URLSearchParams(); const params = new URLSearchParams();
if (searchSpaceId !== undefined) { if (searchSpaceId !== undefined) {
params.set("search_space_id", String(searchSpaceId)); params.set("workspace_id", String(searchSpaceId));
} }
const queryString = params.toString(); const queryString = params.toString();
const url = queryString ? `/api/v1/prompts?${queryString}` : "/api/v1/prompts"; const url = queryString ? `/api/v1/prompts?${queryString}` : "/api/v1/prompts";
@ -30,8 +30,9 @@ class PromptsApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
const { search_space_id, ...body } = parsed.data;
return baseApiService.post("/api/v1/prompts", promptRead, { return baseApiService.post("/api/v1/prompts", promptRead, {
body: parsed.data, body: { ...body, workspace_id: search_space_id },
}); });
}; };

View file

@ -6,7 +6,7 @@ const BASE = "/api/v1/reports";
class ReportsApiService { class ReportsApiService {
list = async (searchSpaceId: number, limit = 200) => { list = async (searchSpaceId: number, limit = 200) => {
const qs = new URLSearchParams({ const qs = new URLSearchParams({
search_space_id: String(searchSpaceId), workspace_id: String(searchSpaceId),
limit: String(limit), limit: String(limit),
}).toString(); }).toString();
return baseApiService.get(`${BASE}?${qs}`, reportList); return baseApiService.get(`${BASE}?${qs}`, reportList);

View file

@ -30,7 +30,7 @@ class RolesApiService {
} }
return baseApiService.post( return baseApiService.post(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/roles`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/roles`,
createRoleResponse, createRoleResponse,
{ {
body: parsedRequest.data.data, body: parsedRequest.data.data,
@ -49,7 +49,7 @@ class RolesApiService {
} }
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/roles`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/roles`,
getRolesResponse getRolesResponse
); );
}; };
@ -65,7 +65,7 @@ class RolesApiService {
} }
return baseApiService.get( return baseApiService.get(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/roles/${parsedRequest.data.role_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/roles/${parsedRequest.data.role_id}`,
getRoleByIdResponse getRoleByIdResponse
); );
}; };
@ -81,7 +81,7 @@ class RolesApiService {
} }
return baseApiService.put( return baseApiService.put(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/roles/${parsedRequest.data.role_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/roles/${parsedRequest.data.role_id}`,
updateRoleResponse, updateRoleResponse,
{ {
body: parsedRequest.data.data, body: parsedRequest.data.data,
@ -100,7 +100,7 @@ class RolesApiService {
} }
return baseApiService.delete( return baseApiService.delete(
`/api/v1/searchspaces/${parsedRequest.data.search_space_id}/roles/${parsedRequest.data.role_id}`, `/api/v1/workspaces/${parsedRequest.data.search_space_id}/roles/${parsedRequest.data.role_id}`,
deleteRoleResponse deleteRoleResponse
); );
}; };

View file

@ -50,7 +50,7 @@ class SearchSpacesApiService {
? new URLSearchParams(transformedQueryParams).toString() ? new URLSearchParams(transformedQueryParams).toString()
: ""; : "";
return baseApiService.get(`/api/v1/searchspaces?${queryParams}`, getSearchSpacesResponse); return baseApiService.get(`/api/v1/workspaces?${queryParams}`, getSearchSpacesResponse);
}; };
/** /**
@ -66,7 +66,7 @@ class SearchSpacesApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
return baseApiService.post(`/api/v1/searchspaces`, createSearchSpaceResponse, { return baseApiService.post(`/api/v1/workspaces`, createSearchSpaceResponse, {
body: parsedRequest.data, body: parsedRequest.data,
}); });
}; };
@ -84,7 +84,7 @@ class SearchSpacesApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
return baseApiService.get(`/api/v1/searchspaces/${request.id}`, getSearchSpaceResponse); return baseApiService.get(`/api/v1/workspaces/${request.id}`, getSearchSpaceResponse);
}; };
/** /**
@ -100,7 +100,7 @@ class SearchSpacesApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
return baseApiService.put(`/api/v1/searchspaces/${request.id}`, updateSearchSpaceResponse, { return baseApiService.put(`/api/v1/workspaces/${request.id}`, updateSearchSpaceResponse, {
body: parsedRequest.data.data, body: parsedRequest.data.data,
}); });
}; };
@ -115,7 +115,7 @@ class SearchSpacesApiService {
} }
return baseApiService.put( return baseApiService.put(
`/api/v1/searchspaces/${request.id}/api-access`, `/api/v1/workspaces/${request.id}/api-access`,
updateSearchSpaceApiAccessResponse, updateSearchSpaceApiAccessResponse,
{ {
body: { api_access_enabled: parsedRequest.data.api_access_enabled }, body: { api_access_enabled: parsedRequest.data.api_access_enabled },
@ -136,7 +136,7 @@ class SearchSpacesApiService {
throw new ValidationError(`Invalid request: ${errorMessage}`); throw new ValidationError(`Invalid request: ${errorMessage}`);
} }
return baseApiService.delete(`/api/v1/searchspaces/${request.id}`, deleteSearchSpaceResponse); return baseApiService.delete(`/api/v1/workspaces/${request.id}`, deleteSearchSpaceResponse);
}; };
/** /**
@ -144,7 +144,7 @@ class SearchSpacesApiService {
*/ */
triggerAiSort = async (searchSpaceId: number) => { triggerAiSort = async (searchSpaceId: number) => {
return baseApiService.post( return baseApiService.post(
`/api/v1/searchspaces/${searchSpaceId}/ai-sort`, `/api/v1/workspaces/${searchSpaceId}/ai-sort`,
z.object({ message: z.string() }), z.object({ message: z.string() }),
{} {}
); );
@ -156,7 +156,7 @@ class SearchSpacesApiService {
*/ */
leaveSearchSpace = async (searchSpaceId: number) => { leaveSearchSpace = async (searchSpaceId: number) => {
return baseApiService.delete( return baseApiService.delete(
`/api/v1/searchspaces/${searchSpaceId}/members/me`, `/api/v1/workspaces/${searchSpaceId}/members/me`,
leaveSearchSpaceResponse leaveSearchSpaceResponse
); );
}; };

View file

@ -23,10 +23,11 @@ class StripeApiService {
createCreditCheckoutSession = async ( createCreditCheckoutSession = async (
request: CreateCreditCheckoutSessionRequest request: CreateCreditCheckoutSessionRequest
): Promise<CreateCreditCheckoutSessionResponse> => { ): Promise<CreateCreditCheckoutSessionResponse> => {
const { search_space_id, ...body } = request;
return baseApiService.post( return baseApiService.post(
"/api/v1/stripe/create-credit-checkout-session", "/api/v1/stripe/create-credit-checkout-session",
createCreditCheckoutSessionResponse, createCreditCheckoutSessionResponse,
{ body: request } { body: { ...body, workspace_id: search_space_id } }
); );
}; };
@ -74,10 +75,11 @@ class StripeApiService {
createAutoReloadSetupSession = async ( createAutoReloadSetupSession = async (
request: CreateAutoReloadSetupSessionRequest request: CreateAutoReloadSetupSessionRequest
): Promise<CreateAutoReloadSetupSessionResponse> => { ): Promise<CreateAutoReloadSetupSessionResponse> => {
const { search_space_id } = request;
return baseApiService.post( return baseApiService.post(
"/api/v1/stripe/auto-reload/setup", "/api/v1/stripe/auto-reload/setup",
createAutoReloadSetupSessionResponse, createAutoReloadSetupSessionResponse,
{ body: request } { body: { workspace_id: search_space_id } }
); );
}; };
} }

View file

@ -6,7 +6,7 @@ const BASE = "/api/v1/video-presentations";
class VideoPresentationsApiService { class VideoPresentationsApiService {
list = async (searchSpaceId: number, limit = 200) => { list = async (searchSpaceId: number, limit = 200) => {
const qs = new URLSearchParams({ const qs = new URLSearchParams({
search_space_id: String(searchSpaceId), workspace_id: String(searchSpaceId),
limit: String(limit), limit: String(limit),
}).toString(); }).toString();
return baseApiService.get(`${BASE}?${qs}`, videoPresentationList); return baseApiService.get(`${BASE}?${qs}`, videoPresentationList);

View file

@ -95,7 +95,7 @@ export async function fetchThreads(
searchSpaceId: number, searchSpaceId: number,
limit?: number limit?: number
): Promise<ThreadListResponse> { ): Promise<ThreadListResponse> {
const params = new URLSearchParams({ search_space_id: String(searchSpaceId) }); const params = new URLSearchParams({ workspace_id: String(searchSpaceId) });
if (limit) params.append("limit", String(limit)); if (limit) params.append("limit", String(limit));
return baseApiService.get<ThreadListResponse>(`/api/v1/threads?${params}`); return baseApiService.get<ThreadListResponse>(`/api/v1/threads?${params}`);
} }
@ -108,7 +108,7 @@ export async function searchThreads(
title: string title: string
): Promise<ThreadListItem[]> { ): Promise<ThreadListItem[]> {
const params = new URLSearchParams({ const params = new URLSearchParams({
search_space_id: String(searchSpaceId), workspace_id: String(searchSpaceId),
title, title,
}); });
return baseApiService.get<ThreadListItem[]>(`/api/v1/threads/search?${params}`); return baseApiService.get<ThreadListItem[]>(`/api/v1/threads/search?${params}`);
@ -125,7 +125,7 @@ export async function createThread(
body: { body: {
title, title,
archived: false, archived: false,
search_space_id: searchSpaceId, workspace_id: searchSpaceId,
}, },
}); });
} }

View file

@ -0,0 +1,11 @@
type RouteParams = Record<string, string | string[] | undefined>;
export function getWorkspaceIdParam(params: RouteParams | null | undefined): string | undefined {
const value = params?.workspace_id ?? params?.search_space_id;
return Array.isArray(value) ? value[0] : value;
}
export function getWorkspaceIdNumber(params: RouteParams | null | undefined): number | undefined {
const parsed = Number(getWorkspaceIdParam(params));
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
}

View file

@ -29,7 +29,7 @@ export const chatThreadFixtures = {
headers: authHeaders(apiToken), headers: authHeaders(apiToken),
data: { data: {
title: "e2e-drive-journey", title: "e2e-drive-journey",
search_space_id: searchSpace.id, workspace_id: searchSpace.id,
visibility: "PRIVATE", visibility: "PRIVATE",
}, },
}); });

View file

@ -24,7 +24,7 @@ export async function streamChatToCompletion(
headers: authHeaders(token), headers: authHeaders(token),
data: { data: {
chat_id: args.threadId, chat_id: args.threadId,
search_space_id: args.searchSpaceId, workspace_id: args.searchSpaceId,
user_query: args.query, user_query: args.query,
}, },
}); });

View file

@ -16,7 +16,7 @@ export async function listConnectors(
searchSpaceId: number searchSpaceId: number
): Promise<ConnectorRow[]> { ): Promise<ConnectorRow[]> {
const response = await request.get( const response = await request.get(
`${BACKEND_URL}/api/v1/search-source-connectors?search_space_id=${searchSpaceId}`, `${BACKEND_URL}/api/v1/search-source-connectors?workspace_id=${searchSpaceId}`,
{ headers: authHeaders(token) } { headers: authHeaders(token) }
); );
if (!response.ok()) { if (!response.ok()) {
@ -115,7 +115,7 @@ export async function triggerIndex(
body: IndexBody body: IndexBody
): Promise<{ ok: true }> { ): Promise<{ ok: true }> {
const response = await request.post( const response = await request.post(
`${BACKEND_URL}/api/v1/search-source-connectors/${connectorId}/index?search_space_id=${searchSpaceId}`, `${BACKEND_URL}/api/v1/search-source-connectors/${connectorId}/index?workspace_id=${searchSpaceId}`,
{ headers: authHeaders(token), data: body } { headers: authHeaders(token), data: body }
); );
if (!response.ok()) { if (!response.ok()) {
@ -134,7 +134,7 @@ export async function triggerIndexExpectDisabled(
body: IndexBody = {} body: IndexBody = {}
): Promise<{ indexing_started: false; message?: string }> { ): Promise<{ indexing_started: false; message?: string }> {
const response = await request.post( const response = await request.post(
`${BACKEND_URL}/api/v1/search-source-connectors/${connectorId}/index?search_space_id=${searchSpaceId}`, `${BACKEND_URL}/api/v1/search-source-connectors/${connectorId}/index?workspace_id=${searchSpaceId}`,
{ headers: authHeaders(token), data: body } { headers: authHeaders(token), data: body }
); );
if (!response.ok()) { if (!response.ok()) {

View file

@ -21,7 +21,7 @@ export async function listDocuments(
limit = 100 limit = 100
): Promise<DocumentRow[]> { ): Promise<DocumentRow[]> {
const response = await request.get( const response = await request.get(
`${BACKEND_URL}/api/v1/documents?search_space_id=${searchSpaceId}&limit=${limit}`, `${BACKEND_URL}/api/v1/documents?workspace_id=${searchSpaceId}&limit=${limit}`,
{ headers: authHeaders(token) } { headers: authHeaders(token) }
); );
if (!response.ok()) { if (!response.ok()) {

View file

@ -13,7 +13,7 @@ export async function createSearchSpace(
name: string, name: string,
description = "E2E test search space" description = "E2E test search space"
): Promise<SearchSpaceRow> { ): Promise<SearchSpaceRow> {
const response = await request.post(`${BACKEND_URL}/api/v1/searchspaces`, { const response = await request.post(`${BACKEND_URL}/api/v1/workspaces`, {
headers: authHeaders(token), headers: authHeaders(token),
data: { name, description }, data: { name, description },
}); });
@ -28,7 +28,7 @@ export async function deleteSearchSpace(
token: string, token: string,
id: number id: number
): Promise<void> { ): Promise<void> {
const response = await request.delete(`${BACKEND_URL}/api/v1/searchspaces/${id}`, { const response = await request.delete(`${BACKEND_URL}/api/v1/workspaces/${id}`, {
headers: authHeaders(token), headers: authHeaders(token),
}); });
if (!response.ok() && response.status() !== 404) { if (!response.ok() && response.status() !== 404) {

View file

@ -12,7 +12,7 @@ test.describe("Smoke", () => {
headers: authHeaders(apiToken), headers: authHeaders(apiToken),
data: { data: {
title: "e2e-chat-stream-smoke", title: "e2e-chat-stream-smoke",
search_space_id: searchSpace.id, workspace_id: searchSpace.id,
visibility: "PRIVATE", visibility: "PRIVATE",
}, },
}); });

View file

@ -3,7 +3,7 @@ import { json, number, string, table } from "@rocicorp/zero";
export const automationTable = table("automations") export const automationTable = table("automations")
.columns({ .columns({
id: number(), id: number(),
searchSpaceId: number().from("search_space_id"), searchSpaceId: number().from("workspace_id"),
}) })
.primaryKey("id"); .primaryKey("id");

View file

@ -23,7 +23,7 @@ export const newChatMessageTable = table("new_chat_messages")
export const newChatThreadTable = table("new_chat_threads") export const newChatThreadTable = table("new_chat_threads")
.columns({ .columns({
id: number(), id: number(),
searchSpaceId: number().from("search_space_id"), searchSpaceId: number().from("workspace_id"),
}) })
.primaryKey("id"); .primaryKey("id");

View file

@ -5,7 +5,7 @@ export const documentTable = table("documents")
id: number(), id: number(),
title: string(), title: string(),
documentType: string().from("document_type"), documentType: string().from("document_type"),
searchSpaceId: number().from("search_space_id"), searchSpaceId: number().from("workspace_id"),
folderId: number().optional().from("folder_id"), folderId: number().optional().from("folder_id"),
createdById: string().optional().from("created_by_id"), createdById: string().optional().from("created_by_id"),
status: json(), status: json(),
@ -24,7 +24,7 @@ export const searchSourceConnectorTable = table("search_source_connectors")
periodicIndexingEnabled: boolean().from("periodic_indexing_enabled"), periodicIndexingEnabled: boolean().from("periodic_indexing_enabled"),
indexingFrequencyMinutes: number().optional().from("indexing_frequency_minutes"), indexingFrequencyMinutes: number().optional().from("indexing_frequency_minutes"),
nextScheduledAt: number().optional().from("next_scheduled_at"), nextScheduledAt: number().optional().from("next_scheduled_at"),
searchSpaceId: number().from("search_space_id"), searchSpaceId: number().from("workspace_id"),
userId: string().from("user_id"), userId: string().from("user_id"),
createdAt: number().from("created_at"), createdAt: number().from("created_at"),
}) })

View file

@ -6,7 +6,7 @@ export const folderTable = table("folders")
name: string(), name: string(),
position: string(), position: string(),
parentId: number().optional().from("parent_id"), parentId: number().optional().from("parent_id"),
searchSpaceId: number().from("search_space_id"), searchSpaceId: number().from("workspace_id"),
createdById: string().optional().from("created_by_id"), createdById: string().optional().from("created_by_id"),
createdAt: number().from("created_at"), createdAt: number().from("created_at"),
updatedAt: number().from("updated_at"), updatedAt: number().from("updated_at"),

View file

@ -4,7 +4,7 @@ export const notificationTable = table("notifications")
.columns({ .columns({
id: number(), id: number(),
userId: string().from("user_id"), userId: string().from("user_id"),
searchSpaceId: number().optional().from("search_space_id"), searchSpaceId: number().optional().from("workspace_id"),
type: string(), type: string(),
title: string(), title: string(),
message: string(), message: string(),

View file

@ -12,7 +12,7 @@ export const podcastTable = table("podcasts")
specVersion: number().from("spec_version"), specVersion: number().from("spec_version"),
durationSeconds: number().optional().from("duration_seconds"), durationSeconds: number().optional().from("duration_seconds"),
error: string().optional(), error: string().optional(),
searchSpaceId: number().from("search_space_id"), searchSpaceId: number().from("workspace_id"),
threadId: number().optional().from("thread_id"), threadId: number().optional().from("thread_id"),
createdAt: number().from("created_at"), createdAt: number().from("created_at"),
}) })