feat(admin): Abgleich einstellbar und Schalter je Projekt
Adminbereich, Abschnitt "Automatischer Abgleich": - ein- und ausschalten - Abstand von 15 Minuten bis taeglich - Projekte je Durchlauf - fertige und archivierte auslassen - Zustand auf einen Blick: verknuepfte Projekte, letzter und naechster Durchlauf, Kurzbericht des letzten Laufs - Knopf "Jetzt abgleichen" fuer einen sofortigen Durchlauf Der Endpunkt POST /api/admin/sync/run dient zugleich als Einstieg fuer einen externen Zeitgeber, falls jemand lieber von aussen taktet als den eingebauten Automatismus zu nutzen. Im Projektdialog laesst sich ein einzelnes Projekt vom Abgleich ausnehmen - nuetzlich bei einem Repo, dessen Token staendig Fehler wirft. Manuell synchronisieren geht unabhaengig davon immer. Die Zahl der in Frage kommenden Projekte wird ueber alle Konten gezaehlt: der Abgleich ist ein Serverauftrag, keine Dateneinsicht. Ein Administrator sieht dadurch weiterhin keine fremden Projekte. Nachgewiesen: Durchlauf 1 aktualisiert das echte Repo und meldet das kaputte als Fehlschlag, Durchlauf 2 stellt das kaputte zurueck, das ausgenommene Projekt bleibt in beiden unberuehrt. Der Zeitplan loeste eigenstaendig aus. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { requireAdminApi } from "@/lib/auth/guard";
|
||||
import { LIMITS, rateLimit } from "@/lib/security/rateLimit";
|
||||
import { clientIp, jsonError, tooManyRequests } from "@/lib/security/request";
|
||||
import { isAutoSyncRunning, runAutoSyncPass } from "@/lib/sync/scheduler";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
/**
|
||||
* Stoesst einen Abgleich sofort an – unabhaengig vom Zeitplan.
|
||||
*
|
||||
* Dient zwei Zwecken: dem Knopf "Jetzt abgleichen" im Adminbereich und
|
||||
* einem externen Zeitgeber, falls jemand lieber von aussen taktet als den
|
||||
* eingebauten Automatismus zu nutzen.
|
||||
*/
|
||||
export async function POST(request: Request) {
|
||||
const auth = await requireAdminApi();
|
||||
if (!auth.ok) return auth.response;
|
||||
|
||||
const limited = rateLimit(
|
||||
`sync-run:${clientIp(request)}`,
|
||||
LIMITS.outbound.limit,
|
||||
LIMITS.outbound.windowMs,
|
||||
);
|
||||
if (!limited.ok) return tooManyRequests(limited.retryAfter);
|
||||
|
||||
if (isAutoSyncRunning()) {
|
||||
return jsonError("Es laeuft bereits ein Abgleich.", 409);
|
||||
}
|
||||
|
||||
const report = await runAutoSyncPass("manuell");
|
||||
if (!report) {
|
||||
return jsonError("Es laeuft bereits ein Abgleich.", 409);
|
||||
}
|
||||
|
||||
return NextResponse.json({ report });
|
||||
}
|
||||
Reference in New Issue
Block a user