fix(integrations): отдавать bindings в ответе sync для VPS Tracker
Build and Push CFDM Docker Image / build-and-push (push) Successful in 1m50s
Build and Push CFDM Docker Image / create-release (push) Skipped
Build and Push CFDM Docker Image / update-wiki (push) Successful in 6s

Ручной sync работает через pull: VPS Tracker получает bindings в ответе и не зависит от обратного push. Уточнены сообщения об ошибках сети.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-01 00:36:04 +07:00
co-authored by Cursor
parent 60da2b9032
commit 19620c0803
2 changed files with 17 additions and 13 deletions
+13 -11
View File
@@ -3,7 +3,7 @@ import type { FastifyInstance } from "fastify";
import { vpsTrackerEventSchema } from "@cfdm/shared"; import { vpsTrackerEventSchema } from "@cfdm/shared";
import { getAppSettingsSecrets } from "@cfdm/db"; import { getAppSettingsSecrets } from "@cfdm/db";
import * as vpsTrackerEvents from "../services/vps-tracker-events.js"; import * as vpsTrackerEvents from "../services/vps-tracker-events.js";
import { syncAllToVpsTracker } from "../services/vps-tracker-sync.js"; import { buildAllSyncBindings } from "../services/vps-tracker-sync.js";
function verifyBearer(authHeader: string | undefined, expected: string): boolean { function verifyBearer(authHeader: string | undefined, expected: string): boolean {
if (!authHeader?.startsWith("Bearer ")) return false; if (!authHeader?.startsWith("Bearer ")) return false;
@@ -43,7 +43,11 @@ export async function integrationsVpsTrackerRoutes(app: FastifyInstance) {
return { ok: true, reconciled }; return { ok: true, reconciled };
}); });
/** Запрос полной синхронизации bindings → VPS Tracker (вызывает VPS Tracker). */ /**
* Полная синхронизация по запросу VPS Tracker (pull).
* Bindings возвращаются в ответе — клиент применяет их локально.
* Не требует доступности VPS Tracker URL из CFDM.
*/
app.post("/integrations/vps-tracker/sync", async (req, reply) => { app.post("/integrations/vps-tracker/sync", async (req, reply) => {
const secrets = getAppSettingsSecrets(app.db); const secrets = getAppSettingsSecrets(app.db);
const token = secrets.vpsTrackerIntegrationToken; const token = secrets.vpsTrackerIntegrationToken;
@@ -57,14 +61,12 @@ export async function integrationsVpsTrackerRoutes(app: FastifyInstance) {
return reply.status(401).send({ ok: false, error: "Unauthorized" }); return reply.status(401).send({ ok: false, error: "Unauthorized" });
} }
const result = await syncAllToVpsTracker(app.db); const bindings = buildAllSyncBindings(app.db);
if (!result.ok) { return {
return reply.status(502).send({ ok: true,
ok: false, count: bindings.length,
error: result.error ?? "Sync failed", bindings,
count: result.count, fullSync: true,
}); };
}
return { ok: true, count: result.count };
}); });
} }
+4 -2
View File
@@ -145,19 +145,21 @@ export async function syncAllToVpsTracker(db: Db): Promise<{
body: JSON.stringify({ bindings, fullSync: true }), body: JSON.stringify({ bindings, fullSync: true }),
}); });
if (!res.ok) { if (!res.ok) {
const detail = await res.text();
return { return {
ok: false, ok: false,
count: 0, count: 0,
error: `HTTP ${res.status}: ${await res.text()}`, error: `VPS Tracker ${baseUrl} ответил HTTP ${res.status}: ${detail}`,
}; };
} }
touchVpsTrackerSync(db); touchVpsTrackerSync(db);
return { ok: true, count: bindings.length }; return { ok: true, count: bindings.length };
} catch (err) { } catch (err) {
const raw = err instanceof Error ? err.message : "Ошибка сети";
return { return {
ok: false, ok: false,
count: 0, count: 0,
error: err instanceof Error ? err.message : "Ошибка сети", error: `Не удалось отправить данные в VPS Tracker (${baseUrl}): ${raw}`,
}; };
} }
} }