feat: Actions system — scheduled mutations on external services

Full-stack implementation of provider-scoped Actions with extensible
executor architecture. First action type: Immich auto_organize (sort
assets into albums by person, CLIP search, date range, favorites).

Core:
- ActionTypeDefinition registry + ActionExecutor ABC with execute/validate/dry-run
- ImmichActionExecutor with multi-album support and client-side filtering
- ImmichClient write methods: add/remove assets, create album, paginated search

Server:
- Action, ActionRule, ActionExecution DB models
- Full CRUD API + manual execute + dry-run + execution history endpoints
- APScheduler integration (interval + cron) for automated execution
- Action type discovery API + provider people endpoint

Frontend:
- Actions page with CRUD, execute/dry-run buttons, inline rule editor
- RuleEditor: person/album MultiEntitySelect pickers, criteria config
- ExecutionHistory: expandable per-rule result details
- MultiEntitySelect reusable component (searchable multi-pick palette)
- Notification tracker album picker migrated to MultiEntitySelect
- Fixed MdiIcon race condition (icons missing after cache-clearing reload)
This commit is contained in:
2026-03-23 16:59:20 +03:00
parent 0fde3c6b3d
commit 6a559bfcd2
26 changed files with 2888 additions and 25 deletions
+5
View File
@@ -18,6 +18,7 @@ import type {
CommandConfig,
CommandTemplateConfig,
CommandTracker,
Action,
} from '$lib/types';
/** Service providers — used by Dashboard, Trackers, Command Trackers, Providers page. */
@@ -53,6 +54,9 @@ export const commandTemplateConfigsCache = createEntityCache<CommandTemplateConf
/** Command trackers — used by Command Trackers page. */
export const commandTrackersCache = createEntityCache<CommandTracker>('/command-trackers');
/** Actions — used by Actions page. */
export const actionsCache = createEntityCache<Action>('/actions');
/** Provider capabilities — used by Template Configs, Command Configs. */
export const capabilitiesCache = (() => {
let data = $state<Record<string, any>>({});
@@ -85,6 +89,7 @@ export const allCaches = {
command_configs: commandConfigsCache,
command_template_configs: commandTemplateConfigsCache,
command_trackers: commandTrackersCache,
actions: actionsCache,
} as const;
/**