package sqlite import ( "context" "database/sql" "time" "switchboard-core/store" ) // PresenceStore manages user_presence table. type PresenceStore struct{} func NewPresenceStore() *PresenceStore { return &PresenceStore{} } func (s *PresenceStore) Heartbeat(ctx context.Context, userID string) error { _, err := DB.ExecContext(ctx, ` INSERT INTO user_presence (user_id, last_seen, status) VALUES (?, datetime('now'), 'online') ON CONFLICT (user_id) DO UPDATE SET last_seen = datetime('now'), status = 'online' `, userID) return err } func (s *PresenceStore) GetLastSeen(ctx context.Context, userID string) (*time.Time, error) { var lastSeen time.Time err := DB.QueryRowContext(ctx, `SELECT last_seen FROM user_presence WHERE user_id = ?`, userID).Scan(st(&lastSeen)) if err == sql.ErrNoRows { return nil, nil } if err != nil { return nil, err } return &lastSeen, nil } func (s *PresenceStore) GetStatuses(ctx context.Context, userIDs []string, threshold time.Time) (map[string]string, error) { result := make(map[string]string, len(userIDs)) for _, id := range userIDs { var lastSeen time.Time err := DB.QueryRowContext(ctx, `SELECT last_seen FROM user_presence WHERE user_id = ?`, id).Scan(st(&lastSeen)) if err != nil || lastSeen.Before(threshold) { result[id] = "offline" } else { result[id] = "online" } } return result, nil } // Ensure PresenceStore satisfies the interface at compile time. var _ store.PresenceStore = (*PresenceStore)(nil)