notifications

package
v1.37.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MaxNotifications is the maximum number of notifications to retain.
	MaxNotifications = 500
	// MaxNotificationAge is the maximum age of a notification before it is pruned.
	MaxNotificationAge = 7 * 24 * time.Hour
)
View Source
const (
	// DefaultCoalesceInterval is the default interval for flushing the coalescing buffer.
	DefaultCoalesceInterval = 500 * time.Millisecond
)

Variables

This section is empty.

Functions

func StartSubscriber

func StartSubscriber(ctx context.Context, bus *events.EventBus, store *NotificationHistoryStore)

StartSubscriber subscribes to the EventBus, filters for EventNotification events, converts them to NotificationRecords, coalesces rapid-fire events for the same (sessionID, notificationType) key within a 500ms window, and flushes them to the store. It stops when the context is canceled, flushing any remaining buffered records.

func StartSubscriberWithInterval

func StartSubscriberWithInterval(ctx context.Context, bus *events.EventBus, store Appender, interval time.Duration)

StartSubscriberWithInterval is like StartSubscriber but allows configuring the coalescing interval. This is primarily useful for tests that need shorter intervals.

Types

type Appender

type Appender interface {
	Append(record *NotificationRecord) error
}

Appender is the interface used by the subscriber to append records. This enables testing without a real NotificationHistoryStore.

type ListOptions

type ListOptions struct {
	Limit      int
	Offset     int
	TypeFilter *int32
	SessionID  string
	UnreadOnly bool
}

ListOptions controls filtering and pagination for List operations.

type NotificationHistoryStore

type NotificationHistoryStore struct {
	// contains filtered or unexported fields
}

NotificationHistoryStore persists notification records to a JSON file with in-memory caching for fast reads.

func NewNotificationHistoryStore

func NewNotificationHistoryStore(filePath string) (*NotificationHistoryStore, error)

NewNotificationHistoryStore creates a new store, loading existing data from disk. If the file does not exist or is corrupted, the store starts empty.

func (*NotificationHistoryStore) Append

Append adds a notification record, enforces retention limits, and persists to disk. If an unread record with the same (sessionID, notificationType) already exists, the existing record is updated in place (occurrence count incremented, metadata refreshed, moved to front) instead of inserting a new record. Per ADR-003, if the existing record is already read, a new unread record is created instead.

For APPROVAL_NEEDED notifications the record ID is also updated to the incoming approval UUID so that SetMetadata outcome-stamping (which looks up by record ID) continues to correlate with the most recent approval for this session.

func (*NotificationHistoryStore) AppendAutoApproved added in v1.35.0

func (s *NotificationHistoryStore) AppendAutoApproved(sessionID, sessionName, toolName, filePath, ruleID, ruleName, ruleSource, decision string) error

AppendAutoApproved writes a silent NOTIFICATION_TYPE_AUTO_APPROVED record directly to history without publishing to the event bus. The record is immediately marked as read so it never appears in the active notification feed — only in the auto-handled history view.

func (*NotificationHistoryStore) Clear

func (s *NotificationHistoryStore) Clear(before *time.Time) (int, error)

Clear removes notifications. If before is nil, clears all. Otherwise clears notifications created before the given time. Returns the number cleared.

func (*NotificationHistoryStore) GetUnreadCount

func (s *NotificationHistoryStore) GetUnreadCount() int

GetUnreadCount returns the number of unread notifications. After server-side deduplication (Task 1.2), each unread record represents a distinct (sessionID, notificationType) group, so this count reflects the number of deduplicated unread groups -- not raw event occurrences.

func (*NotificationHistoryStore) List

List returns a paginated, filtered slice of notification records and the total count.

func (*NotificationHistoryStore) MarkRead

func (s *NotificationHistoryStore) MarkRead(ids []string) (int, error)

MarkRead marks specific notifications as read. If ids is empty, marks all as read. Returns the number of records that were marked.

func (*NotificationHistoryStore) SetMetadata

func (s *NotificationHistoryStore) SetMetadata(id, key, value string) error

SetMetadata updates a single metadata key on the notification record with the given ID. A no-op (not an error) if the record does not exist, since the notification may have been pruned or the approval pre-dates history tracking.

type NotificationRecord

type NotificationRecord struct {
	ID               string            `json:"id"`
	SessionID        string            `json:"session_id"`
	SessionName      string            `json:"session_name"`
	NotificationType int32             `json:"notification_type"`
	Priority         int32             `json:"priority"`
	Title            string            `json:"title"`
	Message          string            `json:"message"`
	Metadata         map[string]string `json:"metadata,omitempty"`
	CreatedAt        time.Time         `json:"created_at"`
	IsRead           bool              `json:"is_read"`
	ReadAt           *time.Time        `json:"read_at,omitempty"`
	// OccurrenceCount tracks how many deduplicated occurrences this record represents.
	// A value of 0 (zero-value from old JSON) should be treated as 1 by consumers.
	OccurrenceCount int `json:"occurrence_count,omitempty"`
	// LastOccurredAt is the timestamp of the most recent occurrence. May differ from
	// CreatedAt which tracks the first occurrence.
	LastOccurredAt *time.Time `json:"last_occurred_at,omitempty"`
}

NotificationRecord is the persisted representation of a notification event.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL