mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 01:50:39 +09:00
feat(backups): tiered daily/weekly/monthly retention with UI controls
Replace single retentionDays with a three-tier BackupRetentionPolicy: - Daily: keep all backups (presets: 3, 7, 14 days; default 7) - Weekly: keep one per calendar week (presets: 1, 2, 4 weeks; default 4) - Monthly: keep one per calendar month (presets: 1, 3, 6 months; default 1) Pruning sorts backups newest-first and applies each tier's cutoff, keeping only the newest entry per ISO week/month bucket. The Instance Settings General page now shows three preset selectors (no icon, matches existing page design). Remove Database icon import.
This commit is contained in:
parent
cc44d309c0
commit
fcbae62baf
13 changed files with 243 additions and 79 deletions
|
|
@ -189,7 +189,7 @@ export type {
|
|||
InstanceExperimentalSettings,
|
||||
InstanceGeneralSettings,
|
||||
InstanceSettings,
|
||||
BackupRetentionDays,
|
||||
BackupRetentionPolicy,
|
||||
Agent,
|
||||
AgentAccessState,
|
||||
AgentChainOfCommandEntry,
|
||||
|
|
@ -371,8 +371,10 @@ export {
|
|||
} from "./types/feedback.js";
|
||||
|
||||
export {
|
||||
BACKUP_RETENTION_PRESETS,
|
||||
DEFAULT_BACKUP_RETENTION_DAYS,
|
||||
DAILY_RETENTION_PRESETS,
|
||||
WEEKLY_RETENTION_PRESETS,
|
||||
MONTHLY_RETENTION_PRESETS,
|
||||
DEFAULT_BACKUP_RETENTION,
|
||||
} from "./types/instance.js";
|
||||
|
||||
export {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ export type {
|
|||
FeedbackTraceBundleFile,
|
||||
FeedbackTraceBundle,
|
||||
} from "./feedback.js";
|
||||
export type { InstanceExperimentalSettings, InstanceGeneralSettings, InstanceSettings, BackupRetentionDays } from "./instance.js";
|
||||
export { BACKUP_RETENTION_PRESETS, DEFAULT_BACKUP_RETENTION_DAYS } from "./instance.js";
|
||||
export type { InstanceExperimentalSettings, InstanceGeneralSettings, InstanceSettings, BackupRetentionPolicy } from "./instance.js";
|
||||
export { DAILY_RETENTION_PRESETS, WEEKLY_RETENTION_PRESETS, MONTHLY_RETENTION_PRESETS, DEFAULT_BACKUP_RETENTION } from "./instance.js";
|
||||
export type {
|
||||
CompanySkillSourceType,
|
||||
CompanySkillTrustLevel,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
import type { FeedbackDataSharingPreference } from "./feedback.js";
|
||||
|
||||
export const BACKUP_RETENTION_PRESETS = [7, 14, 30] as const;
|
||||
export type BackupRetentionDays = (typeof BACKUP_RETENTION_PRESETS)[number];
|
||||
export const DEFAULT_BACKUP_RETENTION_DAYS: BackupRetentionDays = 7;
|
||||
export const DAILY_RETENTION_PRESETS = [3, 7, 14] as const;
|
||||
export const WEEKLY_RETENTION_PRESETS = [1, 2, 4] as const;
|
||||
export const MONTHLY_RETENTION_PRESETS = [1, 3, 6] as const;
|
||||
|
||||
export interface BackupRetentionPolicy {
|
||||
dailyDays: (typeof DAILY_RETENTION_PRESETS)[number];
|
||||
weeklyWeeks: (typeof WEEKLY_RETENTION_PRESETS)[number];
|
||||
monthlyMonths: (typeof MONTHLY_RETENTION_PRESETS)[number];
|
||||
}
|
||||
|
||||
export const DEFAULT_BACKUP_RETENTION: BackupRetentionPolicy = {
|
||||
dailyDays: 7,
|
||||
weeklyWeeks: 4,
|
||||
monthlyMonths: 1,
|
||||
};
|
||||
|
||||
export interface InstanceGeneralSettings {
|
||||
censorUsernameInLogs: boolean;
|
||||
keyboardShortcuts: boolean;
|
||||
feedbackDataSharingPreference: FeedbackDataSharingPreference;
|
||||
backupRetentionDays: BackupRetentionDays;
|
||||
backupRetention: BackupRetentionPolicy;
|
||||
}
|
||||
|
||||
export interface InstanceExperimentalSettings {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,25 @@
|
|||
import { z } from "zod";
|
||||
import { DEFAULT_FEEDBACK_DATA_SHARING_PREFERENCE } from "../types/feedback.js";
|
||||
import { BACKUP_RETENTION_PRESETS, DEFAULT_BACKUP_RETENTION_DAYS } from "../types/instance.js";
|
||||
import {
|
||||
DAILY_RETENTION_PRESETS,
|
||||
WEEKLY_RETENTION_PRESETS,
|
||||
MONTHLY_RETENTION_PRESETS,
|
||||
DEFAULT_BACKUP_RETENTION,
|
||||
} from "../types/instance.js";
|
||||
import { feedbackDataSharingPreferenceSchema } from "./feedback.js";
|
||||
|
||||
export const backupRetentionDaysSchema = z.number().refine(
|
||||
(v): v is (typeof BACKUP_RETENTION_PRESETS)[number] =>
|
||||
(BACKUP_RETENTION_PRESETS as readonly number[]).includes(v),
|
||||
{ message: `Must be one of: ${BACKUP_RETENTION_PRESETS.join(", ")}` },
|
||||
);
|
||||
function presetSchema<T extends readonly number[]>(presets: T, label: string) {
|
||||
return z.number().refine(
|
||||
(v): v is T[number] => (presets as readonly number[]).includes(v),
|
||||
{ message: `${label} must be one of: ${presets.join(", ")}` },
|
||||
);
|
||||
}
|
||||
|
||||
export const backupRetentionPolicySchema = z.object({
|
||||
dailyDays: presetSchema(DAILY_RETENTION_PRESETS, "dailyDays").default(DEFAULT_BACKUP_RETENTION.dailyDays),
|
||||
weeklyWeeks: presetSchema(WEEKLY_RETENTION_PRESETS, "weeklyWeeks").default(DEFAULT_BACKUP_RETENTION.weeklyWeeks),
|
||||
monthlyMonths: presetSchema(MONTHLY_RETENTION_PRESETS, "monthlyMonths").default(DEFAULT_BACKUP_RETENTION.monthlyMonths),
|
||||
});
|
||||
|
||||
export const instanceGeneralSettingsSchema = z.object({
|
||||
censorUsernameInLogs: z.boolean().default(false),
|
||||
|
|
@ -15,7 +27,7 @@ export const instanceGeneralSettingsSchema = z.object({
|
|||
feedbackDataSharingPreference: feedbackDataSharingPreferenceSchema.default(
|
||||
DEFAULT_FEEDBACK_DATA_SHARING_PREFERENCE,
|
||||
),
|
||||
backupRetentionDays: backupRetentionDaysSchema.default(DEFAULT_BACKUP_RETENTION_DAYS),
|
||||
backupRetention: backupRetentionPolicySchema.default(DEFAULT_BACKUP_RETENTION),
|
||||
}).strict();
|
||||
|
||||
export const patchInstanceGeneralSettingsSchema = instanceGeneralSettingsSchema.partial();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue