2

Simplify the dashboard recent IP view

This commit is contained in:
2026-03-12 02:15:45 +01:00
parent 7bd3933215
commit a82421ba3f
8 changed files with 404 additions and 57 deletions

View File

@@ -475,6 +475,75 @@ func (s *Store) ListIPStates(ctx context.Context, limit int, stateFilter string)
return items, nil
}
func (s *Store) ListRecentIPRows(ctx context.Context, since time.Time, limit int) ([]model.RecentIPRow, error) {
if limit <= 0 {
limit = 200
}
rows, err := s.db.QueryContext(ctx, `
WITH recent AS (
SELECT client_ip, COUNT(*) AS event_count, MAX(occurred_at) AS last_seen_at
FROM events
WHERE occurred_at >= ?
GROUP BY client_ip
)
SELECT s.ip,
COALESCE((
SELECT e.source_name
FROM events e
WHERE e.client_ip = s.ip AND e.occurred_at >= ?
ORDER BY e.occurred_at DESC, e.id DESC
LIMIT 1
), s.last_source_name) AS source_name,
s.state,
recent.event_count,
recent.last_seen_at,
s.state_reason,
s.manual_override
FROM recent
JOIN ip_state s ON s.ip = recent.client_ip
ORDER BY recent.event_count DESC, recent.last_seen_at DESC, s.ip ASC
LIMIT ?`,
formatTime(since),
formatTime(since),
limit,
)
if err != nil {
return nil, fmt.Errorf("list recent ip rows: %w", err)
}
defer rows.Close()
items := make([]model.RecentIPRow, 0, limit)
for rows.Next() {
var item model.RecentIPRow
var state string
var lastSeenAt string
var manualOverride string
if err := rows.Scan(
&item.IP,
&item.SourceName,
&state,
&item.Events,
&lastSeenAt,
&item.Reason,
&manualOverride,
); err != nil {
return nil, fmt.Errorf("scan recent ip row: %w", err)
}
parsedLastSeenAt, err := parseTime(lastSeenAt)
if err != nil {
return nil, fmt.Errorf("parse recent ip row last_seen_at: %w", err)
}
item.State = model.IPStateStatus(state)
item.LastSeenAt = parsedLastSeenAt
item.ManualOverride = model.ManualOverride(manualOverride)
items = append(items, item)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate recent ip rows: %w", err)
}
return items, nil
}
func (s *Store) GetIPDetails(ctx context.Context, ip string, eventLimit, decisionLimit, actionLimit int) (model.IPDetails, error) {
state, _, err := s.GetIPState(ctx, ip)
if err != nil {