feat: implement ensure_publication for zero_publication management

- Added the ensure_publication function to create and verify the zero_publication if it is missing, ensuring idempotency during database initialization.
- Integrated ensure_publication into the create_db_and_tables function to prevent zero-cache crash loops on startup.
- Introduced a self-check script to validate the ensure_publication functionality on a create_all-bootstrapped database.
- Updated various components to reflect the transition from search space to workspace, including adjustments in imports and routing paths.
This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-07-05 23:17:13 -07:00
parent 7562bc78ee
commit a64c8205fe
164 changed files with 626 additions and 506 deletions

View file

@ -93,7 +93,7 @@ export function applyActionLogSse(
id: event.id,
thread_id: threadId,
user_id: null,
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
tool_name: event.tool_name,
args: null,
result_id: null,

View file

@ -27,7 +27,7 @@ export function useConnectorsSync(searchSpaceId: number | string | null) {
periodic_indexing_enabled: c.periodicIndexingEnabled,
indexing_frequency_minutes: c.indexingFrequencyMinutes ?? null,
next_scheduled_at: c.nextScheduledAt ? new Date(c.nextScheduledAt).toISOString() : null,
search_space_id: c.searchSpaceId,
workspace_id: c.searchSpaceId,
user_id: c.userId,
created_at: c.createdAt ? new Date(c.createdAt).toISOString() : new Date().toISOString(),
}));

View file

