# `PhoenixKitAgent.UserDeletion`
[🔗](https://github.com/BeamLabEU/phoenix_kit_agent/blob/v0.1.0/lib/phoenix_kit_agent/user_deletion.ex#L1)

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.

  1. **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_uuid` is
     set to `NULL` with the user).
  2. **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).
  3. The user's uuid leaves `notify_user_uuids` of other users' settings and
     the `agent_limit_watchers` setting.

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.

# `run`

```elixir
@spec run(String.t()) :: :ok
```

Runs the cleanup for `user_uuid`. Always `:ok`; failures are logged.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
