# WING-OPS 해양 오염 사고 대응을 위한 방제 운영 지원 시스템. 유류/HNS 확산 예측, 역추적 분석, 구조 시나리오, 항공 방제, 자산 관리, SCAT 해안평가, 기상/해상 정보를 통합 제공한다. --- ## 기술 스택 | 영역 | 기술 | |------|------| | Frontend | React 19, Vite 7, TypeScript 5.9, Tailwind CSS 3 | | 상태 관리 | Zustand (클라이언트), TanStack Query (서버) | | 지도 | MapLibre GL JS 5.x + deck.gl 9.x (GPU 렌더링) | | UI | lucide-react (아이콘), @dnd-kit (드래그앤드롭), emoji-mart (이모지) | | 실시간 | Socket.IO Client 4.8 | | Backend | Express 4, TypeScript, PostgreSQL 16 + PostGIS | | 인증 | JWT HttpOnly Cookie (`WING_SESSION`) + Google OAuth + RBAC 2차원 권한 | | 보안 | Helmet, CORS, Rate-limit, 입력 살균 (sanitize) | | CI/CD | Gitea Actions (main 머지 시 자동 배포) | --- ## 아키텍처 ``` [Browser] | | React 19 + MapLibre GL JS + deck.gl | Zustand (로컬 상태) + TanStack Query (서버 상태) | |--- HTTP (Axios) ---> [Express 4 API] |--- WebSocket ------> [Socket.IO] | [PostgreSQL 16 + PostGIS] wing 단일 DB (public, auth, wing 3개 스키마) ``` ### HTTP 정책 - **GET / POST only** (보안취약점 가이드 준수, PUT/DELETE 미사용) - JWT는 HttpOnly Cookie로 전송, Axios 인터셉터에서 자동 처리 - Helmet CORP cross-origin 설정 (sendBeacon 허용) ### 권한 체계 - RBAC 2차원 권한: **리소스(FEATURE_ID)** x **오퍼레이션(RCUD)** - `permResolver` 엔진이 AUTH_PERM 테이블의 OPER_CD 기반으로 권한 해석 - 백엔드: `requireAuth` > `requireRole` > `requirePermission` 미들웨어 체인 --- ## 프로젝트 구조 ``` wing/ ├── frontend/src/ │ ├── App.tsx MainTab 라우팅, 감사 로그 자동 기록 │ ├── index.css @tailwind + @import 엔트리 │ ├── common/ @common/ alias │ │ ├── components/ auth/, layer/, layout/, map/, ui/ │ │ ├── hooks/ useFeatureTracking, useLayers, useSubMenu │ │ ├── services/ api.ts, authApi.ts, layerService.ts │ │ ├── store/ authStore, menuStore (Zustand) │ │ ├── types/ backtrack, boomLine, hns, navigation │ │ ├── utils/ cn, coordinates, geo, sanitize │ │ ├── styles/ base.css, components.css, wing.css (@layer) │ │ └── constants/ featureIds.ts (FEATURE_ID 상수 체계) │ └── tabs/ @tabs/ alias (11개 탭) │ ├── prediction/ 유류 확산 예측 │ ├── hns/ HNS 분석 │ ├── rescue/ 구조 시나리오 │ ├── aerial/ 항공 방제 │ ├── weather/ 해양 기상 │ ├── incidents/ 사건/사고 관리 │ ├── board/ 게시판 │ ├── reports/ 보고서 │ ├── assets/ 자산 관리 │ ├── scat/ Pre-SCAT 해안평가 │ └── admin/ 관리자 ├── backend/src/ │ ├── server.ts Express 진입점 + 보안 미들웨어 │ ├── auth/ JWT, OAuth, 미들웨어 │ ├── users/, roles/ 사용자/역할 관리, permResolver │ ├── settings/, menus/ 시스템 설정, 메뉴 │ ├── audit/ 감사 로그 │ ├── board/, hns/, reports/ 업무 도메인 │ ├── assets/, incidents/ 업무 도메인 │ ├── scat/, prediction/ 업무 도메인 │ ├── aerial/, rescue/ 업무 도메인 │ ├── routes/ layers, simulation │ ├── middleware/ security (sanitize, rate-limit) │ └── db/ wingDb (authDb는 re-export), seed ├── database/ │ ├── schema/ ERD용 순수 DDL (14파일) │ ├── seed/ 초기 데이터 (14파일) │ ├── migration/ 증분 마이그레이션 (001~016) │ └── _deprecated/ 구 스크립트 (통합 이전) └── .gitea/workflows/ CI/CD 파이프라인 ``` ### Path Alias | Alias | 경로 | |-------|------| | `@common/*` | `src/common/*` | | `@tabs/*` | `src/tabs/*` | --- ## 탭 구성 (11개) | 탭 | 패키지 | 설명 | |---|---|---| | prediction | 확산 예측 | 유류 확산 모델 시뮬레이션 (KOSPS/POSEIDON/OpenDrift 앙상블) | | hns | HNS 분석 | 위험유해물질 거동 분석 + 물질 DB | | rescue | 구조 시나리오 | 해상 구조 시나리오 모의 | | aerial | 항공 방제 | 항공 탐색, 드론, CCTV, 위성 | | weather | 해양 기상 | 실시간 해양기상 오버레이 | | incidents | 사건/사고 | 사건 이력 관리, 미디어 | | board | 게시판 | 공지/자료 게시판 | | reports | 보고서 | 오염보고서 생성기 | | assets | 자산 관리 | 방제 장비/기관/담당자/선박보험 | | scat | 해안평가 | Pre-SCAT 해안 구간 조사 | | admin | 관리자 | 사용자/역할/권한/메뉴/설정 | --- ## 백엔드 API 라우트 모든 API는 `/api/` 접두사 하위에 등록된다. ### 인증/관리 | 라우트 | 설명 | |--------|------| | `/api/auth` | JWT 로그인/로그아웃, OAuth, 토큰 갱신 | | `/api/users` | 사용자 CRUD | | `/api/roles` | 역할/권한 관리, RCUD 매트릭스 | | `/api/settings` | 시스템 설정 | | `/api/menus` | 메뉴 설정 | | `/api/audit` | 감사 로그 | ### 업무 도메인 | 라우트 | 설명 | |--------|------| | `/api/board` | 게시판 CRUD + 첨부파일 | | `/api/hns` | HNS 물질 검색/분석 | | `/api/reports` | 보고서 템플릿/생성/조회 | | `/api/assets` | 자산(장비/기관/선박/보험) 관리 | | `/api/incidents` | 사건/사고 이력 관리 | | `/api/scat` | SCAT 구역/구간/조사 | | `/api/prediction` | 확산 분석/역추적/오일펜스 | | `/api/aerial` | 항공 미디어/CCTV/위성 | | `/api/rescue` | 구난 작전/시나리오 | ### 지도/시뮬레이션 | 라우트 | 설명 | |--------|------| | `/api/layers` | 지도 레이어 데이터 | | `/api/simulation` | 시뮬레이션 실행/결과 | --- ## 데이터베이스 wing 단일 DB에 3개 스키마로 구성: | 스키마 | 용도 | 테이블 수 | |--------|------|-----------| | public | PostGIS 확장 | - | | auth | 인증/권한/감사로그 | 9 | | wing | 운영 데이터 | 35 | - 초기 DDL: `database/schema/` (14파일) - 초기 데이터: `database/seed/` (14파일) - 마이그레이션: `database/migration/001~016` --- ## 퀵스타트 ### 사전 요구사항 - Node.js 20+ (`.node-version` 파일, fnm 사용) - PostgreSQL 16+ (운영 DB 접근 가능해야 함) ### 실행 ```bash # 저장소 복제 git clone https://gitea.gc-si.dev/gc/wing-ops.git cd wing-ops # 백엔드 (터미널 1) cd backend && npm install && npm run dev # localhost:3001 # 프론트엔드 (터미널 2) cd frontend && npm install && npm run dev # localhost:5173 ``` ### 빌드/검증 ```bash # TypeScript 타입 체크 cd frontend && npx tsc --noEmit cd backend && npx tsc --noEmit # ESLint cd frontend && npx eslint . # 프로덕션 빌드 cd frontend && npm run build # tsc -b && vite build → dist/ cd backend && npm run build # tsc → dist/ ``` ### 환경 변수 프론트엔드 (`frontend/.env`): ``` VITE_API_URL=http://localhost:3001/api VITE_GOOGLE_CLIENT_ID=your-google-client-id ``` 백엔드 (`backend/.env`): ``` PORT=3001 NODE_ENV=development JWT_SECRET=your-jwt-secret DB_HOST=211.208.115.83 DB_PORT=5432 DB_NAME=wing DB_USER=wing DB_PASSWORD=your-password GOOGLE_CLIENT_ID=your-google-client-id ``` --- ## 배포 | 항목 | 값 | |------|---| | 프론트엔드 | https://wing-demo.gc-si.dev | | 백엔드 API | https://wing-demo.gc-si.dev/api/ | | CI/CD | Gitea Actions (main 머지 시 자동 배포) | --- ## 개발 워크플로우 ``` 브랜치 분기 → 개발 → 커밋/푸시 → develop MR → main PR → 자동 배포 ``` - `main`: 배포 가능한 안정 브랜치 (보호됨) - `develop`: 개발 통합 브랜치 (보호됨) - `feature/`, `bugfix/`, `hotfix/`: 작업 브랜치 - 직접 push 금지, MR을 통해서만 머지 --- ## 문서 안내 ### 개발 가이드 | 문서 | 설명 | |------|------| | [DEVELOPMENT-GUIDE.md](DEVELOPMENT-GUIDE.md) | 개발 워크플로우 전체 흐름 | | [COMMON-GUIDE.md](COMMON-GUIDE.md) | 공통 로직 (인증, 감사로그, 메뉴, API, 상태관리) | | [MENU-TAB-GUIDE.md](MENU-TAB-GUIDE.md) | 새 메뉴 탭 추가 절차 | ### 운영 가이드 | 문서 | 설명 | |------|------| | [INSTALL_GUIDE.md](INSTALL_GUIDE.md) | 설치 매뉴얼 (온라인/오프라인, DB 초기화) | | [CHANGELOG.md](CHANGELOG.md) | 전체 변경 이력 | ### 코드 컨벤션 (`.claude/rules/`) | 규칙 | 설명 | |------|------| | `team-policy.md` | 보안/품질 정책 | | `git-workflow.md` | 브랜치/커밋/MR 규칙 | | `code-style.md` | TypeScript/React 코드 스타일 | | `naming.md` | 네이밍 규칙 | | `testing.md` | 테스트 규칙 |