@ -56,7 +56,7 @@ export function useDocumentSearch(
documentsApiService
.searchDocuments({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
page: 0,
page_size: SEARCH_INITIAL_SIZE,
title: query.trim(),
@ -91,7 +91,7 @@ export function useDocumentSearch(
try {
const response = await documentsApiService.searchDocuments({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
skip: apiLoadedRef.current,
page_size: SEARCH_SCROLL_SIZE,
title: query.trim(),

View file

@ -13,7 +13,7 @@ export interface DocumentStatusType {
export interface DocumentDisplay {
id: number;
search_space_id: number;
workspace_id: number;
document_type: string;
title: string;
created_by_id: string | null;
@ -25,7 +25,7 @@ export interface DocumentDisplay {
export interface ApiDocumentInput {
id: number;
search_space_id: number;
workspace_id: number;
document_type: string;
title: string;
created_by_id?: string | null;
@ -38,7 +38,7 @@ export interface ApiDocumentInput {
export function toDisplayDoc(item: ApiDocumentInput): DocumentDisplay {
return {
id: item.id,
search_space_id: item.search_space_id,
workspace_id: item.workspace_id,
document_type: item.document_type,
title: item.title,
created_by_id: item.created_by_id ?? null,
@ -142,7 +142,7 @@ export function useDocuments(
const [docsResponse, countsResponse] = await Promise.all([
documentsApiService.getDocuments({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
page: 0,
page_size: INITIAL_PAGE_SIZE,
...(typeFilter.length > 0 && { document_types: typeFilter }),
@ -151,7 +151,7 @@ export function useDocuments(
},
}),
documentsApiService.getDocumentTypeCounts({
queryParams: { search_space_id: searchSpaceId },
queryParams: { workspace_id: searchSpaceId },
}),
]);
@ -201,7 +201,7 @@ export function useDocuments(
documentsApiService
.getDocuments({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
page: 0,
page_size: 20,
},
@ -232,7 +232,7 @@ export function useDocuments(
.filter((d) => !prevIds.has(d.id))
.map((doc) => ({
id: doc.id,
search_space_id: doc.searchSpaceId,
workspace_id: doc.searchSpaceId,
document_type: doc.documentType,
title: doc.title,
created_by_id: doc.createdById ?? null,
@ -308,7 +308,7 @@ export function useDocuments(
try {
const response = await documentsApiService.getDocuments({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
skip: apiLoadedCountRef.current,
page_size: SCROLL_PAGE_SIZE,
...(typeFilter.length > 0 && { document_types: typeFilter }),

View file

@ -66,7 +66,7 @@ export function useFolderSync() {
await documentsApiService.folderUploadFiles(files, {
folder_name: batch.folderName,
search_space_id: batch.searchSpaceId,
workspace_id: batch.searchSpaceId,
relative_paths: addChangeFiles.map((f) => f.relativePath),
root_folder_id: batch.rootFolderId,
});
@ -75,7 +75,7 @@ export function useFolderSync() {
if (unlinkFiles.length > 0) {
await documentsApiService.folderNotifyUnlinked({
folder_name: batch.folderName,
search_space_id: batch.searchSpaceId,
workspace_id: batch.searchSpaceId,
root_folder_id: batch.rootFolderId,
relative_paths: unlinkFiles.map((f) => f.relativePath),
});

View file

@ -79,7 +79,7 @@ export function useInbox(
try {
const notificationsPromise = notificationsApiService.getNotifications({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
category,
limit: INITIAL_PAGE_SIZE,
},
@ -146,7 +146,7 @@ export function useInbox(
({
id: item.id,
user_id: item.userId,
search_space_id: item.searchSpaceId ?? undefined,
workspace_id: item.searchSpaceId ?? undefined,
type: item.type,
title: item.title,
message: item.message,
@ -208,7 +208,7 @@ export function useInbox(
const response = await notificationsApiService.getNotifications({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
category,
before_date: beforeDate,
limit: SCROLL_PAGE_SIZE,

View file

@ -24,8 +24,8 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
const allFilters = { ...memoizedFilters, ...customFilters };
if (allFilters.search_space_id) {
params.search_space_id = allFilters.search_space_id.toString();
if (allFilters.workspace_id) {
params.workspace_id = allFilters.workspace_id.toString();
}
if (allFilters.level) {
params.level = allFilters.level;
@ -55,13 +55,13 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
refetch,
} = useQuery({
queryKey: cacheKeys.logs.withQueryParams({
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
...buildQueryParams(filters ?? {}),
}),
queryFn: () =>
logsApiService.getLogs({
queryParams: {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
...buildQueryParams(filters ?? {}),
},
}),
@ -95,7 +95,7 @@ export function useLogsSummary(
queryKey: cacheKeys.logs.summary(searchSpaceId),
queryFn: () =>
logsApiService.getLogSummary({
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
hours: hours,
}),
enabled: !!searchSpaceId,

View file

@ -8,7 +8,7 @@ export interface SearchSourceConnector {
is_indexable: boolean;
last_indexed_at: string | null;
config: Record<string, unknown>;
search_space_id: number;
workspace_id: number;
user_id?: string;
created_at?: string;
periodic_indexing_enabled: boolean;
@ -108,7 +108,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
const response = await authenticatedFetch(
buildBackendUrl("/api/v1/search-source-connectors", {
search_space_id: spaceId,
workspace_id: spaceId,
}),
{
method: "GET",
@ -157,17 +157,17 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
/**
* Create a new search source connector
* @param connectorData - The connector data (excluding search_space_id)
* @param connectorData - The connector data (excluding workspace_id)
* @param spaceId - The search space ID to associate the connector with
*/
const createConnector = async (
connectorData: Omit<SearchSourceConnector, "id" | "user_id" | "created_at" | "search_space_id">,
connectorData: Omit<SearchSourceConnector, "id" | "user_id" | "created_at" | "workspace_id">,
spaceId: number
) => {
try {
const response = await authenticatedFetch(
buildBackendUrl("/api/v1/search-source-connectors", {
search_space_id: spaceId,
workspace_id: spaceId,
}),
{
method: "POST",
@ -199,7 +199,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
const updateConnector = async (
connectorId: number,
connectorData: Partial<
Omit<SearchSourceConnector, "id" | "user_id" | "created_at" | "search_space_id">
Omit<SearchSourceConnector, "id" | "user_id" | "created_at" | "workspace_id">
>
) => {
try {
@ -269,7 +269,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
try {
const response = await authenticatedFetch(
buildBackendUrl(`/api/v1/search-source-connectors/${connectorId}/index`, {
search_space_id: searchSpaceId,
workspace_id: searchSpaceId,
start_date: startDate,
end_date: endDate,
}),