refactor(anon-chat): route upload through anonymousChatApiService

Fixes #1245. Deduplicate the anonymous-chat file upload request, which
was inlined verbatim in DocumentsSidebar.tsx and free-composer.tsx
while anonymousChatApiService.uploadDocument already existed.

Key change: service now returns a discriminated result instead of
throwing on 409. Callers need to distinguish 409 (quota exceeded, ->
gate to login) from other non-OK responses (real errors, -> throw).

  export type AnonUploadResult =
    | { ok: true; data: { filename: string; size_bytes: number } }
    | { ok: false; reason: "quota_exceeded" };

Both call sites now do:

  const result = await anonymousChatApiService.uploadDocument(file);
  if (!result.ok) {
    if (result.reason === "quota_exceeded") gate("upload more documents");
    return;
  }
  const data = result.data;

Dropped the BACKEND_URL import in both files (no longer used). Verified
zero remaining /api/v1/public/anon-chat/upload references in
surfsense_web/.
This commit is contained in:
Trevin Chow 2026-04-23 03:26:42 -07:00
parent 7245ab4046
commit a2ddf47650
3 changed files with 20 additions and 36 deletions

View file

@ -12,6 +12,10 @@ import { ValidationError } from "../error";
const BASE = "/api/v1/public/anon-chat";
export type AnonUploadResult =
| { ok: true; data: { filename: string; size_bytes: number } }
| { ok: false; reason: "quota_exceeded" };
class AnonymousChatApiService {
private baseUrl: string;
@ -71,7 +75,7 @@ class AnonymousChatApiService {
});
};
uploadDocument = async (file: File): Promise<{ filename: string; size_bytes: number }> => {
uploadDocument = async (file: File): Promise<AnonUploadResult> => {
const formData = new FormData();
formData.append("file", file);
const res = await fetch(this.fullUrl("/upload"), {
@ -79,11 +83,15 @@ class AnonymousChatApiService {
credentials: "include",
body: formData,
});
if (res.status === 409) {
return { ok: false, reason: "quota_exceeded" };
}
if (!res.ok) {
const body = await res.json().catch(() => ({}));
throw new Error(body.detail || `Upload failed: ${res.status}`);
}
return res.json();
const data = await res.json();
return { ok: true, data };
};
getDocument = async (): Promise<{ filename: string; size_bytes: number } | null> => {