feat(files): add Hosted Files admin page at /core/files/

- Search hosted files across all accounts (including disabled)
- Sortable columns, pagination, per-row delete, download, and SHA-256 copy
- Lazy-load file link records per row via /v3/action/hosted_file/{id}/links
- Fix delete to load links first, remove each via correct link_to_type/link_to_id_random,
  then hard-delete with method=delete and rm_orphan=true
- Remove Linked To and Group columns (moved Group/ForType to filter bar only)
- SHA-256 column now visible at lg breakpoint (was xl)
- Added /core/files nav link to /core layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-18 17:32:45 -04:00
parent fa7889bd80
commit 015a38fd14
4 changed files with 649 additions and 0 deletions

View File

@@ -370,6 +370,20 @@ These helper endpoints let the frontend request small server-side transformation
- Add `?background=true` to schedule the clip asynchronously — returns `202 Accepted` immediately; poll the `hosted_file` record for completion.
- Returns 400 on synchronous failure; 202 when scheduled successfully.
- **Get Links**
- Method: `GET`
- Path: `/v3/action/hosted_file/{hosted_file_id}/links`
- Auth: standard V3 headers
- Returns: array of `{ link_to_type, link_to_id, link_to_id_random }` for every record in `hosted_file_link`. Empty array if no links exist (file is an orphan).
- Use this to assess what objects are using a file before deleting it.
- **Delete**
- Method: `DELETE`
- Path: `/v3/action/hosted_file/{hosted_file_id}`
- Query params: `link_to_type`, `link_to_id` (random string), `method` (`hide` | `disable` | `delete`, default `hide`), `rm_orphan` (bool, default `false`)
- Behavior: removes the specified link record, then if `rm_orphan=true` and no links remain, applies `method` to the file. Use `method=delete` to hard-delete the physical file and DB record. Without `link_to_type`/`link_to_id`, no link is removed; `rm_orphan` only fires if the file already has zero links.
- Use the `/links` endpoint first to get `link_to_id_random` — the delete endpoint resolves `link_to_id` as a random string, not an integer.
Frontend guidance:
- Call these routes with the same `link_to_type` / `link_to_id` you plan to associate the resulting hosted_file with — the server resolves random IDs for you.