It was never used. The repository lives on a self-hosted Gitea, which Vercel's git integration cannot connect to at all — so the documented route amounted to "mirror to GitHub first", and nobody did. vercel.json is gone, and with it the branch in next.config.ts that switched off `output: "standalone"` when the VERCEL variable was present. That branch was the only functional trace; everything else was documentation and comments describing a second deployment path that did not exist. DEPLOYMENT.md loses its "two supported ways" framing and the whole Vercel section — about fifty lines. Several statements next to it were stale for a different reason and are corrected in the same pass: the outbound-firewall table still listed Supabase's pooler (the database is a container now, nothing leaves the server), the prerequisites still demanded an existing Supabase project, and the .env table still asked for a pooler connection string instead of the two new passwords. The nightly job is described as what it is — a container in docker-compose.yml — rather than as a replacement for Vercel Cron. Migrations keep their references: two comments from July mention Vercel Cron, and they describe what was true when they were written. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
30 lines
1.4 KiB
TypeScript
30 lines
1.4 KiB
TypeScript
import { NextResponse, type NextRequest } from "next/server";
|
|
import { asSystem } from "@/lib/db";
|
|
import { callFunction } from "@/lib/db/rpc";
|
|
|
|
// Applies effective-dated changes (Versetzung/Beförderung/Karenz/Reorg/Daten
|
|
// ändern with a future "Wirksam ab" date) once their date has arrived — see
|
|
// apply_due_pending_changes() in supabase/migrations.
|
|
//
|
|
// Gerufen wird das vom `cron`-Dienst aus docker-compose.yml, täglich um 03:00.
|
|
// Nicht im Namen einer HR-Person: es gibt keine angemeldete Sitzung, deshalb
|
|
// weist sich der Aufruf mit einem gemeinsamen Geheimnis aus (CRON_SECRET).
|
|
export async function GET(request: NextRequest) {
|
|
const authHeader = request.headers.get("authorization");
|
|
if (!process.env.CRON_SECRET || authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
|
|
return NextResponse.json({ error: "Nicht autorisiert." }, { status: 401 });
|
|
}
|
|
|
|
// Kein privilegierter Zugang mehr: derselbe Datenbankbenutzer ohne
|
|
// BYPASSRLS wie überall. apply_due_pending_changes ist SECURITY DEFINER
|
|
// und prüft selbst, was sie tut — der Dienstschlüssel, der RLS aushebelte,
|
|
// ist damit entfallen.
|
|
try {
|
|
const applied = await asSystem((tx) => callFunction(tx, "apply_due_pending_changes"));
|
|
return NextResponse.json({ applied });
|
|
} catch (err) {
|
|
console.error("apply_due_pending_changes failed:", err);
|
|
return NextResponse.json({ error: "Interner Fehler." }, { status: 500 });
|
|
}
|
|
}
|