mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-09 13:35:12 +09:00
An extension with something worth backing up had to hand-roll it — no policy, no cron mirror, no run history, no retention, no offsite copy, no verification, no restore, and no place in the Protection panel. A registered kind inherits every one of those, because everything downstream of the target_type switches is already generic: the run lifecycle, retention (count, age, incremental-chain ancestry), the API blueprint, and the panel itself, which threads target_type through without ever switching on its value. No migration: target_type is an unconstrained String, and the allowed set lived purely in a Python tuple. A kind supplies resolve() and execute(), plus an optional restore(). Four switches had to learn about the registry, and the order matters in three of them: - validate_target_type is the keystone — every policy route funnels through it, so accepting a registered kind opens the whole blueprint at once. - _resolve_target and _execute_backup check the registry BEFORE their core branches, because both end in an application fallthrough that swallows any unrecognised type. - run_restore_job likewise. This is the sharp one: without it a plugin's archive would be unpacked over an app directory by core's else-branch. A kind that didn't implement restore is refused at request time with a reason, rather than queueing a job that takes the policy lock and runs a safety backup before failing. The registry normalises what plugins hand back — target_type is forced rather than defaulted, so a kind cannot describe itself as an 'application' and be restored as one; execute() must return (path, size, meta) with a real path; and the metadata retention and the panel read is filled in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>