## GUARDiA Manager (frontend) - pages/DrConsole.tsx — DR 재해복구 관제 (시나리오/RTO-RPO/테스트 실행) - pages/NetworkConsole.tsx — 네트워크 장비 관제 (백업/diff/상태) - pages/CsapConsole.tsx — CSAP 준수율 대시보드 (점검/Excel 다운로드) - App.tsx — 3개 라우트 추가 (/dr, /network, /csap) - Sidebar.tsx — '운영 관제' 그룹 메뉴 추가 - AppLayout.tsx — 페이지 타이틀 3개 추가 ## GUARDiA Messenger (React Native) - app/(tabs)/dr.tsx — DR 모니터링 화면 (M-01) - app/(tabs)/network.tsx — 네트워크 장비 현황 화면 (M-02) - app/(tabs)/_layout.tsx — DR·네트워크 탭 추가 - services/api.ts — DR/네트워크/CSAP API 함수 추가 - hooks/useBiometric.ts — 생체인증 훅 (M-03) - hooks/useOfflineCache.ts — 오프라인 캐시 훅 (M-04) ## 매뉴얼 - 16_API_명세서.md — v2.2.0 업데이트 - 39_DR_네트워크장비_CSAP_운영가이드.md — Manager/Messenger UI 연동 현황 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
import axios from 'axios'
|
|
import * as SecureStore from 'expo-secure-store'
|
|
import { API_BASE } from '../constants/Config'
|
|
|
|
const client = axios.create({
|
|
baseURL: API_BASE,
|
|
timeout: 15000,
|
|
// 자체서명 인증서 허용 (개발/테스트)
|
|
})
|
|
|
|
client.interceptors.request.use(async (cfg) => {
|
|
const token = await SecureStore.getItemAsync('grd_token')
|
|
if (token) cfg.headers.Authorization = `Bearer ${token}`
|
|
return cfg
|
|
})
|
|
|
|
client.interceptors.response.use(
|
|
(r) => r,
|
|
async (err) => {
|
|
if (err.response?.status === 401) {
|
|
await SecureStore.deleteItemAsync('grd_token')
|
|
await SecureStore.deleteItemAsync('grd_user')
|
|
}
|
|
return Promise.reject(err)
|
|
}
|
|
)
|
|
|
|
/* ── 인증 ── */
|
|
export const login = (username: string, password: string) =>
|
|
client.post('/api/auth/login', { username, password })
|
|
|
|
export const getMe = () =>
|
|
client.get('/api/auth/me')
|
|
|
|
/* ── 대시보드 ── */
|
|
export const getDashboard = () =>
|
|
client.get('/api/dashboard')
|
|
|
|
/* ── SR ── */
|
|
export const getSRList = (page = 0, size = 20) =>
|
|
client.get(`/api/tasks?page=${page}&size=${size}`)
|
|
|
|
export const getSRDetail = (id: number) =>
|
|
client.get(`/api/tasks/${id}`)
|
|
|
|
export const createSR = (data: { title: string; description: string; priority: string; sr_type: string }) =>
|
|
client.post('/api/tasks', data)
|
|
|
|
export const updateSRStatus = (id: number, status: string) =>
|
|
client.patch(`/api/tasks/${id}/status`, { status })
|
|
|
|
/* ── AI 챗봇 ── */
|
|
export const sendAIMessage = (message: string) =>
|
|
client.post('/api/chatbot/message', { message })
|
|
|
|
/* ── 라이선스 ── */
|
|
export const getLicenseStatus = () =>
|
|
client.get('/api/license/status')
|
|
|
|
/* ── 알림 ── */
|
|
export const getNotifications = () =>
|
|
client.get('/api/notifications?size=30')
|
|
|
|
export const markNotificationRead = (id: number) =>
|
|
client.patch(`/api/notifications/${id}/read`)
|
|
|
|
/* ── DR 자동화 ── */
|
|
export const getDRDashboard = () => client.get('/api/dr/dashboard')
|
|
export const getDRRtoRpo = () => client.get('/api/dr/rto-rpo')
|
|
export const getDRScenarios = () => client.get('/api/dr/scenarios')
|
|
export const runDRTest = (scenarioId: number) =>
|
|
client.post('/api/dr/test', { scenario_id: scenarioId, test_type: 'RECOVERY' })
|
|
|
|
/* ── 네트워크 장비 ── */
|
|
export const getNetworkDevices = (instId?: number) =>
|
|
client.get('/api/network/devices', { params: instId ? { inst_id: instId } : {} })
|
|
export const getNetworkTopology = () => client.get('/api/network/topology')
|
|
export const backupNetworkDevice = (id: number) =>
|
|
client.post(`/api/network/devices/${id}/backup`)
|
|
export const getNetworkDiff = (id: number) =>
|
|
client.get(`/api/network/devices/${id}/diff`)
|
|
|
|
/* ── CSAP 점검 ── */
|
|
export const getCSAPDashboard = () => client.get('/api/compliance/csap/dashboard')
|
|
export const getCSAPItems = () => client.get('/api/compliance/csap/items')
|
|
export const getCSAPResults = () => client.get('/api/compliance/csap/results')
|
|
|
|
export default client
|