versioning.go ergaenzt Restore (stellt eine fruehere Revision ueber denselben CheckOut/CheckIn-Mechanismus als NEUE Revision wieder her, kein separater Codepfad) und GetRevisionContent (beliebige, nicht nur die aktuelle Revision). Revision.CreatedBy ergaenzt fuer Autor-Anzeige. internal/versioningapi: Liste/Content/Restore als HTTP-Endpunkte. OwnerChecker ist eine minimale, echte PermissionChecker-Implementierung (Dokument- oder Revisions-Ersteller) - keine zentrale RBAC-Anbindung fuer dieses Modul vorhanden (VER-01/VER-05-Praezedenzfall), der Aufrufvertrag ist aber so geschnitten, dass eine spaetere echte Rollenpruefung diesen Handler nicht aendern muss. web/dms-browser: Versionsliste (Autor/Zeitpunkt/Kommentar, Download- und Wiederherstellen-Aktion je Zeile), nutzt dieselbe bei DOC-10 gegen 10.000 Zeilen bewiesene Virtualisierungs-Logik. Pruefungen: 1. Wiederherstellung veraendert Historie nicht - alle felder der alten revisionen unveraendert, wiederhergestellter inhalt real entschluesselt und verglichen 2. 100 revisionen bleiben uebersichtlich - dieselbe bei doc-10 bewiesene virtualisierung, weit unterhalb des bewiesenen 10.000er-bereichs 3. berechtigung wird JE revision geprueft - nicht-ersteller sieht accessible:false und bekommt 403, ersteller kann zugreifen (200) Regressionsfrei: go test ./... -p 1 alle pakete PASS, 22/22 vitest-tests. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
54 lines
1.9 KiB
TypeScript
54 lines
1.9 KiB
TypeScript
// Duenner Client fuer VER-02s Backend-Voraussetzung
|
|
// (dms/internal/versioningapi) — enthaelt keine eigene Versions-/
|
|
// Berechtigungslogik.
|
|
|
|
function apiBase(): string {
|
|
const base = process.env.NEXT_PUBLIC_VERSIONING_API_URL;
|
|
if (!base) {
|
|
throw new Error("NEXT_PUBLIC_VERSIONING_API_URL ist nicht gesetzt (Umgebungsvariable erforderlich)");
|
|
}
|
|
return base;
|
|
}
|
|
|
|
function caller(): string {
|
|
const c = process.env.NEXT_PUBLIC_USER_ID;
|
|
if (!c) {
|
|
throw new Error("NEXT_PUBLIC_USER_ID ist nicht gesetzt (Umgebungsvariable erforderlich)");
|
|
}
|
|
return c;
|
|
}
|
|
|
|
export interface RevisionDTO {
|
|
id: string;
|
|
revision_number: number;
|
|
size_bytes: number;
|
|
mime_type: string;
|
|
comment: string | null;
|
|
created_by: string;
|
|
created_at: string;
|
|
accessible: boolean;
|
|
}
|
|
|
|
export function fetchRevisions(documentID: string): Promise<RevisionDTO[]> {
|
|
return fetch(`${apiBase()}/documents/${encodeURIComponent(documentID)}/revisions?caller=${encodeURIComponent(caller())}`).then((res) => {
|
|
if (!res.ok) throw new Error(`Anfrage fehlgeschlagen (${res.status})`);
|
|
return res.json();
|
|
});
|
|
}
|
|
|
|
export function revisionContentUrl(documentID: string, revisionID: string): string {
|
|
return `${apiBase()}/documents/${encodeURIComponent(documentID)}/revisions/${encodeURIComponent(revisionID)}/content?caller=${encodeURIComponent(caller())}`;
|
|
}
|
|
|
|
export async function restoreRevision(documentID: string, revisionID: string): Promise<RevisionDTO> {
|
|
const res = await fetch(
|
|
`${apiBase()}/documents/${encodeURIComponent(documentID)}/revisions/${encodeURIComponent(revisionID)}/restore?caller=${encodeURIComponent(caller())}`,
|
|
{ method: "POST" }
|
|
);
|
|
if (!res.ok) {
|
|
if (res.status === 403) throw new Error("Zugriff verweigert: keine Berechtigung für diese Revision.");
|
|
throw new Error(`Wiederherstellung fehlgeschlagen (${res.status})`);
|
|
}
|
|
return res.json();
|
|
}
|