wing-ops/docs/README.md

285 lines
9.1 KiB
Markdown
Executable File

# 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 (운영) + wing_auth DB (인증)
```
### 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/ @components/ 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, seed
├── database/
│ ├── init.sql wing DB 스키마
│ ├── auth_init.sql wing_auth DB 스키마
│ └── migration/ 001~016 마이그레이션
└── .gitea/workflows/ CI/CD 파이프라인
```
### Path Alias
| Alias | 경로 |
|-------|------|
| `@common/*` | `src/common/*` |
| `@components/*` | `src/components/*` |
---
## 탭 구성 (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` | 시뮬레이션 실행/결과 |
---
## 데이터베이스
| DB | 용도 | 비고 |
|----|------|------|
| wing | 운영 데이터 | PostgreSQL 16 + PostGIS |
| wing_auth | 인증/권한 | 동일 서버, 별도 DB |
마이그레이션 파일: `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
AUTH_DB_HOST=localhost
AUTH_DB_PORT=5432
AUTH_DB_NAME=wing_auth
AUTH_DB_USER=wing_auth
AUTH_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` | 테스트 규칙 |