feat(search): add meilisearch engine foundation

This commit is contained in:
2026-06-04 19:56:29 +08:00
parent db0bd5b0f6
commit 3fc4859e20
13 changed files with 1515 additions and 289 deletions
+123 -113
View File
@@ -14,17 +14,17 @@ import (
"github.com/gochat/gochat/internal/campaign"
"github.com/gochat/gochat/internal/canned"
"github.com/gochat/gochat/internal/channel"
emailchannel "github.com/gochat/gochat/internal/channel/email"
facebookchannel "github.com/gochat/gochat/internal/channel/facebook"
googlechannel "github.com/gochat/gochat/internal/channel/google"
linechannel "github.com/gochat/gochat/internal/channel/line"
microsoftchannel "github.com/gochat/gochat/internal/channel/microsoft"
channelprovider "github.com/gochat/gochat/internal/channel/provider"
telegramchannel "github.com/gochat/gochat/internal/channel/telegram"
tiktokchannel "github.com/gochat/gochat/internal/channel/tiktok"
twiliochannel "github.com/gochat/gochat/internal/channel/twilio"
twitterchannel "github.com/gochat/gochat/internal/channel/twitter"
whatsappchannel "github.com/gochat/gochat/internal/channel/whatsapp"
tiktokchannel "github.com/gochat/gochat/internal/channel/tiktok"
linechannel "github.com/gochat/gochat/internal/channel/line"
twiliochannel "github.com/gochat/gochat/internal/channel/twilio"
emailchannel "github.com/gochat/gochat/internal/channel/email"
"github.com/gochat/gochat/internal/config"
"github.com/gochat/gochat/internal/database"
v1 "github.com/gochat/gochat/internal/handler/api/v1"
@@ -621,7 +621,17 @@ func Bootstrap(env string) (*App, error) {
assignmentPolicyV2Service := service.NewAssignmentPolicyV2Service(assignmentPolicyV2Repo, assignmentPolicyInboxRepo)
// Search service (M14 — Global Search + Advanced Filter)
searchService := search.NewSearchService(searchRepo)
searchEngine, err := search.NewSearchEngine(search.EngineConfig{
Engine: cfg.Search.Engine,
Host: cfg.Search.Host,
APIKey: cfg.Search.APIKey,
IndexPrefix: cfg.Search.IndexPrefix,
TimeoutSeconds: cfg.Search.TimeoutSeconds,
}, searchRepo)
if err != nil {
return nil, fmt.Errorf("search engine init failed: %w", err)
}
searchService := search.NewSearchServiceWithEngine(searchEngine, searchRepo)
// Custom attribute definition + custom filter + custom attribute value services
customAttributeDefinitionService := service.NewCustomAttributeDefinitionService(customAttributeDefinitionRepo)
@@ -667,133 +677,133 @@ func Bootstrap(env string) (*App, error) {
contactMergeRepo := repository.NewContactMergeRepo(db)
contactMergeService := service.NewContactMergeService(contactMergeRepo, db)
handlers := &router.Handlers{
Auth: v1.NewAuthHandler(authService, oauthService),
MFA: v1.NewMFAHandler(mfaService),
SAML: v1.NewSAMLHandler(samlService, jwtService, refreshStore, ssoSessionStore, &cfg.SAML),
Account: v1.NewAccountHandler(accountService),
Contact: v1.NewContactHandler(contactService, contactInboxService, contactMergeService, contactNoteService),
Conversation: v1.NewConversationHandler(conversationService, messageService),
Inbox: v1.NewInboxHandler(inboxService),
InboxMember: v1.NewInboxMemberHandler(inboxMemberService),
WebWidget: v1.NewWebWidgetHandler(inboxService),
WebWidgetTheme: v1.NewWebWidgetThemeHandler(widgetService, inboxService),
WebWidgetPreChat: v1.NewWebWidgetPreChatHandler(widgetService, inboxService),
WebWidgetOffline: v1.NewWebWidgetOfflineHandler(widgetService, inboxService),
InstagramChannel: v1.NewInstagramChannelHandler(igService, igProvider, inboxService, igRepo),
FacebookChannel: v1.NewFacebookChannelHandler(fbChannelService, fbProvider, inboxService, fbChannelRepo),
TwitterChannel: v1.NewTwitterChannelHandler(twService, twProvider, inboxService, twRepo),
MicrosoftChannel: v1.NewMicrosoftChannelHandler(msService, msProvider, inboxService, msRepo),
GoogleChannel: v1.NewGoogleChannelHandler(goService, goProvider, inboxService, goRepo),
TikTokChannel: v1.NewTikTokChannelHandler(ttChannelSvc, ttProvider, inboxService, ttChannelRepo),
LINEChannel: v1.NewLINEChannelHandler(lineChannelSvc, lineProvider, inboxService, lineChannelRepo),
TwilioSMSChannel: v1.NewTwilioChannelHandler(twilioSMSSvc, inboxService, twilioSMSRepo),
EmailChannel: v1.NewEmailChannelHandler(emailChannelSvc, inboxService, emailChannelRepo),
EmailWebhook: emailWebhookHandler,
Message: v1.NewMessageHandler(messageService),
Profile: v1.NewProfileHandler(profileService),
Notification: v1.NewNotificationHandler(notificationService),
PlatformApp: v1.NewPlatformAppHandler(platformAppService),
Team: v1.NewTeamHandler(teamService),
CaptainAssistant: v1.NewCaptainAssistantHandler(captainAssistantService),
CaptainDocument: v1.NewCaptainDocumentHandler(captainDocumentService),
CaptainScenario: v1.NewCaptainScenarioHandler(captainScenarioService),
CaptainCustomTool: v1.NewCaptainCustomToolHandler(captainCustomToolService),
Auth: v1.NewAuthHandler(authService, oauthService),
MFA: v1.NewMFAHandler(mfaService),
SAML: v1.NewSAMLHandler(samlService, jwtService, refreshStore, ssoSessionStore, &cfg.SAML),
Account: v1.NewAccountHandler(accountService),
Contact: v1.NewContactHandler(contactService, contactInboxService, contactMergeService, contactNoteService),
Conversation: v1.NewConversationHandler(conversationService, messageService),
Inbox: v1.NewInboxHandler(inboxService),
InboxMember: v1.NewInboxMemberHandler(inboxMemberService),
WebWidget: v1.NewWebWidgetHandler(inboxService),
WebWidgetTheme: v1.NewWebWidgetThemeHandler(widgetService, inboxService),
WebWidgetPreChat: v1.NewWebWidgetPreChatHandler(widgetService, inboxService),
WebWidgetOffline: v1.NewWebWidgetOfflineHandler(widgetService, inboxService),
InstagramChannel: v1.NewInstagramChannelHandler(igService, igProvider, inboxService, igRepo),
FacebookChannel: v1.NewFacebookChannelHandler(fbChannelService, fbProvider, inboxService, fbChannelRepo),
TwitterChannel: v1.NewTwitterChannelHandler(twService, twProvider, inboxService, twRepo),
MicrosoftChannel: v1.NewMicrosoftChannelHandler(msService, msProvider, inboxService, msRepo),
GoogleChannel: v1.NewGoogleChannelHandler(goService, goProvider, inboxService, goRepo),
TikTokChannel: v1.NewTikTokChannelHandler(ttChannelSvc, ttProvider, inboxService, ttChannelRepo),
LINEChannel: v1.NewLINEChannelHandler(lineChannelSvc, lineProvider, inboxService, lineChannelRepo),
TwilioSMSChannel: v1.NewTwilioChannelHandler(twilioSMSSvc, inboxService, twilioSMSRepo),
EmailChannel: v1.NewEmailChannelHandler(emailChannelSvc, inboxService, emailChannelRepo),
EmailWebhook: emailWebhookHandler,
Message: v1.NewMessageHandler(messageService),
Profile: v1.NewProfileHandler(profileService),
Notification: v1.NewNotificationHandler(notificationService),
PlatformApp: v1.NewPlatformAppHandler(platformAppService),
Team: v1.NewTeamHandler(teamService),
CaptainAssistant: v1.NewCaptainAssistantHandler(captainAssistantService),
CaptainDocument: v1.NewCaptainDocumentHandler(captainDocumentService),
CaptainScenario: v1.NewCaptainScenarioHandler(captainScenarioService),
CaptainCustomTool: v1.NewCaptainCustomToolHandler(captainCustomToolService),
CaptainTask: v1.NewCaptainTaskHandler(captainTaskService),
CaptainPreference: v1.NewCaptainPreferenceHandler(captainPreferenceService),
CaptainTaskExtended: v1.NewCaptainTaskExtendedHandler(captainTaskExtendedService),
CaptainAssistantResponse: v1.NewCaptainAssistantResponseHandler(captainAssistantResponseService),
CaptainBulkAction: v1.NewCaptainBulkActionHandler(captainBulkActionService),
Copilot: v1.NewCopilotHandler(copilotService),
Analytics: v1.NewAnalyticsHandler(analyticsService),
LiveReport: v1.NewLiveReportHandler(analyticsService),
DashboardApp: v1.NewDashboardAppHandler(dashboardAppService),
Portal: v1.NewPortalHandler(portalService),
Category: v1.NewCategoryHandler(categoryService),
Article: v1.NewArticleHandler(articleService),
Folder: v1.NewFolderHandler(folderService),
PortalMember: v1.NewPortalMemberHandler(portalMemberService),
AutomationRule: v1.NewAutomationRuleHandler(automationRuleService),
Macro: v1.NewMacroHandler(macroService),
CsatSurvey: v1.NewCsatSurveyHandler(csatSurveyService),
CannedResponse: v1.NewCannedResponseHandler(cannedResponseService),
PushSubscription: v1.NewPushSubscriptionHandler(pushSubscriptionService),
Copilot: v1.NewCopilotHandler(copilotService),
Analytics: v1.NewAnalyticsHandler(analyticsService),
LiveReport: v1.NewLiveReportHandler(analyticsService),
DashboardApp: v1.NewDashboardAppHandler(dashboardAppService),
Portal: v1.NewPortalHandler(portalService),
Category: v1.NewCategoryHandler(categoryService),
Article: v1.NewArticleHandler(articleService),
Folder: v1.NewFolderHandler(folderService),
PortalMember: v1.NewPortalMemberHandler(portalMemberService),
AutomationRule: v1.NewAutomationRuleHandler(automationRuleService),
Macro: v1.NewMacroHandler(macroService),
CsatSurvey: v1.NewCsatSurveyHandler(csatSurveyService),
CannedResponse: v1.NewCannedResponseHandler(cannedResponseService),
PushSubscription: v1.NewPushSubscriptionHandler(pushSubscriptionService),
NotificationSubscription: v1.NewNotificationSubscriptionHandler(notificationSubscriptionService),
WebhookSubscription: v1.NewWebhookSubscriptionHandler(webhookSubscriptionService),
TelegramWebhook: telegramWebhookHandler,
FacebookWebhook: facebookWebhookHandler,
WhatsAppWebhook: whatsappWebhookHandler,
TikTokWebhook: tiktokWebhookHandler,
LineWebhook: lineWebhookHandler,
TwilioWebhook: twilioWebhookHandler,
Label: v1.NewLabelHandler(tagService, labelService),
Campaign: v1.NewCampaignHandler(campaignService),
AssignmentPolicy: v1.NewAssignmentPolicyHandler(assignmentPolicyService),
SlaPolicy: v1.NewSlaPolicyHandler(slaPolicyService),
AssignmentPolicyV2: v1.NewAssignmentPolicyV2Handler(assignmentPolicyV2Service),
WebhookSubscription: v1.NewWebhookSubscriptionHandler(webhookSubscriptionService),
TelegramWebhook: telegramWebhookHandler,
FacebookWebhook: facebookWebhookHandler,
WhatsAppWebhook: whatsappWebhookHandler,
TikTokWebhook: tiktokWebhookHandler,
LineWebhook: lineWebhookHandler,
TwilioWebhook: twilioWebhookHandler,
Label: v1.NewLabelHandler(tagService, labelService),
Campaign: v1.NewCampaignHandler(campaignService),
AssignmentPolicy: v1.NewAssignmentPolicyHandler(assignmentPolicyService),
SlaPolicy: v1.NewSlaPolicyHandler(slaPolicyService),
AssignmentPolicyV2: v1.NewAssignmentPolicyV2Handler(assignmentPolicyV2Service),
// Enterprise: AuditLog, CustomRole, AgentCapacityPolicy, CsatMetrics handlers
Audit: v1.NewAuditHandler(auditService),
CustomRole: v1.NewCustomRoleHandler(customRoleService),
AgentCapacity: v1.NewAgentCapacityHandler(agentCapacityPolicyService),
CsatMetrics: v1.NewCsatMetricsHandler(csatMetricsService),
Search: v1.NewSearchHandler(searchService),
Widget: widgetHandler,
Audit: v1.NewAuditHandler(auditService),
CustomRole: v1.NewCustomRoleHandler(customRoleService),
AgentCapacity: v1.NewAgentCapacityHandler(agentCapacityPolicyService),
CsatMetrics: v1.NewCsatMetricsHandler(csatMetricsService),
Search: v1.NewSearchHandler(searchService),
Widget: widgetHandler,
// M13: SSO/SAML enterprise authentication handlers
AccountSamlSettings: v1.NewAccountSamlSettingsHandler(accountSamlSettingsRepo),
SSOSession: v1.NewSSOSessionHandler(ssoSessionStore),
// M13: LDAP/OIDC enterprise authentication handlers
LDAP: v1.NewLDAPHandler(ldapService, ssoMiddleware, jwtService, refreshStore, ssoSessionStore, &cfg.LDAP, db),
OIDC: v1.NewOIDCHandler(oidcService, ssoMiddleware, jwtService, refreshStore, &cfg.OIDC),
SSOMiddleware: ssoMiddleware,
LDAP: v1.NewLDAPHandler(ldapService, ssoMiddleware, jwtService, refreshStore, ssoSessionStore, &cfg.LDAP, db),
OIDC: v1.NewOIDCHandler(oidcService, ssoMiddleware, jwtService, refreshStore, &cfg.OIDC),
SSOMiddleware: ssoMiddleware,
// M12: AgentBot handlers (platform-level + account-level bots)
AgentBot: v1.NewAgentBotHandler(agentBotService),
InstallationConfig: v1.NewInstallationConfigHandler(installationConfigService),
WidgetTest: v1.NewWidgetTestHandler(widgetTestService),
AgentBotInbox: v1.NewAgentBotInboxHandler(agentBotInboxService),
AgentBot: v1.NewAgentBotHandler(agentBotService),
InstallationConfig: v1.NewInstallationConfigHandler(installationConfigService),
WidgetTest: v1.NewWidgetTestHandler(widgetTestService),
AgentBotInbox: v1.NewAgentBotInboxHandler(agentBotInboxService),
// P9: AgentBot rule engine + trigger config handlers
BotRule: v1.NewBotRuleHandler(botRuleService),
BotTriggerConfig: v1.NewBotTriggerConfigHandler(botTriggerConfigService),
BotRule: v1.NewBotRuleHandler(botRuleService),
BotTriggerConfig: v1.NewBotTriggerConfigHandler(botTriggerConfigService),
// M12: SSE streaming + conversation insight handlers
SSEStream: v1.NewSSEStreamHandler(copilotService, llmProvider),
SSEStream: v1.NewSSEStreamHandler(copilotService, llmProvider),
ConversationInsight: v1.NewConversationInsightHandler(conversationInsightService),
// M4 G3: ContactInbox filter handler (account-scope)
ContactInboxFilter: v1.NewContactInboxHandler(contactInboxService),
ContactInboxFilter: v1.NewContactInboxHandler(contactInboxService),
// Conversation participant + draft message handlers
ConversationParticipant: v1.NewConversationParticipantHandler(conversationParticipantService),
DraftMessage: v1.NewDraftMessageHandler(draftMessageService),
// G4: Companies module (CRUD + search + nested contacts/conversations/notes)
Company: v1.NewCompanyHandler(companyService),
Company: v1.NewCompanyHandler(companyService),
// Custom attributes + custom filters
CustomAttributeDefinition: v1.NewCustomAttributeDefinitionHandler(customAttributeDefinitionService),
CustomAttributeValue: v1.NewCustomAttributeValueHandler(customAttributeValueService),
CustomFilter: v1.NewCustomFilterHandler(customFilterService),
// G16: Third-party integration handlers (IntegrationHook CRUD + Slack/Shopify/Linear/Notion)
IntegrationHook: v1.NewIntegrationHookHandler(integrationHookService),
SlackIntegration: v1.NewSlackIntegrationHandler(slackIntegrationService),
ShopifyIntegration: v1.NewShopifyIntegrationHandler(shopifyIntegrationService),
LinearIntegration: v1.NewLinearIntegrationHandler(linearIntegrationService),
NotionIntegration: v1.NewNotionIntegrationHandler(notionIntegrationService),
PlatformUserSSO: v1.NewPlatformUserSSOHandler(),
IntegrationHook: v1.NewIntegrationHookHandler(integrationHookService),
SlackIntegration: v1.NewSlackIntegrationHandler(slackIntegrationService),
ShopifyIntegration: v1.NewShopifyIntegrationHandler(shopifyIntegrationService),
LinearIntegration: v1.NewLinearIntegrationHandler(linearIntegrationService),
NotionIntegration: v1.NewNotionIntegrationHandler(notionIntegrationService),
PlatformUserSSO: v1.NewPlatformUserSSOHandler(),
// Platform API AccessToken-authenticated handlers
PlatformUser: v1.NewPlatformUserHandler(platformUserService),
PlatformAccount: v1.NewPlatformAccountHandler(accountRepo, permissibleRepo, accountService),
PlatformAgentBot: v1.NewPlatformAgentBotHandler(agentBotRepo, permissibleRepo),
PlatformAccountUser: v1.NewPlatformAccountUserHandler(accountRepo, userRepo, permissibleRepo),
Upload: uploadHandler,
PlatformUser: v1.NewPlatformUserHandler(platformUserService),
PlatformAccount: v1.NewPlatformAccountHandler(accountRepo, permissibleRepo, accountService),
PlatformAgentBot: v1.NewPlatformAgentBotHandler(agentBotRepo, permissibleRepo),
PlatformAccountUser: v1.NewPlatformAccountUserHandler(accountRepo, userRepo, permissibleRepo),
Upload: uploadHandler,
// Lane B: AssignableAgent handler (find agents available for assignment)
AssignableAgent: v1.NewAssignableAgentHandler(assignableAgentService),
AgentBulk: v1.NewAgentBulkHandler(conversationService),
BulkAction: v1.NewBulkActionHandler(conversationService, contactService),
AssignableAgent: v1.NewAssignableAgentHandler(assignableAgentService),
AgentBulk: v1.NewAgentBulkHandler(conversationService),
BulkAction: v1.NewBulkActionHandler(conversationService, contactService),
// Lane C: CSAT template (singular per inbox) + Inbox limits
InboxCsatTemplate: v1.NewInboxCsatTemplateHandler(csatTemplateService),
InboxLimit: v1.NewInboxLimitHandler(inboxLimitService),
WorkingHour: v1.NewWorkingHourHandler(workingHourService),
InboxCsatTemplate: v1.NewInboxCsatTemplateHandler(csatTemplateService),
InboxLimit: v1.NewInboxLimitHandler(inboxLimitService),
WorkingHour: v1.NewWorkingHourHandler(workingHourService),
// Banner handler (Platform CRUD + account read-only)
Banner: v1.NewBannerHandler(bannerService),
Banner: v1.NewBannerHandler(bannerService),
// EmailChannelMigration handler (account-scoped create-only)
EmailChannelMigration: v1.NewEmailChannelMigrationHandler(emailChannelMigrationService),
// SummaryReport handler (read-only reporting resource — agent/team/inbox/label summaries)
SummaryReport: v1.NewSummaryReportHandler(summaryReportService),
}
}
_ = agentBotListener // M12: subscribed to message events via service calls
// Step 10: Setup Gin router + middleware chain
@@ -849,12 +859,12 @@ func Bootstrap(env string) (*App, error) {
applogger.L().Info("All dependencies wired successfully")
return &App{
config: cfg,
reloader: reloader,
db: db,
pubsub: ps,
engine: engine,
wsHub: wsHub,
config: cfg,
reloader: reloader,
db: db,
pubsub: ps,
engine: engine,
wsHub: wsHub,
notificationDeliverySvc: notificationDeliverySvc,
}, nil
}
@@ -868,10 +878,10 @@ type hubTypingAdapter struct {
func (a *hubTypingAdapter) SetTypingOn(ctx context.Context, accountID, conversationID uint, performer *wspkg.Performer) error {
msg := &wspkg.WSMessage{
Event: wspkg.EventConversationTypingOn,
Data: map[string]any{"conversation_id": conversationID},
AccountID: accountID,
Performer: performer,
Event: wspkg.EventConversationTypingOn,
Data: map[string]any{"conversation_id": conversationID},
AccountID: accountID,
Performer: performer,
}
data, _ := json.Marshal(msg)
a.hub.SendToAccount(accountID, data)
@@ -880,10 +890,10 @@ func (a *hubTypingAdapter) SetTypingOn(ctx context.Context, accountID, conversat
func (a *hubTypingAdapter) SetTypingOff(ctx context.Context, accountID, conversationID uint, performer *wspkg.Performer) error {
msg := &wspkg.WSMessage{
Event: wspkg.EventConversationTypingOff,
Data: map[string]any{"conversation_id": conversationID},
AccountID: accountID,
Performer: performer,
Event: wspkg.EventConversationTypingOff,
Data: map[string]any{"conversation_id": conversationID},
AccountID: accountID,
Performer: performer,
}
data, _ := json.Marshal(msg)
a.hub.SendToAccount(accountID, data)