using System.Text.Json.Serialization;
namespace ClawdDotNet.Core.Backup;
/// Wie mit Zugangsdaten in der Sicherung verfahren wird.
public enum SecretMode
{
///
/// Zugangsdaten werden entfernt. Die Sicherung ist gefahrlos ablegbar, die
/// Wiederherstellung aber unvollständig — Schlüssel und Passwörter müssen
/// danach neu eingetragen werden.
///
Exclude,
///
/// Zugangsdaten werden mit einer Passphrase geschützt. Nur so überstehen sie
/// einen Rechner- oder Benutzerwechsel.
///
Passphrase,
///
/// Die ganze Sicherung wird mit dem Lizenzschlüssel verschlüsselt
/// (), die Zugangsdaten reisen mit.
///
/// Der Weg, den der Instanzmanager nimmt. Er übersteht einen Maschinenwechsel,
/// ohne dass eine Passphrase gespeichert oder eingetippt werden müsste — der
/// Lizenzschlüssel ist ohnehin da. Deshalb darf auch die tägliche Sicherung jetzt
/// Zugangsdaten enthalten.
///
License
}
public sealed record BackupOptions
{
public SecretMode Secrets { get; init; } = SecretMode.Exclude;
/// Erforderlich bei .
public string? Passphrase { get; init; }
/// Erforderlich bei .
public string? LicenseKey { get; init; }
/// Protokolle sind groß und selten nötig.
public bool IncludeLogs { get; init; }
/// Chatverläufe gehören zum Arbeitsstand, können aber umfangreich sein.
public bool IncludeChatHistory { get; init; } = true;
}
public sealed record RestoreOptions
{
public string? Passphrase { get; init; }
///
/// Für verschlüsselte Sicherungen: der Lizenzschlüssel der Installation, von der sie
/// stammt. Passt er nicht, kommt .
///
public string? LicenseKey { get; init; }
/// Nur prüfen und berichten, nichts schreiben.
public bool DryRun { get; init; }
/// Vorhandene Dateien im Ziel überschreiben.
public bool Overwrite { get; init; }
}
public sealed record BackupEntry(
[property: JsonPropertyName("path")] string Path,
[property: JsonPropertyName("size")] long Size,
[property: JsonPropertyName("sha256")] string Sha256);
public sealed record BackupManifest
{
/// Erlaubt es späteren Fassungen, ältere Sicherungen zu erkennen.
[JsonPropertyName("formatVersion")]
public int FormatVersion { get; init; } = 1;
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; init; }
[JsonPropertyName("instanceId")]
public string InstanceId { get; init; } = "";
[JsonPropertyName("instanceName")]
public string InstanceName { get; init; } = "";
[JsonPropertyName("secrets")]
public string Secrets { get; init; } = nameof(SecretMode.Exclude);
/// Wie viele Zugangsdaten enthalten bzw. entfernt wurden.
[JsonPropertyName("secretCount")]
public int SecretCount { get; init; }
[JsonPropertyName("files")]
public List Files { get; init; } = new();
///
/// Enthält die Sicherung Zugangsdaten, die beim Zurückspielen auf den Schlüssel der
/// Zielmaschine umgeschlüsselt werden müssen?
///
[JsonIgnore]
public bool HasSecrets => Secrets is nameof(SecretMode.Passphrase) or nameof(SecretMode.License);
}
public sealed record BackupResult(string ZipPath, BackupManifest Manifest, long SizeBytes);
public sealed record RestoreResult(
IReadOnlyList Written,
IReadOnlyList Skipped,
IReadOnlyList WouldOverwrite)
{
public bool HasConflicts => WouldOverwrite.Count > 0;
}
/// Nicht versiegelt: ist ein Sonderfall davon.
public class BackupException(string message, Exception? inner = null)
: Exception(message, inner);