zioinfo-mail/app/services/api.ts
DESKTOP-TKLFCPR\ython 8fbb64a12a feat(ui): Manager DR·네트워크·CSAP 관제 + Messenger DR·네트워크 화면 구현
## 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>
2026-05-31 09:53:17 +09:00

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