The one action shape PhoenixKit.Modules.Storage.Reorganizer understands.
A Source returns plain maps (so a module can build them without
compiling against this module — see Source's moduledoc). new!/1
validates the shape and fills defaults for anything the source left out;
the engine works with the normalized result from here on.
Summary
Functions
Validates a plain map from a Source, raising ArgumentError naming the
offending key on any problem, and fills defaults for keys the source
didn't set.
A :move action is a no-op when the folder it targets already sits at the
wanted parent_uuid with the wanted name (or an accepted "name (N)"
variant of it — matches the previous run's own suffix-on-collision output,
so re-running plan/2 doesn't propose renaming it back and forth). A nil
name means "keep the current name", so it always matches.
Types
@type on_conflict() :: :suffix | :report
@type op() :: :move | :trash | :report
@type t() :: %{ :source => String.t(), :kind => atom(), :label => String.t(), :op => op(), optional(:folder) => %PhoenixKit.Modules.Storage.Folder{ __meta__: term(), children: term(), color: term(), cover_file_uuid: term(), description: term(), files: term(), folder_links: term(), header_show_background: term(), header_show_creator: term(), header_show_date: term(), header_show_description: term(), header_show_file_count: term(), header_show_icon: term(), header_show_title: term(), header_size: term(), inserted_at: term(), logo_file_uuid: term(), name: term(), parent: term(), parent_uuid: term(), trashed_at: term(), updated_at: term(), user: term(), user_uuid: term(), uuid: term() } | nil, optional(:parent_uuid) => String.t() | nil, optional(:name) => String.t() | nil, optional(:counts) => {non_neg_integer(), non_neg_integer()} | nil, optional(:on_conflict) => on_conflict(), optional(:after_move) => (-> :ok | {:ok, term()} | {:error, term()}) | nil, optional(:reason) => String.t() | nil, optional(:outcome) => atom(), optional(:changes) => [:moved | :renamed | :restored], optional(:error) => term() }
Functions
Validates a plain map from a Source, raising ArgumentError naming the
offending key on any problem, and fills defaults for keys the source
didn't set.
A :move action is a no-op when the folder it targets already sits at the
wanted parent_uuid with the wanted name (or an accepted "name (N)"
variant of it — matches the previous run's own suffix-on-collision output,
so re-running plan/2 doesn't propose renaming it back and forth). A nil
name means "keep the current name", so it always matches.
An action carrying after_move is never a noop, even when the folder is
already in place: the folder position matching doesn't mean the pointer
back-fill it exists to run has happened — the engine still needs to apply
it (see PhoenixKit.Modules.Storage.Reorganizer's move path, which skips
update_folder but still runs after_move in that case).
A trashed folder is never a noop either, even when its parent/name already
match: restoring it is itself a change the engine must apply (outcome
:restored when nothing else about it changes).