back up on publish, which is when this site actually changes
A nightly backup of a site that only changes when somebody publishes spends most of its life copying a database identical to yesterday's, and misses the one moment worth capturing. So "On publish" joins the schedules, and goes first. Stored in the same column as a cron expression because it answers the same question — WHEN — and a second column would mean every read had to decide which of the two was authoritative. It creates no cron job and no catch-up tick. A missed run is a run whose TIME passed while the machine was down; an event has no time, so there is nothing to have missed, and a catch-up here would take a backup every fifteen minutes of a site nobody had touched. `backupAfterPublish()` does nothing unless this is the configured trigger, so the publish path can call it unconditionally and never has to know what the backup settings say. It swallows failures for the same reason the timer does: a backup that could not be taken must not present as a publish that failed, when the thing the person asked for worked. Nothing calls it yet — there is no publish in this plugin, because the sections that would do the publishing are not built. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+26
-9
@@ -42,8 +42,18 @@ type Settings = {
|
||||
recent: Backup[];
|
||||
};
|
||||
|
||||
/** Every schedule anybody has actually wanted, and their expressions. */
|
||||
/** The sentinel the API stores for "not on a clock". Kept in step with `ON_PUBLISH` in api/backups.ts. */
|
||||
const ON_PUBLISH = 'on-publish';
|
||||
|
||||
/**
|
||||
* When to back up.
|
||||
*
|
||||
* "On publish" is first because it is the right answer for a site that only changes when somebody
|
||||
* changes it: a nightly backup spends most of its life copying a database identical to yesterday's,
|
||||
* and misses the one moment worth capturing.
|
||||
*/
|
||||
const CHOICES = [
|
||||
{ label: 'On publish', cron: ON_PUBLISH },
|
||||
{ label: 'Hourly', cron: '0 * * * *' },
|
||||
// Midnight, 6am, noon and 6pm — anchored to the clock rather than to whenever this was saved.
|
||||
{ label: 'Every 6 hours', cron: '0 */6 * * *' },
|
||||
@@ -266,14 +276,21 @@ export const BackupsRow = ({ prodName, devName }: { prodName: string; devName: s
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
{/* The expression stays visible and editable. The buttons write into it; they do not hide it. */}
|
||||
<Input
|
||||
value={cron}
|
||||
onChange={(event) => setCron(event.target.value)}
|
||||
className="w-full font-mono text-xs"
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
/>
|
||||
{/* The expression stays visible and editable for a SCHEDULE. "On publish" is not one, so the
|
||||
box would be a field with nothing to put in it. */}
|
||||
{cron === ON_PUBLISH ? (
|
||||
<p className="text-xs text-muted-foreground/70">
|
||||
A backup is taken every time the site is published, and at no other time.
|
||||
</p>
|
||||
) : (
|
||||
<Input
|
||||
value={cron}
|
||||
onChange={(event) => setCron(event.target.value)}
|
||||
className="w-full font-mono text-xs"
|
||||
autoComplete="off"
|
||||
spellCheck={false}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
|
||||
Reference in New Issue
Block a user