Commit d1492007 authored by Steven's avatar Steven

fix(store): filter inbox notifications by message type at database level

Add MessageType filter to FindInbox to exclude legacy VERSION_UPDATE
notifications from inbox queries. This resolves the issue where users
saw notification counts but no items displayed, as VERSION_UPDATE
entries cannot be rendered in the new UserNotification API.

Changes:
- Add MessageType field to FindInbox struct for database-level filtering
- Implement JSON extraction filters in SQLite, MySQL, and PostgreSQL drivers
- Update ListUserNotifications to filter MEMO_COMMENT type at store level

This approach improves performance by filtering at the database rather
than in application code, reducing unnecessary data transfer for users
with many legacy inbox entries.

Fixes #5278

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
parent 17e116b9
......@@ -1583,8 +1583,11 @@ func (s *APIV1Service) ListUserNotifications(ctx context.Context, request *v1pb.
}
// Fetch inbox items from storage
// Filter at database level to only include MEMO_COMMENT notifications (ignore legacy VERSION_UPDATE entries)
memoCommentType := storepb.InboxMessage_MEMO_COMMENT
inboxes, err := s.Store.ListInboxes(ctx, &store.FindInbox{
ReceiverID: &userID,
ReceiverID: &userID,
MessageType: &memoCommentType,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list inboxes: %v", err)
......
......@@ -60,6 +60,11 @@ func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.I
if find.Status != nil {
where, args = append(where, "`status` = ?"), append(args, *find.Status)
}
if find.MessageType != nil {
// Filter by message type using JSON extraction
// Note: The type field in JSON is stored as string representation of the enum name
where, args = append(where, "JSON_EXTRACT(`message`, '$.type') = ?"), append(args, find.MessageType.String())
}
query := "SELECT `id`, UNIX_TIMESTAMP(`created_ts`), `sender_id`, `receiver_id`, `status`, `message` FROM `inbox` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC"
if find.Limit != nil {
......
......@@ -50,6 +50,11 @@ func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.I
if find.Status != nil {
where, args = append(where, "status = "+placeholder(len(args)+1)), append(args, *find.Status)
}
if find.MessageType != nil {
// Filter by message type using PostgreSQL JSON extraction
// Note: The type field in JSON is stored as string representation of the enum name
where, args = append(where, "message->>'type' = "+placeholder(len(args)+1)), append(args, find.MessageType.String())
}
query := "SELECT id, created_ts, sender_id, receiver_id, status, message FROM inbox WHERE " + strings.Join(where, " AND ") + " ORDER BY created_ts DESC"
if find.Limit != nil {
......
......@@ -52,6 +52,11 @@ func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.I
if find.Status != nil {
where, args = append(where, "`status` = ?"), append(args, *find.Status)
}
if find.MessageType != nil {
// Filter by message type using JSON extraction
// Note: The type field in JSON is stored as string representation of the enum name
where, args = append(where, "JSON_EXTRACT(`message`, '$.type') = ?"), append(args, find.MessageType.String())
}
query := "SELECT `id`, `created_ts`, `sender_id`, `receiver_id`, `status`, `message` FROM `inbox` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC"
if find.Limit != nil {
......
......@@ -39,10 +39,11 @@ type UpdateInbox struct {
// FindInbox specifies filter criteria for querying inbox items.
type FindInbox struct {
ID *int32
SenderID *int32
ReceiverID *int32
Status *InboxStatus
ID *int32
SenderID *int32
ReceiverID *int32
Status *InboxStatus
MessageType *storepb.InboxMessage_Type
// Pagination
Limit *int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment