package fleet import ( "database/sql" "github.com/google/uuid" ) func (s *Store) InsertSeerEvent(hostID, eventType, payload string) error { _, err := s.db.Exec(` INSERT INTO seer_events (id, host_id, event_type, payload_json) VALUES (?, ?, ?, ?) `, uuid.NewString(), nullString(hostID), eventType, payload) return err } func (s *Store) ListSeerEvents(limit int) ([]SeerEvent, error) { if limit <= 0 { limit = 50 } rows, err := s.db.Query(` SELECT id, host_id, event_type, payload_json, created_at FROM seer_events ORDER BY created_at DESC LIMIT ? `, limit) if err != nil { return nil, err } defer rows.Close() var events []SeerEvent for rows.Next() { var e SeerEvent var hostID sql.NullString if err := rows.Scan(&e.ID, &hostID, &e.EventType, &e.PayloadJSON, &e.CreatedAt); err != nil { return nil, err } if hostID.Valid { e.HostID = hostID.String } events = append(events, e) } return events, rows.Err() } // SeerEvent is a court/LOTL timeline entry. type SeerEvent struct { ID string `json:"id"` HostID string `json:"host_id,omitempty"` EventType string `json:"event_type"` PayloadJSON string `json:"payload_json"` CreatedAt string `json:"created_at"` } // ListSeerEventsSince returns events newer than the given SQLite timestamp string (exclusive). func (s *Store) ListSeerEventsSince(since string, limit int) ([]SeerEvent, error) { if limit <= 0 { limit = 50 } var rows interface { Close() error Next() bool Scan(dest ...any) error Err() error } var err error if since == "" { rows, err = s.db.Query(` SELECT id, host_id, event_type, payload_json, created_at FROM seer_events ORDER BY created_at ASC LIMIT ?`, limit) } else { rows, err = s.db.Query(` SELECT id, host_id, event_type, payload_json, created_at FROM seer_events WHERE created_at > ? ORDER BY created_at ASC LIMIT ?`, since, limit) } if err != nil { return nil, err } defer rows.Close() var events []SeerEvent for rows.Next() { var e SeerEvent var hostID sql.NullString if err := rows.Scan(&e.ID, &hostID, &e.EventType, &e.PayloadJSON, &e.CreatedAt); err != nil { return nil, err } if hostID.Valid { e.HostID = hostID.String } events = append(events, e) } return events, rows.Err() } func nullString(s string) sql.NullString { if s == "" { return sql.NullString{} } return sql.NullString{String: s, Valid: true} }