fix: correct all web-admin API endpoint URLs to match backend routes

The web-admin frontend was calling incorrect API paths that didn't match
the actual backend service routes through Kong gateway, causing all
requests to fail with 404 or route-mismatch errors.

URL corrections:
- servers: /api/v1/servers → /api/v1/inventory/servers
- runbooks: /api/v1/runbooks → /api/v1/ops/runbooks
- risk-rules: /api/v1/security/risk-rules → /api/v1/agent/risk-rules
- credentials: /api/v1/security/credentials → /api/v1/inventory/credentials
- roles: /api/v1/security/roles → /api/v1/auth/roles
- permissions: /api/v1/security/permissions → /api/v1/auth/permissions
- tenants: /api/v1/tenants → /api/v1/admin/tenants
- communication: /api/v1/communication → /api/v1/comm

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-02 09:29:51 -08:00
parent 94e3153e39
commit 375c5632f6
16 changed files with 63 additions and 63 deletions

View File

@ -3,7 +3,7 @@ import type { CreateRunbookDto } from '@/application/dto/runbook.dto';
import type { Runbook } from '@/domain/entities/runbook'; import type { Runbook } from '@/domain/entities/runbook';
export async function createRunbook(data: CreateRunbookDto): Promise<Runbook> { export async function createRunbook(data: CreateRunbookDto): Promise<Runbook> {
return apiClient<Runbook>('/api/v1/runbooks', { return apiClient<Runbook>('/api/v1/ops/runbooks', {
method: 'POST', method: 'POST',
body: data, body: data,
}); });

View File

@ -1,7 +1,7 @@
import { apiClient } from '@/infrastructure/api/api-client'; import { apiClient } from '@/infrastructure/api/api-client';
export async function deleteRunbook(id: string): Promise<void> { export async function deleteRunbook(id: string): Promise<void> {
await apiClient(`/api/v1/runbooks/${id}`, { await apiClient(`/api/v1/ops/runbooks/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
} }

View File

@ -2,7 +2,7 @@ import { apiClient } from '@/infrastructure/api/api-client';
import type { RunbookExecution } from '@/domain/entities/runbook'; import type { RunbookExecution } from '@/domain/entities/runbook';
export async function testRunbook(id: string): Promise<RunbookExecution> { export async function testRunbook(id: string): Promise<RunbookExecution> {
return apiClient<RunbookExecution>(`/api/v1/runbooks/${id}/execute`, { return apiClient<RunbookExecution>(`/api/v1/ops/runbooks/${id}/execute`, {
method: 'POST', method: 'POST',
body: { dryRun: true }, body: { dryRun: true },
}); });

View File

@ -3,7 +3,7 @@ import type { UpdateRunbookDto } from '@/application/dto/runbook.dto';
import type { Runbook } from '@/domain/entities/runbook'; import type { Runbook } from '@/domain/entities/runbook';
export async function updateRunbook(id: string, data: UpdateRunbookDto): Promise<Runbook> { export async function updateRunbook(id: string, data: UpdateRunbookDto): Promise<Runbook> {
return apiClient<Runbook>(`/api/v1/runbooks/${id}`, { return apiClient<Runbook>(`/api/v1/ops/runbooks/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });

View File

@ -3,27 +3,27 @@ import type { Credential } from '@/domain/entities/credential';
export async function listCredentials(params?: Record<string, string>): Promise<Credential[]> { export async function listCredentials(params?: Record<string, string>): Promise<Credential[]> {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<Credential[]>(`/api/v1/security/credentials${query}`); return apiClient<Credential[]>(`/api/v1/inventory/credentials${query}`);
} }
export async function createCredential( export async function createCredential(
credential: Omit<Credential, 'id' | 'createdAt' | 'updatedAt' | 'associatedServers'>, credential: Omit<Credential, 'id' | 'createdAt' | 'updatedAt' | 'associatedServers'>,
): Promise<Credential> { ): Promise<Credential> {
return apiClient<Credential>('/api/v1/security/credentials', { return apiClient<Credential>('/api/v1/inventory/credentials', {
method: 'POST', method: 'POST',
body: credential, body: credential,
}); });
} }
export async function updateCredential(id: string, data: Partial<Credential>): Promise<Credential> { export async function updateCredential(id: string, data: Partial<Credential>): Promise<Credential> {
return apiClient<Credential>(`/api/v1/security/credentials/${id}`, { return apiClient<Credential>(`/api/v1/inventory/credentials/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
} }
export async function deleteCredential(id: string): Promise<void> { export async function deleteCredential(id: string): Promise<void> {
await apiClient(`/api/v1/security/credentials/${id}`, { await apiClient(`/api/v1/inventory/credentials/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
} }

View File

@ -7,16 +7,16 @@ export interface PermissionMatrix {
} }
export async function getPermissionMatrix(): Promise<PermissionMatrix> { export async function getPermissionMatrix(): Promise<PermissionMatrix> {
return apiClient<PermissionMatrix>('/api/v1/security/permissions/matrix'); return apiClient<PermissionMatrix>('/api/v1/auth/permissions/matrix');
} }
export async function updateRolePermissions(roleId: string, permissions: string[]): Promise<void> { export async function updateRolePermissions(roleId: string, permissions: string[]): Promise<void> {
await apiClient(`/api/v1/security/permissions/roles/${roleId}`, { await apiClient(`/api/v1/auth/roles/${roleId}/permissions`, {
method: 'PUT', method: 'PUT',
body: { permissions }, body: { permissions },
}); });
} }
export async function listRoles(): Promise<Role[]> { export async function listRoles(): Promise<Role[]> {
return apiClient<Role[]>('/api/v1/security/roles'); return apiClient<Role[]>('/api/v1/auth/roles');
} }

View File

@ -3,27 +3,27 @@ import type { RiskRule } from '@/domain/entities/risk-rule';
export async function listRiskRules(params?: Record<string, string>): Promise<RiskRule[]> { export async function listRiskRules(params?: Record<string, string>): Promise<RiskRule[]> {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<RiskRule[]>(`/api/v1/security/risk-rules${query}`); return apiClient<RiskRule[]>(`/api/v1/agent/risk-rules${query}`);
} }
export async function createRiskRule( export async function createRiskRule(
rule: Omit<RiskRule, 'id' | 'createdAt' | 'updatedAt'>, rule: Omit<RiskRule, 'id' | 'createdAt' | 'updatedAt'>,
): Promise<RiskRule> { ): Promise<RiskRule> {
return apiClient<RiskRule>('/api/v1/security/risk-rules', { return apiClient<RiskRule>('/api/v1/agent/risk-rules', {
method: 'POST', method: 'POST',
body: rule, body: rule,
}); });
} }
export async function updateRiskRule(id: string, data: Partial<RiskRule>): Promise<RiskRule> { export async function updateRiskRule(id: string, data: Partial<RiskRule>): Promise<RiskRule> {
return apiClient<RiskRule>(`/api/v1/security/risk-rules/${id}`, { return apiClient<RiskRule>(`/api/v1/agent/risk-rules/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
} }
export async function deleteRiskRule(id: string): Promise<void> { export async function deleteRiskRule(id: string): Promise<void> {
await apiClient(`/api/v1/security/risk-rules/${id}`, { await apiClient(`/api/v1/agent/risk-rules/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
} }

View File

@ -3,7 +3,7 @@ import type { CreateServerDto } from '@/application/dto/server.dto';
import type { Server } from '@/domain/entities/server'; import type { Server } from '@/domain/entities/server';
export async function addServer(data: CreateServerDto): Promise<Server> { export async function addServer(data: CreateServerDto): Promise<Server> {
return apiClient<Server>('/api/v1/servers', { return apiClient<Server>('/api/v1/inventory/servers', {
method: 'POST', method: 'POST',
body: data, body: data,
}); });

View File

@ -1,7 +1,7 @@
import { apiClient } from '@/infrastructure/api/api-client'; import { apiClient } from '@/infrastructure/api/api-client';
export async function removeServer(id: string): Promise<void> { export async function removeServer(id: string): Promise<void> {
await apiClient(`/api/v1/servers/${id}`, { await apiClient(`/api/v1/inventory/servers/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
} }

View File

@ -3,7 +3,7 @@ import type { UpdateServerDto } from '@/application/dto/server.dto';
import type { Server } from '@/domain/entities/server'; import type { Server } from '@/domain/entities/server';
export async function updateServer(id: string, data: UpdateServerDto): Promise<Server> { export async function updateServer(id: string, data: UpdateServerDto): Promise<Server> {
return apiClient<Server>(`/api/v1/servers/${id}`, { return apiClient<Server>(`/api/v1/inventory/servers/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });

View File

@ -6,64 +6,64 @@ import type { EscalationPolicy } from '@/domain/entities/escalation-policy';
export const apiCommunicationRepository: CommunicationRepository = { export const apiCommunicationRepository: CommunicationRepository = {
async listContacts(params) { async listContacts(params) {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<Contact[]>(`/api/v1/communication/contacts${query}`); return apiClient<Contact[]>(`/api/v1/comm/contacts${query}`);
}, },
async getContactById(id) { async getContactById(id) {
return apiClient<Contact>(`/api/v1/communication/contacts/${id}`); return apiClient<Contact>(`/api/v1/comm/contacts/${id}`);
}, },
async createContact(contact) { async createContact(contact) {
return apiClient<Contact>('/api/v1/communication/contacts', { return apiClient<Contact>('/api/v1/comm/contacts', {
method: 'POST', method: 'POST',
body: contact, body: contact,
}); });
}, },
async updateContact(id, data) { async updateContact(id, data) {
return apiClient<Contact>(`/api/v1/communication/contacts/${id}`, { return apiClient<Contact>(`/api/v1/comm/contacts/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async removeContact(id) { async removeContact(id) {
await apiClient(`/api/v1/communication/contacts/${id}`, { await apiClient(`/api/v1/comm/contacts/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },
async listEscalationPolicies(params) { async listEscalationPolicies(params) {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<EscalationPolicy[]>(`/api/v1/communication/escalation-policies${query}`); return apiClient<EscalationPolicy[]>(`/api/v1/comm/escalation-policies${query}`);
}, },
async getEscalationPolicyById(id) { async getEscalationPolicyById(id) {
return apiClient<EscalationPolicy>(`/api/v1/communication/escalation-policies/${id}`); return apiClient<EscalationPolicy>(`/api/v1/comm/escalation-policies/${id}`);
}, },
async createEscalationPolicy(policy) { async createEscalationPolicy(policy) {
return apiClient<EscalationPolicy>('/api/v1/communication/escalation-policies', { return apiClient<EscalationPolicy>('/api/v1/comm/escalation-policies', {
method: 'POST', method: 'POST',
body: policy, body: policy,
}); });
}, },
async updateEscalationPolicy(id, data) { async updateEscalationPolicy(id, data) {
return apiClient<EscalationPolicy>(`/api/v1/communication/escalation-policies/${id}`, { return apiClient<EscalationPolicy>(`/api/v1/comm/escalation-policies/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async removeEscalationPolicy(id) { async removeEscalationPolicy(id) {
await apiClient(`/api/v1/communication/escalation-policies/${id}`, { await apiClient(`/api/v1/comm/escalation-policies/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },
async sendTestMessage(channelType, contactId) { async sendTestMessage(channelType, contactId) {
await apiClient('/api/v1/communication/test-message', { await apiClient('/api/v1/comm/test-message', {
method: 'POST', method: 'POST',
body: { channelType, contactId }, body: { channelType, contactId },
}); });

View File

@ -4,40 +4,40 @@ import type { Runbook, RunbookExecution } from '@/domain/entities/runbook';
export const apiRunbookRepository: RunbookRepository = { export const apiRunbookRepository: RunbookRepository = {
async list() { async list() {
return apiClient<Runbook[]>('/api/v1/runbooks'); return apiClient<Runbook[]>('/api/v1/ops/runbooks');
}, },
async getById(id) { async getById(id) {
return apiClient<Runbook>(`/api/v1/runbooks/${id}`); return apiClient<Runbook>(`/api/v1/ops/runbooks/${id}`);
}, },
async create(runbook) { async create(runbook) {
return apiClient<Runbook>('/api/v1/runbooks', { return apiClient<Runbook>('/api/v1/ops/runbooks', {
method: 'POST', method: 'POST',
body: runbook, body: runbook,
}); });
}, },
async update(id, data) { async update(id, data) {
return apiClient<Runbook>(`/api/v1/runbooks/${id}`, { return apiClient<Runbook>(`/api/v1/ops/runbooks/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async remove(id) { async remove(id) {
await apiClient(`/api/v1/runbooks/${id}`, { await apiClient(`/api/v1/ops/runbooks/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },
async execute(id) { async execute(id) {
return apiClient<RunbookExecution>(`/api/v1/runbooks/${id}/execute`, { return apiClient<RunbookExecution>(`/api/v1/ops/runbooks/${id}/execute`, {
method: 'POST', method: 'POST',
}); });
}, },
async getExecutions(id) { async getExecutions(id) {
return apiClient<RunbookExecution[]>(`/api/v1/runbooks/${id}/executions`); return apiClient<RunbookExecution[]>(`/api/v1/ops/runbooks/${id}/executions`);
}, },
}; };

View File

@ -7,72 +7,72 @@ import type { Role } from '@/domain/entities/role';
export const apiSecurityRepository: SecurityRepository = { export const apiSecurityRepository: SecurityRepository = {
async listRiskRules(params) { async listRiskRules(params) {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<RiskRule[]>(`/api/v1/security/risk-rules${query}`); return apiClient<RiskRule[]>(`/api/v1/agent/risk-rules${query}`);
}, },
async getRiskRuleById(id) { async getRiskRuleById(id) {
return apiClient<RiskRule>(`/api/v1/security/risk-rules/${id}`); return apiClient<RiskRule>(`/api/v1/agent/risk-rules/${id}`);
}, },
async createRiskRule(rule) { async createRiskRule(rule) {
return apiClient<RiskRule>('/api/v1/security/risk-rules', { return apiClient<RiskRule>('/api/v1/agent/risk-rules', {
method: 'POST', method: 'POST',
body: rule, body: rule,
}); });
}, },
async updateRiskRule(id, data) { async updateRiskRule(id, data) {
return apiClient<RiskRule>(`/api/v1/security/risk-rules/${id}`, { return apiClient<RiskRule>(`/api/v1/agent/risk-rules/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async removeRiskRule(id) { async removeRiskRule(id) {
await apiClient(`/api/v1/security/risk-rules/${id}`, { await apiClient(`/api/v1/agent/risk-rules/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },
async listCredentials(params) { async listCredentials(params) {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<Credential[]>(`/api/v1/security/credentials${query}`); return apiClient<Credential[]>(`/api/v1/inventory/credentials${query}`);
}, },
async getCredentialById(id) { async getCredentialById(id) {
return apiClient<Credential>(`/api/v1/security/credentials/${id}`); return apiClient<Credential>(`/api/v1/inventory/credentials/${id}`);
}, },
async createCredential(credential) { async createCredential(credential) {
return apiClient<Credential>('/api/v1/security/credentials', { return apiClient<Credential>('/api/v1/inventory/credentials', {
method: 'POST', method: 'POST',
body: credential, body: credential,
}); });
}, },
async updateCredential(id, data) { async updateCredential(id, data) {
return apiClient<Credential>(`/api/v1/security/credentials/${id}`, { return apiClient<Credential>(`/api/v1/inventory/credentials/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async removeCredential(id) { async removeCredential(id) {
await apiClient(`/api/v1/security/credentials/${id}`, { await apiClient(`/api/v1/inventory/credentials/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },
async listRoles() { async listRoles() {
return apiClient<Role[]>('/api/v1/security/roles'); return apiClient<Role[]>('/api/v1/auth/roles');
}, },
async getPermissionMatrix() { async getPermissionMatrix() {
return apiClient<{ roles: Role[]; allPermissions: string[] }>('/api/v1/security/permissions/matrix'); return apiClient<{ roles: Role[]; allPermissions: string[] }>('/api/v1/auth/permissions/matrix');
}, },
async updateRolePermissions(roleId, permissions) { async updateRolePermissions(roleId, permissions) {
await apiClient(`/api/v1/security/permissions/roles/${roleId}`, { await apiClient(`/api/v1/auth/roles/${roleId}/permissions`, {
method: 'PUT', method: 'PUT',
body: { permissions }, body: { permissions },
}); });

View File

@ -5,29 +5,29 @@ import type { Server } from '@/domain/entities/server';
export const apiServerRepository: ServerRepository = { export const apiServerRepository: ServerRepository = {
async list(params) { async list(params) {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<Server[]>(`/api/v1/servers${query}`); return apiClient<Server[]>(`/api/v1/inventory/servers${query}`);
}, },
async getById(id) { async getById(id) {
return apiClient<Server>(`/api/v1/servers/${id}`); return apiClient<Server>(`/api/v1/inventory/servers/${id}`);
}, },
async create(server) { async create(server) {
return apiClient<Server>('/api/v1/servers', { return apiClient<Server>('/api/v1/inventory/servers', {
method: 'POST', method: 'POST',
body: server, body: server,
}); });
}, },
async update(id, data) { async update(id, data) {
return apiClient<Server>(`/api/v1/servers/${id}`, { return apiClient<Server>(`/api/v1/inventory/servers/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async remove(id) { async remove(id) {
await apiClient(`/api/v1/servers/${id}`, { await apiClient(`/api/v1/inventory/servers/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },

View File

@ -12,29 +12,29 @@ export interface TenantRepository {
export const apiTenantRepository: TenantRepository = { export const apiTenantRepository: TenantRepository = {
async list(params) { async list(params) {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<Tenant[]>(`/api/v1/tenants${query}`); return apiClient<Tenant[]>(`/api/v1/admin/tenants${query}`);
}, },
async getById(id) { async getById(id) {
return apiClient<Tenant>(`/api/v1/tenants/${id}`); return apiClient<Tenant>(`/api/v1/admin/tenants/${id}`);
}, },
async create(tenant) { async create(tenant) {
return apiClient<Tenant>('/api/v1/tenants', { return apiClient<Tenant>('/api/v1/admin/tenants', {
method: 'POST', method: 'POST',
body: tenant, body: tenant,
}); });
}, },
async update(id, data) { async update(id, data) {
return apiClient<Tenant>(`/api/v1/tenants/${id}`, { return apiClient<Tenant>(`/api/v1/admin/tenants/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
}, },
async remove(id) { async remove(id) {
await apiClient(`/api/v1/tenants/${id}`, { await apiClient(`/api/v1/admin/tenants/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
}, },

View File

@ -20,14 +20,14 @@ export const fetchRiskRules = createAsyncThunk(
'riskRules/fetchAll', 'riskRules/fetchAll',
async (params?: Record<string, string>) => { async (params?: Record<string, string>) => {
const query = params ? '?' + new URLSearchParams(params).toString() : ''; const query = params ? '?' + new URLSearchParams(params).toString() : '';
return apiClient<RiskRule[]>(`/api/v1/security/risk-rules${query}`); return apiClient<RiskRule[]>(`/api/v1/agent/risk-rules${query}`);
}, },
); );
export const addRiskRule = createAsyncThunk( export const addRiskRule = createAsyncThunk(
'riskRules/add', 'riskRules/add',
async (rule: Omit<RiskRule, 'id' | 'createdAt' | 'updatedAt'>) => { async (rule: Omit<RiskRule, 'id' | 'createdAt' | 'updatedAt'>) => {
return apiClient<RiskRule>('/api/v1/security/risk-rules', { return apiClient<RiskRule>('/api/v1/agent/risk-rules', {
method: 'POST', method: 'POST',
body: rule, body: rule,
}); });
@ -37,7 +37,7 @@ export const addRiskRule = createAsyncThunk(
export const editRiskRule = createAsyncThunk( export const editRiskRule = createAsyncThunk(
'riskRules/edit', 'riskRules/edit',
async ({ id, data }: { id: string; data: Partial<RiskRule> }) => { async ({ id, data }: { id: string; data: Partial<RiskRule> }) => {
return apiClient<RiskRule>(`/api/v1/security/risk-rules/${id}`, { return apiClient<RiskRule>(`/api/v1/agent/risk-rules/${id}`, {
method: 'PUT', method: 'PUT',
body: data, body: data,
}); });
@ -47,7 +47,7 @@ export const editRiskRule = createAsyncThunk(
export const removeRiskRule = createAsyncThunk( export const removeRiskRule = createAsyncThunk(
'riskRules/remove', 'riskRules/remove',
async (id: string) => { async (id: string) => {
await apiClient(`/api/v1/security/risk-rules/${id}`, { await apiClient(`/api/v1/agent/risk-rules/${id}`, {
method: 'DELETE', method: 'DELETE',
}); });
return id; return id;