import { getBearerAuthHeaders } from './authHeaders'; import { projectSettingsErrorFromResponse } from './projectSettingsError'; export type ApiProjectMemberRole = 'owner' | 'member' | 'viewer'; export type ApiProjectMemberStatus = 'active' | 'exited'; export type ApiDocumentDuty = 'author' | 'reviewer' | 'approver' | ''; export interface ApiProjectMemberRecord { id?: number; project_id?: number; user_id: number; username?: string; name?: string; project_role: ApiProjectMemberRole; document_duty?: ApiDocumentDuty; status: ApiProjectMemberStatus; joined_at?: string; } export interface ListProjectMembersResponse { members: ApiProjectMemberRecord[]; } export interface UpsertProjectMemberPayload { user_id: number; project_role: ApiProjectMemberRole; document_duty?: ApiDocumentDuty; status?: ApiProjectMemberStatus; } async function memberApiError(res: Response, fallback: string) { const text = await res.text(); return projectSettingsErrorFromResponse(res.status, text, fallback); } export async function listProjectMembers(projectId: number): Promise { const res = await fetch(`/api/v1/projects/${projectId}/members`, { headers: getBearerAuthHeaders(), }); if (!res.ok) { throw await memberApiError(res, `获取项目成员失败: ${res.status}`); } const data: ListProjectMembersResponse = await res.json(); return data.members ?? []; } export async function addProjectMember( projectId: number, payload: UpsertProjectMemberPayload ): Promise { const res = await fetch(`/api/v1/projects/${projectId}/members`, { method: 'POST', headers: getBearerAuthHeaders('application/json'), body: JSON.stringify(payload), }); if (!res.ok) { throw await memberApiError(res, `添加项目成员失败: ${res.status}`); } } export async function updateProjectMember( projectId: number, payload: UpsertProjectMemberPayload ): Promise { const res = await fetch(`/api/v1/projects/${projectId}/members`, { method: 'PUT', headers: getBearerAuthHeaders('application/json'), body: JSON.stringify(payload), }); if (!res.ok) { throw await memberApiError(res, `更新项目成员失败: ${res.status}`); } } export async function removeProjectMember(projectId: number, userId: number): Promise { const res = await fetch( `/api/v1/projects/${projectId}/members?user_id=${encodeURIComponent(String(userId))}`, { method: 'DELETE', headers: getBearerAuthHeaders(), } ); if (!res.ok) { throw await memberApiError(res, `移出项目成员失败: ${res.status}`); } }