refactor: Remove deprecated create_connector_indexed_notification method and add notification types

- Removed the deprecated create_connector_indexed_notification method from NotificationService.
- Introduced new notification types and schemas in notification.types.ts to standardize notification handling.
- Updated useNotifications hook to utilize the new notification type definitions.
This commit is contained in:
Anish Sarkar 2026-01-13 17:21:00 +05:30
parent e38e6d90e0
commit 59a8ef5d64
5 changed files with 115 additions and 60 deletions

View file

@ -505,49 +505,3 @@ class NotificationService:
},
)
@staticmethod
async def create_connector_indexed_notification(
session: AsyncSession,
user_id: UUID,
connector_name: str,
connector_type: str,
status: str,
search_space_id: int,
indexed_count: int | None = None,
) -> Notification:
"""
Create notification when connector indexing completes.
DEPRECATED: Use NotificationService.connector_indexing methods instead.
Args:
session: Database session
user_id: User to notify
connector_name: Name of the connector
connector_type: Type of connector
status: Indexing status ('SUCCESS', 'FAILED')
search_space_id: Search space ID
indexed_count: Number of items indexed (optional)
Returns:
Notification: The created notification
"""
status_lower = status.lower()
title = f"Connector indexed: {connector_name}"
message = f'Your connector "{connector_name}" has finished indexing ({status_lower}).'
if indexed_count is not None:
message += f" {indexed_count} items indexed."
return await NotificationService.create_notification(
session=session,
user_id=user_id,
notification_type="connector_indexed",
title=title,
message=message,
search_space_id=search_space_id,
notification_metadata={
"connector_name": connector_name,
"connector_type": connector_type,
"status": status,
"indexed_count": indexed_count,
},
)

View file

@ -1,4 +1,5 @@
export enum EnumConnectorName {
SERPER_API = "SERPER_API",
TAVILY_API = "TAVILY_API",
SEARXNG_API = "SEARXNG_API",
LINKUP_API = "LINKUP_API",

View file

@ -6,9 +6,11 @@ export const documentTypeEnum = z.enum([
"CRAWLED_URL",
"FILE",
"SLACK_CONNECTOR",
"TEAMS_CONNECTOR",
"NOTION_CONNECTOR",
"YOUTUBE_VIDEO",
"GITHUB_CONNECTOR",
"LINEAR_CONNECTOR",
"DISCORD_CONNECTOR",
"JIRA_CONNECTOR",
"CONFLUENCE_CONNECTOR",
@ -19,9 +21,9 @@ export const documentTypeEnum = z.enum([
"AIRTABLE_CONNECTOR",
"LUMA_CONNECTOR",
"ELASTICSEARCH_CONNECTOR",
"LINEAR_CONNECTOR",
"NOTE",
"BOOKSTACK_CONNECTOR",
"CIRCLEBACK",
"NOTE",
]);
export const document = z.object({

View file

@ -0,0 +1,108 @@
import { z } from "zod";
import { searchSourceConnectorTypeEnum } from "./connector.types";
/**
* Notification type enum - matches backend notification types
*/
export const notificationTypeEnum = z.enum([
"connector_indexing",
"document_processed",
]);
/**
* Notification status enum - used in metadata
*/
export const notificationStatusEnum = z.enum([
"in_progress",
"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 processed metadata schema
*/
export const documentProcessedMetadata = baseNotificationMetadata.extend({
document_id: z.number(),
status: z.string(),
});
/**
* Union of all notification metadata types
* Use this when the notification type is unknown
*/
export const notificationMetadata = z.union([
connectorIndexingMetadata,
documentProcessedMetadata,
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 documentProcessedNotification = notification.extend({
type: z.literal("document_processed"),
metadata: documentProcessedMetadata,
});
// Inferred types
export type NotificationTypeEnum = z.infer<typeof notificationTypeEnum>;
export type NotificationStatusEnum = z.infer<typeof notificationStatusEnum>;
export type BaseNotificationMetadata = z.infer<typeof baseNotificationMetadata>;
export type ConnectorIndexingMetadata = z.infer<typeof connectorIndexingMetadata>;
export type DocumentProcessedMetadata = z.infer<typeof documentProcessedMetadata>;
export type NotificationMetadata = z.infer<typeof notificationMetadata>;
export type Notification = z.infer<typeof notification>;
export type ConnectorIndexingNotification = z.infer<typeof connectorIndexingNotification>;
export type DocumentProcessedNotification = z.infer<typeof documentProcessedNotification>;

View file

@ -2,19 +2,9 @@
import { useEffect, useState, useCallback, useRef } from 'react'
import { initElectric, isElectricInitialized, type ElectricClient, type SyncHandle } from '@/lib/electric/client'
import type { Notification } from '@/contracts/types/notification.types'
export interface Notification {
id: number
user_id: string
search_space_id: number | null
type: string
title: string
message: string
read: boolean
metadata: Record<string, unknown>
created_at: string
updated_at: string | null
}
export type { Notification } from '@/contracts/types/notification.types'
export function useNotifications(userId: string | null) {
const [electric, setElectric] = useState<ElectricClient | null>(null)