import express from 'express'; import { listMedia, createMedia, listCctv, listSatRequests, createSatRequest, updateSatRequestStatus, isValidSatStatus, } from './aerialService.js'; import { isValidNumber } from '../middleware/security.js'; import { requireAuth, requirePermission } from '../auth/authMiddleware.js'; const router = express.Router(); // ============================================================ // AERIAL_MEDIA 라우트 // ============================================================ // GET /api/aerial/media — 미디어 목록 router.get('/media', requireAuth, requirePermission('aerial', 'READ'), async (req, res) => { try { const { equipType, mediaType, acdntSn, search } = req.query; const acdntSnNum = acdntSn ? parseInt(acdntSn as string, 10) : undefined; if (acdntSn && !isValidNumber(acdntSnNum, 1, 999999)) { res.status(400).json({ error: '유효하지 않은 사고 번호' }); return; } const items = await listMedia({ equipType: equipType as string | undefined, mediaType: mediaType as string | undefined, acdntSn: acdntSnNum, search: search as string | undefined, }); res.json(items); } catch (err) { console.error('[aerial] 미디어 목록 오류:', err); res.status(500).json({ error: '미디어 목록 조회 실패' }); } }); // POST /api/aerial/media — 미디어 메타 등록 router.post('/media', requireAuth, requirePermission('aerial', 'CREATE'), async (req, res) => { try { const { acdntSn, fileNm, orgnlNm, filePath, lon, lat, locDc, equipTpCd, equipNm, mediaTpCd, takngDtm, fileSz, resolution, } = req.body; if (!fileNm) { res.status(400).json({ error: '파일명은 필수입니다.' }); return; } const result = await createMedia({ acdntSn, fileNm, orgnlNm, filePath, lon, lat, locDc, equipTpCd, equipNm, mediaTpCd, takngDtm, fileSz, resolution, }); res.status(201).json(result); } catch (err) { console.error('[aerial] 미디어 등록 오류:', err); res.status(500).json({ error: '미디어 등록 실패' }); } }); // ============================================================ // CCTV_CAMERA 라우트 // ============================================================ // GET /api/aerial/cctv — CCTV 목록 router.get('/cctv', requireAuth, requirePermission('aerial', 'READ'), async (req, res) => { try { const { region, status } = req.query; const items = await listCctv({ region: region as string | undefined, status: status as string | undefined, }); res.json(items); } catch (err) { console.error('[aerial] CCTV 목록 오류:', err); res.status(500).json({ error: 'CCTV 목록 조회 실패' }); } }); // ============================================================ // SAT_REQUEST 라우트 // ============================================================ // GET /api/aerial/satellite — 위성 촬영 요청 목록 router.get('/satellite', requireAuth, requirePermission('aerial', 'READ'), async (req, res) => { try { const { status } = req.query; const items = await listSatRequests({ status: status as string | undefined, }); res.json(items); } catch (err) { console.error('[aerial] 위성 요청 목록 오류:', err); res.status(500).json({ error: '위성 요청 목록 조회 실패' }); } }); // POST /api/aerial/satellite — 위성 촬영 요청 생성 router.post('/satellite', requireAuth, requirePermission('aerial', 'CREATE'), async (req, res) => { try { const { reqCd, acdntSn, lon, lat, zoneDc, coordDc, zoneAreaKm2, satNm, providerNm, resolution, purposeDc, reqstrNm, reqDtm, expectedRcvDtm, } = req.body; if (!reqCd) { res.status(400).json({ error: '요청코드는 필수입니다.' }); return; } const result = await createSatRequest({ reqCd, acdntSn, lon, lat, zoneDc, coordDc, zoneAreaKm2, satNm, providerNm, resolution, purposeDc, reqstrNm, reqDtm, expectedRcvDtm, }); res.status(201).json(result); } catch (err) { console.error('[aerial] 위성 요청 생성 오류:', err); res.status(500).json({ error: '위성 요청 생성 실패' }); } }); // POST /api/aerial/satellite/:sn/status — 위성 요청 상태 변경 router.post('/satellite/:sn/status', requireAuth, requirePermission('aerial', 'CREATE'), 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 { sttsCd } = req.body; if (!sttsCd || !isValidSatStatus(sttsCd)) { res.status(400).json({ error: '유효하지 않은 상태값 (PENDING/SHOOTING/COMPLETED/CANCELLED)' }); return; } await updateSatRequestStatus(sn, sttsCd); res.json({ success: true }); } catch (err) { console.error('[aerial] 위성 요청 상태 변경 오류:', err); res.status(500).json({ error: '위성 요청 상태 변경 실패' }); } }); export default router;