What the module does before core deletes a user (before_user_delete/1,
spec §5.7). Core calls it outside the delete's transaction, whether or not the
module is enabled, and a failure here never stops the delete.
Known gap (MVP): core runs this hook before the transaction that deletes the user. If that delete then fails, the user stays, but their attachment files are already gone from Storage for good. The fix — unlink here and delete the files from a job once the user row is gone — needs a core hook after the delete, or a job; it is not built.
- Attachment files. Every Storage file of the user's attachments is
deleted completely (
Storage.delete_file_completely/1) — only if it lies in the module's hidden library (PhoenixKitAgent.Library) and nothing but this user's attachments refers to it. Anything else (a file in Media, a file another row points at) is only unlinked from the attachment and left alone. Without this the files would stay behind, with personal data, owned by nobody (phoenix_kit_files.user_uuidis set toNULLwith the user). - The user's folder in the module's library: files still in it that nothing refers to are deleted the same way, then the folder is removed (a file that is kept moves to the library root).
- The user's uuid leaves
notify_user_uuidsof other users' settings and theagent_limit_watcherssetting.
The user's rows in the module's tables are deleted with the user row by the
database (ON DELETE CASCADE).
"Refers to" means a row of any table whose foreign key points at the file, found in the database catalogue, so a module that links files later is covered too. Storage's own rows of the file (its instances, its system children) do not count; a folder link, a derived copy or a folder cover does. A reference without a foreign key cannot be seen; the hidden library is not offered by any picker, which is what keeps such references from existing.
Steps 1-3 run only when the module's tables are there: the version marker
is read in the schema the module's tables live in (config :phoenix_kit, prefix:). When it reads 0 while the module's library exists, the cleanup
is skipped with a warning (no user data in it). Failures are logged as
their class only — never a file name or a value.
Summary
Functions
Runs the cleanup for user_uuid. Always :ok; failures are logged.
Functions
@spec run(String.t()) :: :ok
Runs the cleanup for user_uuid. Always :ok; failures are logged.