import { config } from "../config"; import { UploadVersionResult, VersionRecord } from "../models/versionRecord"; import { apiFetch, apiGetJson, apiSendExpectJson, ApiError, readErrorMessage } from "./apiClient"; import { generateGuid } from "./metadataService"; /** * เรียก version API ของ backend (FR-5/6/7 ฝั่ง client) * `fields` = map จาก `readContentControlFields()` ตาม FR-11 */ /** FR-5 — อัปโหลดไฟล์ปัจจุบันเป็น version ใหม่ (แนบ fields map ถ้ามี) * + FR-13: แนบ commit message ทางเลือกของผู้ใช้ */ export async function uploadVersion( documentId: string, file: Blob, clientVersionId: string, fields?: Record, fileName?: string, message?: string ): Promise { const form = new FormData(); form.append("file", file, fileName || `${documentId}.docx`); form.append("clientVersionId", clientVersionId); if (fields && Object.keys(fields).length > 0) { form.append("fields", JSON.stringify(fields)); } const trimmedMessage = message?.trim(); if (trimmedMessage) { form.append("message", trimmedMessage); } return apiSendExpectJson( `/api/documents/${documentId}/versions`, { method: "POST", body: form }, "อัปโหลด version ไม่สำเร็จ" ); } /** FR-6 — version history เรียงใหม่ → เก่า */ export async function getVersions(documentId: string): Promise { return apiGetJson( `/api/documents/${documentId}/versions`, "โหลด version history ไม่สำเร็จ" ); } /** FR-7 — URL ของ download endpoint (ผ่าน backend proxy เท่านั้น — MinIO ไม่ถูก expose) */ export function buildDownloadUrl(documentId: string, versionId: string): string { return `${config.apiBaseUrl}/api/documents/${documentId}/versions/${versionId}/download`; } export interface VersionDownloadLink { url: string; /** ISO-8601 เวลาที่ URL หมดอายุ */ expiresAt: string; } /** * FR-7 — ขอ presigned URL อายุสั้นของ version หนึ่ง เพื่อเปิดในเบราว์เซอร์ของผู้ใช้ * (webview ของ Word ทิ้ง blob download เงียบๆ — ให้เบราว์เซอร์จริงจัดการแทน) */ export async function getDownloadLink( documentId: string, versionId: string ): Promise { return apiGetJson( `/api/documents/${documentId}/versions/${versionId}/download-link`, "ขอลิงก์ดาวน์โหลดไม่สำเร็จ" ); } /** FR-7 — ดาวน์โหลดไฟล์ของ version หนึ่งเป็น Blob (ต้องแนบ Bearer จึงต้อง fetch แทน link ตรง) */ export async function downloadVersion(documentId: string, versionId: string): Promise { const response = await apiFetch(buildDownloadUrl(documentId, versionId)); if (!response.ok) { throw new ApiError( response.status, await readErrorMessage(response, `ดาวน์โหลด version ไม่สำเร็จ (${response.status})`) ); } return response.blob(); } /** สร้าง clientVersionId ใหม่สำหรับ upload ครั้งถัดไป */ export function newClientVersionId(): string { return generateGuid(); }