import { normalizeGenealogyPathId } from './genealogy-contract.js' import { normalizeGenealogyInvitation, normalizeGenealogyInvitationRedeemPayload, normalizeGenealogyInvitationToken, normalizeIssuedGenealogyInvitation, normalizeJoinApplicationPayload, normalizeJoinAuditPayload, normalizeMyGenealogyInvitations } from './genealogy-membership-contract.js' import { normalizeResourcePathId } from './request-normalizers.js' import { createRequestError, requestStrict } from './request-client.js' const readMembershipList = async (url, label, requestOptions) => { const rows = await requestStrict({ url, method: 'GET' }, { requestController: requestOptions.requestController ?? null }) if (!Array.isArray(rows)) { throw createRequestError(`${label}响应不是列表`, 'LIST_RESPONSE_INVALID') } return rows } const writeMembership = (url, method, data, requestOptions) => { return requestStrict({ url, method, ...(data === undefined ? {} : { data }) }, { requestController: requestOptions.requestController ?? null }) } export const genealogyMembershipApi = { async previewGenealogyInvitation(token, requestOptions = {}) { const normalizedToken = normalizeGenealogyInvitationToken(token) const invitation = await requestStrict({ url: `/genealogy/app/genealogies/invitations/preview?token=${encodeURIComponent(normalizedToken)}`, method: 'GET' }, { requestController: requestOptions.requestController ?? null }) return normalizeGenealogyInvitation(invitation, 'ACTIVE') }, async issueGenealogyInvitation(genealogyId, requestOptions = {}) { const normalizedGenealogyId = normalizeGenealogyPathId(genealogyId) const invitationResponse = await writeMembership( `/genealogy/app/genealogies/${normalizedGenealogyId}/invitations`, 'POST', {}, requestOptions ) const invitation = normalizeIssuedGenealogyInvitation(invitationResponse) if (invitation.genealogyId !== normalizedGenealogyId) { throw createRequestError( '家谱邀请码归属与当前家谱不匹配', 'GENEALOGY_INVITATION_RESPONSE_INVALID' ) } return invitation }, async getMyGenealogyInvitations(requestOptions = {}) { const invitations = await requestStrict({ url: '/genealogy/app/genealogies/invitations/mine', method: 'GET' }, { requestController: requestOptions.requestController ?? null }) return normalizeMyGenealogyInvitations(invitations) }, async revokeGenealogyInvitation(inviteId, requestOptions = {}) { const normalizedInviteId = normalizeResourcePathId(inviteId, '家谱邀请标识') await requestStrict({ url: `/genealogy/app/genealogies/invitations/${normalizedInviteId}`, method: 'DELETE' }, { requireData: false, requestController: requestOptions.requestController ?? null }) return null }, async redeemGenealogyInvitation(payload, requestOptions = {}) { const invitation = await writeMembership( '/genealogy/app/genealogies/invitations/redeem', 'POST', normalizeGenealogyInvitationRedeemPayload(payload), requestOptions ) return normalizeGenealogyInvitation(invitation, 'REDEEMED') }, async applyToJoin(genealogyId, payload, requestOptions = {}) { const normalizedGenealogyId = normalizeGenealogyPathId(genealogyId) const applicationDraft = normalizeJoinApplicationPayload(payload) return requestStrict({ url: `/genealogy/app/genealogies/${normalizedGenealogyId}/join-applies`, method: 'POST', data: applicationDraft }, { requestController: requestOptions.requestController ?? null }) }, async getMyJoinApplications(requestOptions = {}) { return readMembershipList( '/genealogy/app/genealogies/join-applies/mine', '我的加入申请', requestOptions ) }, async withdrawJoinApplication(applicationId, requestOptions = {}) { const normalizedApplicationId = normalizeResourcePathId(applicationId, '加入申请标识') await requestStrict({ url: `/genealogy/app/genealogies/join-applies/${normalizedApplicationId}`, method: 'DELETE' }, { requireData: false, requestController: requestOptions.requestController ?? null }) return null }, async getPendingApplications(genealogyId, requestOptions = {}) { const normalizedGenealogyId = normalizeGenealogyPathId(genealogyId) return readMembershipList( `/genealogy/app/genealogies/${normalizedGenealogyId}/join-applies/pending`, '待审核申请', requestOptions ) }, async auditApplication(genealogyId, applicationId, payload, requestOptions = {}) { const normalizedGenealogyId = normalizeGenealogyPathId(genealogyId) const normalizedApplicationId = normalizeResourcePathId(applicationId, '加入申请标识') const auditDecision = normalizeJoinAuditPayload(payload) await requestStrict({ url: `/genealogy/app/genealogies/${normalizedGenealogyId}/join-applies/${normalizedApplicationId}/audit`, method: 'PUT', data: auditDecision }, { requireData: false, requestController: requestOptions.requestController ?? null }) return null } }