mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-22 23:31:12 +02:00
merge
This commit is contained in:
commit
49d51ba569
70 changed files with 4266 additions and 1362 deletions
|
|
@ -1,5 +1,19 @@
|
|||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Raw comment
|
||||
*/
|
||||
export const rawComment = z.object({
|
||||
id: z.number(),
|
||||
message_id: z.number(),
|
||||
thread_id: z.number(), // Denormalized for efficient Electric subscriptions
|
||||
parent_id: z.number().nullable(),
|
||||
author_id: z.string().nullable(),
|
||||
content: z.string(),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string(),
|
||||
});
|
||||
|
||||
export const author = z.object({
|
||||
id: z.string().uuid(),
|
||||
display_name: z.string().nullable(),
|
||||
|
|
@ -122,6 +136,7 @@ export const getMentionsResponse = z.object({
|
|||
total_count: z.number(),
|
||||
});
|
||||
|
||||
export type RawComment = z.infer<typeof rawComment>;
|
||||
export type Author = z.infer<typeof author>;
|
||||
export type CommentReply = z.infer<typeof commentReply>;
|
||||
export type Comment = z.infer<typeof comment>;
|
||||
|
|
|
|||
15
surfsense_web/contracts/types/chat-messages.types.ts
Normal file
15
surfsense_web/contracts/types/chat-messages.types.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Raw message from database (Electric SQL sync)
|
||||
*/
|
||||
export const rawMessage = z.object({
|
||||
id: z.number(),
|
||||
thread_id: z.number(),
|
||||
role: z.string(),
|
||||
content: z.unknown(),
|
||||
author_id: z.string().nullable(),
|
||||
created_at: z.string(),
|
||||
});
|
||||
|
||||
export type RawMessage = z.infer<typeof rawMessage>;
|
||||
24
surfsense_web/contracts/types/chat-session-state.types.ts
Normal file
24
surfsense_web/contracts/types/chat-session-state.types.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Chat session state for live collaboration.
|
||||
* Tracks which user the AI is currently responding to.
|
||||
*/
|
||||
export const chatSessionState = z.object({
|
||||
id: z.number(),
|
||||
thread_id: z.number(),
|
||||
ai_responding_to_user_id: z.string().uuid().nullable(),
|
||||
updated_at: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* User currently being responded to by the AI.
|
||||
*/
|
||||
export const respondingUser = z.object({
|
||||
id: z.string().uuid(),
|
||||
display_name: z.string().nullable(),
|
||||
email: z.string(),
|
||||
});
|
||||
|
||||
export type ChatSessionState = z.infer<typeof chatSessionState>;
|
||||
export type RespondingUser = z.infer<typeof respondingUser>;
|
||||
281
surfsense_web/contracts/types/inbox.types.ts
Normal file
281
surfsense_web/contracts/types/inbox.types.ts
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
import { z } from "zod";
|
||||
import { searchSourceConnectorTypeEnum } from "./connector.types";
|
||||
import { documentTypeEnum } from "./document.types";
|
||||
|
||||
/**
|
||||
* Inbox item type enum - matches backend notification types
|
||||
*/
|
||||
export const inboxItemTypeEnum = z.enum([
|
||||
"connector_indexing",
|
||||
"document_processing",
|
||||
"new_mention",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Inbox item status enum - used in metadata
|
||||
*/
|
||||
export const inboxItemStatusEnum = z.enum(["in_progress", "completed", "failed"]);
|
||||
|
||||
/**
|
||||
* Document processing stage enum
|
||||
*/
|
||||
export const documentProcessingStageEnum = z.enum([
|
||||
"queued",
|
||||
"parsing",
|
||||
"chunking",
|
||||
"embedding",
|
||||
"storing",
|
||||
"completed",
|
||||
"failed",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Base metadata schema shared across inbox item types
|
||||
*/
|
||||
export const baseInboxItemMetadata = z.object({
|
||||
operation_id: z.string().optional(),
|
||||
status: inboxItemStatusEnum.optional(),
|
||||
started_at: z.string().optional(),
|
||||
completed_at: z.string().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Connector indexing metadata schema
|
||||
*/
|
||||
export const connectorIndexingMetadata = baseInboxItemMetadata.extend({
|
||||
connector_id: z.number(),
|
||||
connector_name: z.string(),
|
||||
connector_type: searchSourceConnectorTypeEnum,
|
||||
start_date: z.string().nullable().optional(),
|
||||
end_date: z.string().nullable().optional(),
|
||||
indexed_count: z.number(),
|
||||
total_count: z.number().optional(),
|
||||
progress_percent: z.number().optional(),
|
||||
error_message: z.string().nullable().optional(),
|
||||
// Google Drive specific fields
|
||||
folder_count: z.number().optional(),
|
||||
file_count: z.number().optional(),
|
||||
folder_names: z.array(z.string()).optional(),
|
||||
file_names: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Document processing metadata schema
|
||||
*/
|
||||
export const documentProcessingMetadata = baseInboxItemMetadata.extend({
|
||||
document_type: documentTypeEnum,
|
||||
document_name: z.string(),
|
||||
processing_stage: documentProcessingStageEnum,
|
||||
file_size: z.number().optional(),
|
||||
chunks_count: z.number().optional(),
|
||||
document_id: z.number().optional(),
|
||||
error_message: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* New mention metadata schema
|
||||
*/
|
||||
export const newMentionMetadata = z.object({
|
||||
mention_id: z.number(),
|
||||
comment_id: z.number(),
|
||||
message_id: z.number(),
|
||||
thread_id: z.number(),
|
||||
thread_title: z.string(),
|
||||
author_id: z.string(),
|
||||
author_name: z.string(),
|
||||
author_avatar_url: z.string().nullable().optional(),
|
||||
author_email: z.string().optional(),
|
||||
content_preview: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Union of all inbox item metadata types
|
||||
* Use this when the inbox item type is unknown
|
||||
*/
|
||||
export const inboxItemMetadata = z.union([
|
||||
connectorIndexingMetadata,
|
||||
documentProcessingMetadata,
|
||||
newMentionMetadata,
|
||||
baseInboxItemMetadata,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Main inbox item schema
|
||||
*/
|
||||
export const inboxItem = z.object({
|
||||
id: z.number(),
|
||||
user_id: z.string(),
|
||||
search_space_id: z.number().nullable(),
|
||||
type: inboxItemTypeEnum,
|
||||
title: z.string(),
|
||||
message: z.string(),
|
||||
read: z.boolean(),
|
||||
metadata: z.record(z.string(), z.unknown()),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string().nullable(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Typed inbox item schemas for specific types
|
||||
*/
|
||||
export const connectorIndexingInboxItem = inboxItem.extend({
|
||||
type: z.literal("connector_indexing"),
|
||||
metadata: connectorIndexingMetadata,
|
||||
});
|
||||
|
||||
export const documentProcessingInboxItem = inboxItem.extend({
|
||||
type: z.literal("document_processing"),
|
||||
metadata: documentProcessingMetadata,
|
||||
});
|
||||
|
||||
export const newMentionInboxItem = inboxItem.extend({
|
||||
type: z.literal("new_mention"),
|
||||
metadata: newMentionMetadata,
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// API Request/Response Schemas
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Request schema for getting notifications
|
||||
*/
|
||||
export const getNotificationsRequest = z.object({
|
||||
queryParams: z.object({
|
||||
search_space_id: z.number().optional(),
|
||||
type: inboxItemTypeEnum.optional(),
|
||||
before_date: z.string().optional(),
|
||||
limit: z.number().min(1).max(100).optional(),
|
||||
offset: z.number().min(0).optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
/**
|
||||
* Response schema for listing notifications
|
||||
*/
|
||||
export const getNotificationsResponse = z.object({
|
||||
items: z.array(inboxItem),
|
||||
total: z.number(),
|
||||
has_more: z.boolean(),
|
||||
next_offset: z.number().nullable(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Request schema for marking a single notification as read
|
||||
*/
|
||||
export const markNotificationReadRequest = z.object({
|
||||
notificationId: z.number(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Response schema for mark as read operations
|
||||
*/
|
||||
export const markNotificationReadResponse = z.object({
|
||||
success: z.boolean(),
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Response schema for mark all as read operation
|
||||
*/
|
||||
export const markAllNotificationsReadResponse = z.object({
|
||||
success: z.boolean(),
|
||||
message: z.string(),
|
||||
updated_count: z.number(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Request schema for getting unread count
|
||||
*/
|
||||
export const getUnreadCountRequest = z.object({
|
||||
search_space_id: z.number().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Response schema for unread count
|
||||
* Returns both total and recent counts for split tracking
|
||||
*/
|
||||
export const getUnreadCountResponse = z.object({
|
||||
total_unread: z.number(),
|
||||
recent_unread: z.number(), // Within SYNC_WINDOW_DAYS (14 days)
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// Type Guards for Metadata
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Type guard for ConnectorIndexingMetadata
|
||||
*/
|
||||
export function isConnectorIndexingMetadata(
|
||||
metadata: unknown
|
||||
): metadata is ConnectorIndexingMetadata {
|
||||
return connectorIndexingMetadata.safeParse(metadata).success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard for DocumentProcessingMetadata
|
||||
*/
|
||||
export function isDocumentProcessingMetadata(
|
||||
metadata: unknown
|
||||
): metadata is DocumentProcessingMetadata {
|
||||
return documentProcessingMetadata.safeParse(metadata).success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard for NewMentionMetadata
|
||||
*/
|
||||
export function isNewMentionMetadata(metadata: unknown): metadata is NewMentionMetadata {
|
||||
return newMentionMetadata.safeParse(metadata).success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe metadata parser - returns typed metadata or null
|
||||
*/
|
||||
export function parseInboxItemMetadata(
|
||||
type: InboxItemTypeEnum,
|
||||
metadata: unknown
|
||||
): ConnectorIndexingMetadata | DocumentProcessingMetadata | NewMentionMetadata | null {
|
||||
switch (type) {
|
||||
case "connector_indexing": {
|
||||
const result = connectorIndexingMetadata.safeParse(metadata);
|
||||
return result.success ? result.data : null;
|
||||
}
|
||||
case "document_processing": {
|
||||
const result = documentProcessingMetadata.safeParse(metadata);
|
||||
return result.success ? result.data : null;
|
||||
}
|
||||
case "new_mention": {
|
||||
const result = newMentionMetadata.safeParse(metadata);
|
||||
return result.success ? result.data : null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Inferred types
|
||||
// =============================================================================
|
||||
|
||||
export type InboxItemTypeEnum = z.infer<typeof inboxItemTypeEnum>;
|
||||
export type InboxItemStatusEnum = z.infer<typeof inboxItemStatusEnum>;
|
||||
export type DocumentProcessingStageEnum = z.infer<typeof documentProcessingStageEnum>;
|
||||
export type BaseInboxItemMetadata = z.infer<typeof baseInboxItemMetadata>;
|
||||
export type ConnectorIndexingMetadata = z.infer<typeof connectorIndexingMetadata>;
|
||||
export type DocumentProcessingMetadata = z.infer<typeof documentProcessingMetadata>;
|
||||
export type NewMentionMetadata = z.infer<typeof newMentionMetadata>;
|
||||
export type InboxItemMetadata = z.infer<typeof inboxItemMetadata>;
|
||||
export type InboxItem = z.infer<typeof inboxItem>;
|
||||
export type ConnectorIndexingInboxItem = z.infer<typeof connectorIndexingInboxItem>;
|
||||
export type DocumentProcessingInboxItem = z.infer<typeof documentProcessingInboxItem>;
|
||||
export type NewMentionInboxItem = z.infer<typeof newMentionInboxItem>;
|
||||
|
||||
// API Request/Response types
|
||||
export type GetNotificationsRequest = z.infer<typeof getNotificationsRequest>;
|
||||
export type GetNotificationsResponse = z.infer<typeof getNotificationsResponse>;
|
||||
export type MarkNotificationReadRequest = z.infer<typeof markNotificationReadRequest>;
|
||||
export type MarkNotificationReadResponse = z.infer<typeof markNotificationReadResponse>;
|
||||
export type MarkAllNotificationsReadResponse = z.infer<typeof markAllNotificationsReadResponse>;
|
||||
export type GetUnreadCountRequest = z.infer<typeof getUnreadCountRequest>;
|
||||
export type GetUnreadCountResponse = z.infer<typeof getUnreadCountResponse>;
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
import { z } from "zod";
|
||||
import { searchSourceConnectorTypeEnum } from "./connector.types";
|
||||
import { documentTypeEnum } from "./document.types";
|
||||
|
||||
/**
|
||||
* Notification type enum - matches backend notification types
|
||||
*/
|
||||
export const notificationTypeEnum = z.enum([
|
||||
"connector_indexing",
|
||||
"document_processing",
|
||||
"new_mention",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Notification status enum - used in metadata
|
||||
*/
|
||||
export const notificationStatusEnum = z.enum(["in_progress", "completed", "failed"]);
|
||||
|
||||
/**
|
||||
* Document processing stage enum
|
||||
*/
|
||||
export const documentProcessingStageEnum = z.enum([
|
||||
"queued",
|
||||
"parsing",
|
||||
"chunking",
|
||||
"embedding",
|
||||
"storing",
|
||||
"completed",
|
||||
"failed",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Base metadata schema shared across notification types
|
||||
*/
|
||||
export const baseNotificationMetadata = z.object({
|
||||
operation_id: z.string().optional(),
|
||||
status: notificationStatusEnum.optional(),
|
||||
started_at: z.string().optional(),
|
||||
completed_at: z.string().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Connector indexing metadata schema
|
||||
*/
|
||||
export const connectorIndexingMetadata = baseNotificationMetadata.extend({
|
||||
connector_id: z.number(),
|
||||
connector_name: z.string(),
|
||||
connector_type: searchSourceConnectorTypeEnum,
|
||||
start_date: z.string().nullable().optional(),
|
||||
end_date: z.string().nullable().optional(),
|
||||
indexed_count: z.number(),
|
||||
total_count: z.number().optional(),
|
||||
progress_percent: z.number().optional(),
|
||||
error_message: z.string().nullable().optional(),
|
||||
// Google Drive specific fields
|
||||
folder_count: z.number().optional(),
|
||||
file_count: z.number().optional(),
|
||||
folder_names: z.array(z.string()).optional(),
|
||||
file_names: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Document processing metadata schema
|
||||
*/
|
||||
export const documentProcessingMetadata = baseNotificationMetadata.extend({
|
||||
document_type: documentTypeEnum,
|
||||
document_name: z.string(),
|
||||
processing_stage: documentProcessingStageEnum,
|
||||
file_size: z.number().optional(),
|
||||
chunks_count: z.number().optional(),
|
||||
document_id: z.number().optional(),
|
||||
error_message: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* New mention metadata schema
|
||||
*/
|
||||
export const newMentionMetadata = z.object({
|
||||
mention_id: z.number(),
|
||||
comment_id: z.number(),
|
||||
message_id: z.number(),
|
||||
thread_id: z.number(),
|
||||
thread_title: z.string(),
|
||||
author_id: z.string(),
|
||||
author_name: z.string(),
|
||||
author_avatar_url: z.string().nullable().optional(),
|
||||
author_email: z.string().optional(),
|
||||
content_preview: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Union of all notification metadata types
|
||||
* Use this when the notification type is unknown
|
||||
*/
|
||||
export const notificationMetadata = z.union([
|
||||
connectorIndexingMetadata,
|
||||
documentProcessingMetadata,
|
||||
newMentionMetadata,
|
||||
baseNotificationMetadata,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Main notification schema
|
||||
*/
|
||||
export const notification = z.object({
|
||||
id: z.number(),
|
||||
user_id: z.string(),
|
||||
search_space_id: z.number().nullable(),
|
||||
type: notificationTypeEnum,
|
||||
title: z.string(),
|
||||
message: z.string(),
|
||||
read: z.boolean(),
|
||||
metadata: z.record(z.string(), z.unknown()),
|
||||
created_at: z.string(),
|
||||
updated_at: z.string().nullable(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Typed notification schemas for specific notification types
|
||||
*/
|
||||
export const connectorIndexingNotification = notification.extend({
|
||||
type: z.literal("connector_indexing"),
|
||||
metadata: connectorIndexingMetadata,
|
||||
});
|
||||
|
||||
export const documentProcessingNotification = notification.extend({
|
||||
type: z.literal("document_processing"),
|
||||
metadata: documentProcessingMetadata,
|
||||
});
|
||||
|
||||
export const newMentionNotification = notification.extend({
|
||||
type: z.literal("new_mention"),
|
||||
metadata: newMentionMetadata,
|
||||
});
|
||||
|
||||
// Inferred types
|
||||
export type NotificationTypeEnum = z.infer<typeof notificationTypeEnum>;
|
||||
export type NotificationStatusEnum = z.infer<typeof notificationStatusEnum>;
|
||||
export type DocumentProcessingStageEnum = z.infer<typeof documentProcessingStageEnum>;
|
||||
export type BaseNotificationMetadata = z.infer<typeof baseNotificationMetadata>;
|
||||
export type ConnectorIndexingMetadata = z.infer<typeof connectorIndexingMetadata>;
|
||||
export type DocumentProcessingMetadata = z.infer<typeof documentProcessingMetadata>;
|
||||
export type NewMentionMetadata = z.infer<typeof newMentionMetadata>;
|
||||
export type NotificationMetadata = z.infer<typeof notificationMetadata>;
|
||||
export type Notification = z.infer<typeof notification>;
|
||||
export type ConnectorIndexingNotification = z.infer<typeof connectorIndexingNotification>;
|
||||
export type DocumentProcessingNotification = z.infer<typeof documentProcessingNotification>;
|
||||
export type NewMentionNotification = z.infer<typeof newMentionNotification>;
|
||||
Loading…
Add table
Add a link
Reference in a new issue