Enhance API routing and testing for user endpoints
Publish telemt-api gateway Docker image / test (push) Successful in 24s
Publish telemt-api gateway Docker image / build-and-push (push) Successful in 1m52s

- Updated the reverse proxy to redirect `GET` requests for `/api/{alias}/users` to `/v1/stats/users`, ensuring compatibility with Telemt builds that handle these requests differently.
- Added tests to verify that `GET` and `HEAD` requests to `/api/{alias}/users` are correctly rewritten, while `POST` requests and user-specific retrievals remain unchanged.
- Improved documentation in GATEWAY_RUN.md to clarify the behavior of the API routing and the importance of using the correct base URL.
This commit is contained in:
Denozordec
2026-03-30 11:18:36 +07:00
parent d69849e5e2
commit 368473de59
4 changed files with 102 additions and 9 deletions
+18 -7
View File
@@ -47,8 +47,9 @@
fleet = f.data ?? null;
uniqueIps = u.data ?? null;
// Как бейдж «OK» в таблице: только health + system/info (без x.ok — в JSON поле ok опционально).
const aliases = (fleet?.servers ?? [])
.filter((x) => x.alias && x.ok && x.health_ok && x.system_info_ok)
.filter((x) => x.alias && x.health_ok && x.system_info_ok)
.map((x) => x.alias as string);
const next: typeof nodeStats = {};
const concurrency = 4;
@@ -61,8 +62,8 @@
const d = st.data;
next[alias] = {
ok: true,
bad: d.connections_bad_total,
total: d.connections_total
bad: numStat(d.connections_bad_total, 0),
total: numStat(d.connections_total, 0)
};
} catch (e) {
next[alias] = {
@@ -83,6 +84,16 @@
onMount(load);
/** Число из ответа Telemt (поле может отсутствовать или прийти строкой). */
function numStat(v: unknown, fallback = 0): number {
if (typeof v === 'number' && Number.isFinite(v)) return v;
if (typeof v === 'string' && v.trim() !== '') {
const n = Number(v);
if (Number.isFinite(n)) return n;
}
return fallback;
}
let totalBad = $derived.by(() => {
let n = 0;
for (const v of Object.values(nodeStats)) {
@@ -268,13 +279,13 @@
{#if srv.alias}
{@const st = nodeStats[srv.alias]}
{#if !st}
<span title="Нет ответа stats/summary для этой ноды"></span>
{:else if 'ok' in st && st.ok === false}
<span class="text-xs text-muted-foreground"></span>
<span class="text-xs text-muted-foreground" title={st.error}>—</span>
{:else if st && 'bad' in st && st.ok}
{st.bad ?? '—'}
{st.bad ?? 0}
{:else}
<span title="Неожиданное состояние stats"></span>
{/if}
{:else}