feat(crm): route crm search through meilisearch
This commit is contained in:
@@ -14,5 +14,6 @@ type SearchRepoInterface interface {
|
||||
SearchConversations(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Conversation, int64, error)
|
||||
SearchMessages(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Message, int64, error)
|
||||
SearchContacts(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Contact, int64, error)
|
||||
SearchCompanies(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Company, int64, error)
|
||||
SearchArticles(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Article, int64, error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,27 @@ func (s *SearchService) GlobalSearch(ctx context.Context, accountID uint, query
|
||||
}
|
||||
}
|
||||
|
||||
// Search companies
|
||||
if filter.ShouldSearchType(ResultTypeCompany) {
|
||||
companies, companyCount, err := s.searchRepo.SearchCompanies(ctx, accountID, query, filter)
|
||||
if err != nil {
|
||||
applogger.L().Warnf("search companies error: %v", err)
|
||||
} else {
|
||||
byType["company"] = companyCount
|
||||
totalCount += companyCount
|
||||
for _, company := range companies {
|
||||
allResults = append(allResults, SearchResult{
|
||||
Type: ResultTypeCompany,
|
||||
ID: company.ID,
|
||||
AccountID: company.AccountID,
|
||||
Snippet: company.Name,
|
||||
Score: 1,
|
||||
Data: company,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search articles (Knowledge Base)
|
||||
if filter.ShouldSearchType(ResultTypeArticle) {
|
||||
articles, articleCount, err := s.searchRepo.SearchArticles(ctx, accountID, query, filter)
|
||||
@@ -235,6 +256,30 @@ func (s *SearchService) SearchContacts(ctx context.Context, accountID uint, quer
|
||||
return results, total, nil
|
||||
}
|
||||
|
||||
// SearchCompanies performs a filtered company search.
|
||||
func (s *SearchService) SearchCompanies(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]SearchResult, int64, error) {
|
||||
if s.engine != nil {
|
||||
return s.searchWithEngineForType(ctx, accountID, query, filter, ResultTypeCompany)
|
||||
}
|
||||
companies, total, err := s.searchRepo.SearchCompanies(ctx, accountID, query, filter)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("search companies: %w", err)
|
||||
}
|
||||
|
||||
results := make([]SearchResult, len(companies))
|
||||
for i, company := range companies {
|
||||
results[i] = SearchResult{
|
||||
Type: ResultTypeCompany,
|
||||
ID: company.ID,
|
||||
AccountID: company.AccountID,
|
||||
Snippet: company.Name,
|
||||
Score: 1,
|
||||
Data: company,
|
||||
}
|
||||
}
|
||||
return results, total, nil
|
||||
}
|
||||
|
||||
// SearchArticles performs a filtered knowledge base article search.
|
||||
// Convenience method for article-only search with full filter support.
|
||||
func (s *SearchService) SearchArticles(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]SearchResult, int64, error) {
|
||||
|
||||
@@ -15,20 +15,24 @@ import (
|
||||
// mockSearchRepo implements SearchRepoInterface for testing.
|
||||
type mockSearchRepo struct {
|
||||
conversations []model.Conversation
|
||||
convCount int64
|
||||
convErr error
|
||||
convCount int64
|
||||
convErr error
|
||||
|
||||
messages []model.Message
|
||||
msgCount int64
|
||||
msgErr error
|
||||
messages []model.Message
|
||||
msgCount int64
|
||||
msgErr error
|
||||
|
||||
contacts []model.Contact
|
||||
contactCount int64
|
||||
contactErr error
|
||||
|
||||
articles []model.Article
|
||||
articleCount int64
|
||||
articleErr error
|
||||
companies []model.Company
|
||||
companyCount int64
|
||||
companyErr error
|
||||
|
||||
articles []model.Article
|
||||
articleCount int64
|
||||
articleErr error
|
||||
}
|
||||
|
||||
func (m *mockSearchRepo) SearchConversations(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Conversation, int64, error) {
|
||||
@@ -43,6 +47,10 @@ func (m *mockSearchRepo) SearchContacts(ctx context.Context, accountID uint, que
|
||||
return m.contacts, m.contactCount, m.contactErr
|
||||
}
|
||||
|
||||
func (m *mockSearchRepo) SearchCompanies(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Company, int64, error) {
|
||||
return m.companies, m.companyCount, m.companyErr
|
||||
}
|
||||
|
||||
func (m *mockSearchRepo) SearchArticles(ctx context.Context, accountID uint, query string, filter *SearchFilter) ([]model.Article, int64, error) {
|
||||
return m.articles, m.articleCount, m.articleErr
|
||||
}
|
||||
@@ -75,6 +83,15 @@ func makeContact(id uint, accountID uint, name string, email string, phone strin
|
||||
}
|
||||
}
|
||||
|
||||
func makeCompany(id uint, accountID uint, name string, domain string) model.Company {
|
||||
return model.Company{
|
||||
AccountID: accountID,
|
||||
ID: id,
|
||||
Name: name,
|
||||
Domain: domain,
|
||||
}
|
||||
}
|
||||
|
||||
func makeArticle(id uint, accountID uint, title string, description string, content string, status string) model.Article {
|
||||
return model.Article{
|
||||
Base: model.Base{ID: id},
|
||||
@@ -277,6 +294,21 @@ func TestSearchContacts_ConvenienceMethod(t *testing.T) {
|
||||
assert.Equal(t, ResultTypeContact, results[0].Type)
|
||||
}
|
||||
|
||||
func TestSearchCompanies_ConvenienceMethod(t *testing.T) {
|
||||
repo := &mockSearchRepo{}
|
||||
repo.companies = []model.Company{makeCompany(7, 1, "Acme", "acme.example")}
|
||||
repo.companyCount = 1
|
||||
|
||||
svc := NewSearchService(repo)
|
||||
filter := &SearchFilter{Page: 1, PerPage: 25}
|
||||
|
||||
results, total, err := svc.SearchCompanies(context.Background(), 1, "acme", filter)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(1), total)
|
||||
assert.Len(t, results, 1)
|
||||
assert.Equal(t, ResultTypeCompany, results[0].Type)
|
||||
}
|
||||
|
||||
func TestSearchArticles_ConvenienceMethod(t *testing.T) {
|
||||
repo := &mockSearchRepo{}
|
||||
repo.articles = []model.Article{makeArticle(1, 1, "FAQ", "Common questions", "Details here", "published")}
|
||||
@@ -555,4 +587,4 @@ func TestSortResultsByScore_StableOrder(t *testing.T) {
|
||||
assert.Equal(t, uint(1), results[0].ID)
|
||||
assert.Equal(t, uint(2), results[1].ID)
|
||||
assert.Equal(t, uint(3), results[2].ID)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user