import { API_ENDPOINTS } from "@/api/config"; import { jsonRequestInit, requestJson } from "@/api/http"; export type SectionState = { section_id?: string; status: "editing" | "submitted" | "approved" | "rejected"; head_commit_id: string | null; version: number; locked_by: string | null; locked_at: string | null; lock_expires_at: string | null; updated_at?: string; }; export type Section = { id: string; title: string; description: string | null; user_id: string | null; created_by: string | null; created_at: string; updated_at: string; state: Omit; }; export type SectionCommit = { id: string; section_id: string; parent_commit_id: string | null; commit_no: number; kind: "manual" | "restore"; restored_from_commit_id: string | null; created_by: string; created_at: string; title: string | null; note: string | null; snapshot_hash: string | null; snapshot?: unknown; }; export type SectionSubmission = { id: string; section_id: string; commit_id: string; submitted_by: string; submitted_at: string; status: "pending" | "approved" | "rejected" | "conflicted"; reviewed_by: string | null; reviewed_at: string | null; review_note: string | null; snapshot_hash: string | null; snapshot?: unknown; }; export type EditorLoadResponse = { section: Section; state: SectionState; commit: SectionCommit | null; snapshot: unknown; }; export type CreateSectionInput = { id?: string; title: string; description?: string | null; user_id?: string; created_by?: string; }; export type CreateCommitInput = { snapshot: unknown; created_by?: string; user_id?: string; expected_version?: number; expected_head_commit_id?: string | null; title?: string | null; note?: string | null; }; export async function fetchSections(): Promise { return requestJson(API_ENDPOINTS.sections); } export async function createSection(input: CreateSectionInput): Promise
{ return requestJson
(API_ENDPOINTS.sections, jsonRequestInit("POST", input)); } export async function openSectionEditor(sectionId: string, userId?: string): Promise { const params = new URLSearchParams(); if (userId) params.set("user_id", userId); return requestJson(sectionUrl(sectionId, "editor", params)); } export async function lockSection(sectionId: string, userId: string): Promise<{ state: SectionState }> { return requestJson<{ state: SectionState }>( sectionUrl(sectionId, "lock"), jsonRequestInit("POST", { user_id: userId }) ); } export async function unlockSection(sectionId: string, userId: string): Promise<{ success: boolean }> { return requestJson<{ success: boolean }>( sectionUrl(sectionId, "unlock"), jsonRequestInit("POST", { user_id: userId }) ); } export async function createSectionCommit( sectionId: string, input: CreateCommitInput ): Promise<{ commit: SectionCommit; state: SectionState }> { return requestJson<{ commit: SectionCommit; state: SectionState }>( sectionUrl(sectionId, "commits"), jsonRequestInit("POST", input) ); } export async function fetchSectionCommits( sectionId: string, options?: { includeSnapshot?: boolean } ): Promise { const params = new URLSearchParams(); if (options?.includeSnapshot) params.set("include_snapshot", "1"); return requestJson(sectionUrl(sectionId, "commits", params)); } export async function restoreSectionCommit( sectionId: string, input: { commit_id: string; created_by?: string; user_id?: string; expected_version?: number; expected_head_commit_id?: string | null; title?: string | null; note?: string | null; } ): Promise<{ commit: SectionCommit; state: SectionState }> { return requestJson<{ commit: SectionCommit; state: SectionState }>( sectionUrl(sectionId, "restore"), jsonRequestInit("POST", input) ); } export async function submitSection( sectionId: string, input: { commit_id?: string; submitted_by?: string; user_id?: string } ): Promise { return requestJson(sectionUrl(sectionId, "submit"), jsonRequestInit("POST", input)); } export async function fetchSectionSubmissions( sectionId: string, options?: { includeSnapshot?: boolean } ): Promise { const params = new URLSearchParams(); if (options?.includeSnapshot) params.set("include_snapshot", "1"); return requestJson(sectionUrl(sectionId, "submissions", params)); } export async function approveSubmission( submissionId: string, input: { reviewed_by?: string; user_id?: string; review_note?: string | null } ): Promise { return requestJson( submissionUrl(submissionId, "approve"), jsonRequestInit("POST", input) ); } export async function rejectSubmission( submissionId: string, input: { reviewed_by?: string; user_id?: string; review_note?: string | null } ): Promise { return requestJson( submissionUrl(submissionId, "reject"), jsonRequestInit("POST", input) ); } function sectionUrl(sectionId: string, path?: string, params?: URLSearchParams): string { return appendQuery( `${API_ENDPOINTS.sections}/${encodeURIComponent(sectionId)}${path ? `/${path}` : ""}`, params ); } function submissionUrl(submissionId: string, path: "approve" | "reject"): string { return `${API_ENDPOINTS.submissions}/${encodeURIComponent(submissionId)}/${path}`; } function appendQuery(url: string, params?: URLSearchParams): string { const suffix = params?.toString(); return suffix ? `${url}?${suffix}` : url; }