- 우측 패널에 HNS 대기확산/긴급구난 완료 이력 목록 및 체크박스 연동 - incidents 목록에 hasHnsCompleted/hasRescueCompleted 플래그 추가 - hns/rescue 목록 API에 acdntSn 필터 추가 - /gsc/accidents 셀렉트박스 소스를 gsc.tgs_acdnt_info → wing.ACDNT 로 전환 - gsc → wing.ACDNT 동기화 마이그레이션 032 추가
69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import express from 'express';
|
|
import { listOps, getOps, listScenarios } from './rescueService.js';
|
|
import { isValidNumber } from '../middleware/security.js';
|
|
import { requireAuth, requirePermission } from '../auth/authMiddleware.js';
|
|
|
|
const router = express.Router();
|
|
|
|
// ============================================================
|
|
// GET /api/rescue/ops — 구조 작전 목록
|
|
// ============================================================
|
|
router.get('/ops', requireAuth, requirePermission('rescue', 'READ'), async (req, res) => {
|
|
try {
|
|
const { sttsCd, acdntTpCd, search, acdntSn } = req.query;
|
|
const acdntSnNum = acdntSn ? parseInt(acdntSn as string, 10) : undefined;
|
|
const items = await listOps({
|
|
sttsCd: sttsCd as string | undefined,
|
|
acdntTpCd: acdntTpCd as string | undefined,
|
|
search: search as string | undefined,
|
|
acdntSn: acdntSnNum && !Number.isNaN(acdntSnNum) ? acdntSnNum : undefined,
|
|
});
|
|
res.json(items);
|
|
} catch (err) {
|
|
console.error('[rescue] 구조 작전 목록 오류:', err);
|
|
res.status(500).json({ error: '구조 작전 목록 조회 실패' });
|
|
}
|
|
});
|
|
|
|
// ============================================================
|
|
// GET /api/rescue/ops/:sn — 구조 작전 단건 상세
|
|
// ============================================================
|
|
router.get('/ops/:sn', requireAuth, requirePermission('rescue', 'READ'), async (req, res) => {
|
|
try {
|
|
const sn = parseInt(req.params.sn as string, 10);
|
|
if (!isValidNumber(sn, 1, 999999)) {
|
|
res.status(400).json({ error: '유효하지 않은 구조 작전 번호' });
|
|
return;
|
|
}
|
|
const item = await getOps(sn);
|
|
if (!item) {
|
|
res.status(404).json({ error: '구조 작전을 찾을 수 없습니다.' });
|
|
return;
|
|
}
|
|
res.json(item);
|
|
} catch (err) {
|
|
console.error('[rescue] 구조 작전 상세 오류:', err);
|
|
res.status(500).json({ error: '구조 작전 상세 조회 실패' });
|
|
}
|
|
});
|
|
|
|
// ============================================================
|
|
// GET /api/rescue/ops/:sn/scenarios — 시나리오 목록
|
|
// ============================================================
|
|
router.get('/ops/:sn/scenarios', requireAuth, requirePermission('rescue', 'READ'), async (req, res) => {
|
|
try {
|
|
const sn = parseInt(req.params.sn as string, 10);
|
|
if (!isValidNumber(sn, 1, 999999)) {
|
|
res.status(400).json({ error: '유효하지 않은 구조 작전 번호' });
|
|
return;
|
|
}
|
|
const scenarios = await listScenarios(sn);
|
|
res.json(scenarios);
|
|
} catch (err) {
|
|
console.error('[rescue] 시나리오 목록 오류:', err);
|
|
res.status(500).json({ error: '시나리오 목록 조회 실패' });
|
|
}
|
|
});
|
|
|
|
export default router;
|