feat(search): scope message recency
This commit is contained in:
@@ -33,6 +33,7 @@ type RepoSearchFilter struct {
|
||||
Private *bool
|
||||
EnforceInboxAccess bool
|
||||
AccessibleInboxIDs []uint
|
||||
MessageCreatedAfter *time.Time
|
||||
DateFrom *time.Time
|
||||
DateTo *time.Time
|
||||
SortBy string
|
||||
@@ -107,6 +108,7 @@ func searchFilterToRepo(f *search.SearchFilter) *RepoSearchFilter {
|
||||
Private: f.Private,
|
||||
EnforceInboxAccess: f.EnforceInboxAccess,
|
||||
AccessibleInboxIDs: append([]uint(nil), f.AccessibleInboxIDs...),
|
||||
MessageCreatedAfter: f.MessageCreatedAfter,
|
||||
DateFrom: f.DateFrom,
|
||||
DateTo: f.DateTo,
|
||||
SortBy: f.SortBy,
|
||||
@@ -207,6 +209,7 @@ func (r *SearchRepo) searchMessagesInternal(ctx context.Context, accountID uint,
|
||||
var total int64
|
||||
|
||||
q := r.db.WithContext(ctx).Model(&model.Message{}).Where("account_id = ?", accountID)
|
||||
q = applyMessageRecentBase(q, filter)
|
||||
|
||||
// Text search on message content — ILIKE or pg_trgm fuzzy match
|
||||
if query != "" {
|
||||
@@ -515,6 +518,13 @@ func applySearchInboxAccess(q *gorm.DB, filter *RepoSearchFilter) *gorm.DB {
|
||||
return q.Where("inbox_id IN ?", filter.AccessibleInboxIDs)
|
||||
}
|
||||
|
||||
func applyMessageRecentBase(q *gorm.DB, filter *RepoSearchFilter) *gorm.DB {
|
||||
if filter == nil || filter.MessageCreatedAfter == nil {
|
||||
return q
|
||||
}
|
||||
return q.Where("created_at >= ?", *filter.MessageCreatedAfter)
|
||||
}
|
||||
|
||||
func searchInboxIDAllowed(filter *RepoSearchFilter, inboxID uint) bool {
|
||||
if filter == nil || !filter.EnforceInboxAccess {
|
||||
return true
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -245,6 +246,27 @@ func TestSearchRepo_SearchMessages_InaccessibleInboxParamFallsBackToAccessibleBa
|
||||
assert.Equal(t, visibleMsg.ID, results[0].ID)
|
||||
}
|
||||
|
||||
func TestSearchRepo_SearchMessages_MessageBaseExcludesOldMessages(t *testing.T) {
|
||||
db := setupTestDB(t)
|
||||
repo := NewSearchRepo(db)
|
||||
|
||||
account := createTestAccountForSearch(t, db)
|
||||
conv := createTestConversationForSearch(t, db, account.ID, "open", "")
|
||||
cutoff := time.Date(2026, 3, 7, 12, 0, 0, 0, time.UTC)
|
||||
recentMsg := createTestMessageForSearch(t, db, account.ID, conv.ID, "recent message", "incoming")
|
||||
require.NoError(t, db.Model(recentMsg).Update("created_at", cutoff.Add(time.Hour)).Error)
|
||||
oldMsg := createTestMessageForSearch(t, db, account.ID, conv.ID, "old message", "incoming")
|
||||
require.NoError(t, db.Model(oldMsg).Update("created_at", cutoff.Add(-time.Hour)).Error)
|
||||
|
||||
filter := &search.SearchFilter{Page: 1, PerPage: 25, MessageCreatedAfter: &cutoff}
|
||||
results, total, err := repo.SearchMessages(context.Background(), account.ID, "", filter)
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(1), total)
|
||||
require.Len(t, results, 1)
|
||||
assert.Equal(t, recentMsg.ID, results[0].ID)
|
||||
}
|
||||
|
||||
// ========== SearchConversations DB tests (PG only for ILIKE) ==========
|
||||
|
||||
func TestSearchRepo_SearchConversations_EmptyQuery(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user