/** * Governance API Client for DAARION.city * Based on: backend/http/governance.routes.ts */ import type { AgentGovLevel, GovernanceScope, AgentRolesResponse, GovernanceAgent, GovernancePower, RevocationType, } from '../types/governance'; // API base URL for governance endpoints const getApiBase = () => { if (typeof window === 'undefined') { return process.env.INTERNAL_API_URL || 'http://daarion-city-service:7001'; } return ''; }; const API_BASE = getApiBase(); async function fetchApi(endpoint: string, options?: RequestInit): Promise { const url = `${API_BASE}${endpoint}`; const response = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', ...options?.headers, }, }); if (!response.ok) { const error = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(error.detail || `HTTP ${response.status}`); } return response.json(); } // ============================================================================ // AGENT GOVERNANCE // ============================================================================ export async function promoteAgent( actorId: string, targetId: string, newLevel: AgentGovLevel, scope: GovernanceScope, reason?: string ): Promise<{ success: boolean; message: string }> { return fetchApi('/api/v1/governance/agent/promote', { method: 'POST', body: JSON.stringify({ actorId, targetId, newLevel, scope, reason }), }); } export async function demoteAgent( actorId: string, targetId: string, newLevel: AgentGovLevel, scope: GovernanceScope, reason?: string ): Promise<{ success: boolean; message: string }> { return fetchApi('/api/v1/governance/agent/demote', { method: 'POST', body: JSON.stringify({ actorId, targetId, newLevel, scope, reason }), }); } export async function revokeAgent( actorId: string, targetId: string, reason: string, scope: GovernanceScope, revocationType: RevocationType = 'soft' ): Promise<{ success: boolean; message: string }> { return fetchApi('/api/v1/governance/agent/revoke', { method: 'POST', body: JSON.stringify({ actorId, targetId, reason, scope, revocationType }), }); } export async function suspendAgent( actorId: string, targetId: string, reason: string, scope: GovernanceScope ): Promise<{ success: boolean; message: string }> { return fetchApi('/api/v1/governance/agent/suspend', { method: 'POST', body: JSON.stringify({ actorId, targetId, reason, scope }), }); } export async function reinstateAgent( actorId: string, targetId: string, scope: GovernanceScope ): Promise<{ success: boolean; message: string }> { return fetchApi('/api/v1/governance/agent/reinstate', { method: 'POST', body: JSON.stringify({ actorId, targetId, scope }), }); } export async function getAgentRoles(agentId: string): Promise { return fetchApi(`/api/v1/governance/agent/${agentId}/roles`); } export async function getAgentPermissions(agentId: string): Promise { return fetchApi(`/api/v1/governance/agent/${agentId}/permissions`); } export async function checkPermission( actorId: string, action: string, targetType: string, targetId: string ): Promise<{ allowed: boolean; reason?: string }> { return fetchApi('/api/v1/governance/check', { method: 'POST', body: JSON.stringify({ actorId, action, targetType, targetId }), }); } // ============================================================================ // CITY GOVERNANCE AGENTS // ============================================================================ export async function getCityAgents(): Promise { const raw = await fetchApi>('/api/v1/governance/agents/city'); return raw.map((agent) => ({ id: agent.id, displayName: agent.display_name, avatarUrl: agent.avatar_url, govLevel: (agent.gov_level || 'guest') as AgentGovLevel, status: (agent.status || 'active') as 'active' | 'suspended' | 'revoked', })); } export async function getDistrictLeadAgents(): Promise { try { const raw = await fetchApi>('/api/v1/governance/agents/district-leads'); return raw.map((agent) => ({ id: agent.id, displayName: agent.display_name, avatarUrl: agent.avatar_url, govLevel: (agent.gov_level || 'district_lead') as AgentGovLevel, status: (agent.status || 'active') as 'active' | 'suspended' | 'revoked', homeMicrodaoId: agent.home_microdao_id, homeMicrodaoName: agent.home_microdao_name, })); } catch { return []; } } export async function getAgentsByLevel(level: AgentGovLevel): Promise { return fetchApi(`/api/v1/governance/agents/by-level/${level}`); } // ============================================================================ // DAIS KEYS // ============================================================================ export async function revokeDaisKey( daisId: string, keyId: string, reason: string, revokedBy: string ): Promise<{ success: boolean }> { return fetchApi('/api/v1/governance/dais/keys/revoke', { method: 'POST', body: JSON.stringify({ daisId, keyId, reason, revokedBy }), }); } // Export all functions as a namespace export const governanceApi = { promoteAgent, demoteAgent, revokeAgent, suspendAgent, reinstateAgent, getAgentRoles, getAgentPermissions, checkPermission, getCityAgents, getDistrictLeadAgents, getAgentsByLevel, revokeDaisKey, };