# PROJECT: AE Hosted Files — Upload Util & V3 Actions Migration **Status:** In Progress **Date:** 2026-03-25 **Affected systems:** Frontend (aether_app_sveltekit), Backend (aether_api_fastapi) --- ## Background The legacy `hosted_file.router` (registered at prefix `/hosted_file`) was commented out in `app/routers/registry.py` as part of the V3 migration: ```python # app.include_router(hosted_file.router, prefix='/hosted_file', tags=['Hosted File']) app.include_router(api_v3_actions_hosted_file.router, prefix='/v3/action/hosted_file', ...) ``` This broke several frontend features that were still calling the old endpoints. Three endpoints have been fixed on the frontend side (already committed and pushed). One endpoint still needs a backend fix. --- ## Endpoints: Status Summary ### FIXED (frontend updated to call new V3 path) | Old endpoint | New endpoint | Frontend file | |---|---|---| | `POST /hosted_file/upload_files` | `POST /v3/action/hosted_file/upload` | `src/lib/ae_core/ae_comp__hosted_files_upload.svelte`, `src/routes/events/ae_comp__event_files_upload.svelte` | | `GET /hosted_file/{id}/clip_video` | `GET /v3/action/hosted_file/{id}/clip_video` | `src/lib/ae_core/ae_comp__hosted_files_clip_video.svelte` | ### NEEDS BACKEND ACTION — Hash Lookup Endpoint **Missing endpoint:** `GET /hosted_file/hash/{hosted_file_hash}` This endpoint existed in the legacy `hosted_file.py` router (line 233) and has **not** been ported to `api_v3_actions_hosted_file.py`. **What it does:** 1. Looks up a `hosted_file` record by its `hash_sha256` field 2. Optionally checks that the physical file actually exists on disk (`check_for_local=true`) 3. Returns the full hosted_file object with two extra flags: - `hosted_file_found_check: true` — file record exists AND physical file confirmed on disk - `hosted_file_size_check: ` — file size from disk **Legacy implementation (hosted_file.py:233):** ```python @router.get('/hash/{hosted_file_hash}', response_model=Resp_Body_Base) async def check_hosted_file_obj_w_hash( hosted_file_hash: str = Path(min_length=64, max_length=64), check_for_local: Optional[bool] = True, commons: Common_Route_Params = Depends(common_route_params), ): if hfid := lookup_file_hash(file_hash=hosted_file_hash): obj = load_hosted_file_obj(hosted_file_id=hfid, model_as_dict=True) if check_for_local and obj: if check := check_for_hosted_file_hash_file(file_hash=hosted_file_hash, sub_dir=obj.get('subdirectory_path', '')): obj['hosted_file_found_check'] = True obj['hosted_file_size_check'] = check['file_size'] return mk_resp(data=obj, response=commons.response) return mk_resp(data=False, status_code=404, response=commons.response) ``` **Where it's called on the frontend:** - `src/lib/ae_core/core__check_hosted_file_obj_w_hash.ts` — thin wrapper, calls `GET /hosted_file/hash/{hash}` - `src/lib/elements/element_input_file.svelte` — calls this before uploading (dedup check) - `src/lib/elements/element_input_files_tbl.svelte` — same (dedup check in the table file input) - Exported via `src/lib/ae_core/ae_core_functions.ts` as `core_func.check_hosted_file_obj_w_hash` **Current impact:** The 404 causes a null return. The frontend checks `result && result.hosted_file_found_check` — so if null, it silently skips the dedup check and proceeds to upload anyway. Uploads still work, but duplicate files may be created rather than reusing existing records. **Requested fix (backend):** Port this endpoint to `api_v3_actions_hosted_file.py` as: ``` GET /v3/action/hosted_file/hash/{hosted_file_hash} ``` Parameters and response shape should match the legacy implementation exactly. The `check_for_local` query param (default `True`) must be preserved — the frontend passes `check_for_local=true` and expects `hosted_file_found_check` in the response. **After backend deploys the new endpoint**, the frontend needs one line changed in `src/lib/ae_core/core__check_hosted_file_obj_w_hash.ts`: ```ts // Before: const endpoint = `/hosted_file/hash/${hosted_file_hash}`; // After: const endpoint = `/v3/action/hosted_file/hash/${hosted_file_hash}`; ``` --- ## Other Legacy Endpoints — Audit Notes The following were also in `hosted_file.py` but appear to either have V3 equivalents already or are not currently called by the frontend. Backend should confirm: | Legacy endpoint | V3 equivalent | Notes | |---|---|---| | `GET /hosted_file/{id}/download` | `GET /v3/action/hosted_file/{id}/download` | Exists in V3 router | | `DELETE /hosted_file/{id}` | `DELETE /v3/action/hosted_file/{id}` | Exists in V3 router | | `GET /hosted_file/{id}/convert_file` | `GET /v3/action/hosted_file/{id}/convert_file` | Exists in V3 router | | `GET /hosted_file/{id}/stream` | Unknown | Not confirmed in V3 router — verify | | `GET /hosted_file/directory_check` | Unknown | Admin/dev utility — verify if still needed | | `GET /hosted_file/hash/{hash}/download` (via V3) | `GET /v3/action/hosted_file/hash/{sha256}/download` | Exists in V3 router (hash-based download) | | `GET /hosted_file/tmp/{subdir}/{filename}/download` | Unknown | Temp file download — verify if still needed | | `POST /hosted_file/create_video` | Unknown | Verify if still needed | --- ## Coordinator Notes - Frontend commits fixing upload and clip_video are on branch `ae_app_3x_llm` (commits `a5a806e2` and `362136e6`) - Once the backend adds the hash lookup endpoint, the frontend one-line fix in `core__check_hosted_file_obj_w_hash.ts` can be committed alongside it - The `check_for_local` flag is important — it verifies the physical file exists on disk, not just the DB record. Don't drop it in the V3 port.