Files

133 lines
5.7 KiB
PHP

<?php
/**
* C-Relay-PG Admin — Per-Relay Backfill Progress.
*/
require_once __DIR__ . '/lib/helpers.php';
$pdo = db();
$page = current_page();
$per = cfg('relays_per_page', 50);
$offset = ($page - 1) * $per;
$filter = query_param('filter', 'all');
$pubkey = query_param('pubkey', '');
$where = [];
$params = [];
if ($filter === 'incomplete') {
$where[] = 'rp.complete = false';
} elseif ($filter === 'error') {
$where[] = "rp.last_status LIKE 'error%'";
} elseif ($filter === 'complete') {
$where[] = 'rp.complete = true';
}
if ($pubkey) {
$where[] = 'rp.author_pubkey = ?';
$params[] = $pubkey;
}
$where_sql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
$total = 0;
$relays = [];
try {
$stmt = $pdo->prepare("SELECT COUNT(*) FROM caching_backfill_relay_progress rp $where_sql");
$stmt->execute($params);
$total = intval($stmt->fetchColumn());
$sql = "
SELECT rp.author_pubkey, rp.relay_url, rp.until_cursor, rp.complete,
rp.events_fetched,
COALESCE(rp.consecutive_errors, 0) AS consecutive_errors,
rp.last_status, rp.updated_at,
e.content::json->>'name' AS name,
e.content::json->>'display_name' AS display_name
FROM caching_backfill_relay_progress rp
LEFT JOIN LATERAL (SELECT content FROM events WHERE pubkey = rp.author_pubkey AND kind = 0 ORDER BY created_at DESC LIMIT 1) e ON true
$where_sql
ORDER BY rp.complete ASC, COALESCE(rp.consecutive_errors, 0) DESC, rp.updated_at DESC
LIMIT $per OFFSET $offset
";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$relays = $stmt->fetchAll();
} catch (PDOException $ex) {}
function status_badge(string $status): string {
if ($status === 'eose') return '<span class="badge badge-success">eose</span>';
if ($status === 'timeout') return '<span class="badge badge-warning">timeout</span>';
if (str_starts_with($status, 'error')) return '<span class="badge badge-error">' . e($status) . '</span>';
if (str_starts_with($status, 'NOTICE')) return '<span class="badge badge-warning">' . e($status) . '</span>';
if (str_starts_with($status, 'CLOSED')) return '<span class="badge badge-warning">' . e($status) . '</span>';
if ($status === '') return '<span class="badge badge-muted">—</span>';
return '<span class="badge badge-muted">' . e($status) . '</span>';
}
admin_header('relays', 'C-Relay-PG Admin — Relay Progress');
?>
<div class="section">
<div class="section-header">PER-RELAY BACKFILL PROGRESS (<?= number_format($total) ?> total)</div>
<form class="filters" method="get">
<select name="filter" onchange="this.form.submit()">
<option value="all" <?= $filter==='all'?'selected':'' ?>>All</option>
<option value="incomplete" <?= $filter==='incomplete'?'selected':'' ?>>Incomplete only</option>
<option value="error" <?= $filter==='error'?'selected':'' ?>>Errors only</option>
<option value="complete" <?= $filter==='complete'?'selected':'' ?>>Complete only</option>
</select>
<?php if ($pubkey): ?>
<input type="hidden" name="pubkey" value="<?= e($pubkey) ?>">
<span style="font-size:10px;color:var(--muted-color)">Filtered by: <span class="pubkey"><?= e(trunc($pubkey, 16)) ?></span></span>
<a href="relays.php?filter=<?= e($filter) ?>" style="font-size:10px">Clear</a>
<?php endif; ?>
</form>
<div class="config-table-container">
<table class="config-table">
<thead>
<tr>
<th>Author</th>
<th>Relay URL</th>
<th>Complete</th>
<th>Events</th>
<th>Errors</th>
<th>Last Status</th>
<th>Updated</th>
</tr>
</thead>
<tbody>
<?php foreach ($relays as $r):
$name = $r['display_name'] ?: $r['name'];
$npub = hex_to_npub($r['author_pubkey']);
?>
<tr <?= intval($r['consecutive_errors']) >= 3 ? 'style="background:rgba(255,0,0,0.05)"' : '' ?>>
<td>
<?php if ($name): ?>
<strong><?= e($name) ?></strong>
<?php else: ?>
<span style="color:var(--muted-color);font-style:italic">unknown</span>
<?php endif; ?>
<br><a href="follows.php?search=<?= e($r['author_pubkey']) ?>" class="npub-link"><?= e(trunc($npub, 20)) ?></a>
</td>
<td><?= e($r['relay_url']) ?></td>
<td><?= $r['complete'] ? '<span class="badge badge-success">✓</span>' : '<span class="badge badge-warning">…</span>' ?></td>
<td><?= number_format(intval($r['events_fetched'])) ?></td>
<td><?= intval($r['consecutive_errors']) > 0
? '<span class="status-error">' . intval($r['consecutive_errors']) . '</span>'
: '0' ?></td>
<td><?= status_badge($r['last_status']) ?></td>
<td><?= time_ago(intval($r['updated_at'])) ?></td>
</tr>
<?php endforeach; ?>
<?php if (empty($relays)): ?>
<tr><td colspan="7" style="text-align:center;color:var(--muted-color);padding:20px">No relay progress rows found.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?= pagination($page, $per, $total, 'relays.php' . ($filter !== 'all' ? '?filter=' . e($filter) : '') . ($pubkey ? '&pubkey=' . e($pubkey) : '')) ?>
</div>
<?php admin_footer(); ?>