refactor: Phase 1 - 긴급 보안 및 중복 제거
## 🚨 보안 강화 - 하드코딩된 비밀번호를 환경변수로 전환 - .env.example 생성 및 보안 가이드 추가 - docker-compose.yml 환경변수 적용 - README.md에서 실제 비밀번호 제거 ## 🗑️ 중복 제거 - synology_deployment/ 디렉토리 제거 (268MB) - synology_deployment*.tar.gz 아카이브 제거 (234MB) - 총 502MB의 중복 파일 삭제 ## 🧹 백업 파일 정리 - *.backup 파일 제거 (10개) - *복사본* 파일 제거 - *이전* 파일 제거 - json(백업)/ 디렉토리 제거 ## 📋 .gitignore 업데이트 - 백업 파일 패턴 추가 - 보안 파일 제외 (.env, *.pem, *.key) - 임시 파일 제외 (*.tmp, *.new) - 빌드 아티팩트 제외 (*.tar.gz) ## 📚 문서화 - docs/ 디렉토리 구조 생성 - 리팩토링 분석 및 계획 문서 작성 - 코딩 스타일 가이드 작성 - 개발 환경 설정 가이드 작성 - 시스템 아키텍처 문서 작성 ## 변경된 파일 - .env.example (신규) - .gitignore (업데이트) - docker-compose.yml (환경변수 적용) - README.md (보안 정보 제거) - docs/* (신규 문서 7개) ## 보안 개선 효과 ✅ 비밀번호 노출 위험 제거 ✅ Git 히스토리에서 민감 정보 분리 ✅ 환경별 설정 분리 가능 ✅ 배포 보안 강화 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
624
docs/architecture/OVERVIEW.md
Normal file
624
docs/architecture/OVERVIEW.md
Normal file
@@ -0,0 +1,624 @@
|
||||
# 시스템 아키텍처 개요
|
||||
|
||||
> TK-FB-Project 시스템 아키텍처 및 설계 문서
|
||||
|
||||
## 📊 시스템 개요
|
||||
|
||||
TK-FB-Project는 Technical Korea의 **일일 작업 관리 시스템**으로, 작업자들의 일일 업무를 기록하고 관리하는 웹 기반 애플리케이션입니다.
|
||||
|
||||
### 주요 기능
|
||||
1. **작업 보고서 관리**: 일일 작업 내용 기록 및 조회
|
||||
2. **작업자 관리**: 작업자 정보 및 권한 관리
|
||||
3. **프로젝트 관리**: 프로젝트별 작업 추적
|
||||
4. **근태 관리**: 출퇴근 및 휴가 관리
|
||||
5. **대시보드**: 작업 통계 및 분석
|
||||
6. **이슈 관리**: 작업 중 발생한 이슈 추적
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 아키텍처 다이어그램
|
||||
|
||||
### 전체 시스템 구조
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 클라이언트 │
|
||||
│ (Web Browser) │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Dashboard │ │ Calendar │ │ Report │ │
|
||||
│ │ (HTML/ │ │ (HTML/ │ │ (HTML/ │ │
|
||||
│ │ CSS/JS) │ │ CSS/JS) │ │ CSS/JS) │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ HTTP/HTTPS
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Nginx (Port 8080) │
|
||||
│ (Static File Server) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ Reverse Proxy
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ API Server (Port 20005) │
|
||||
│ Node.js + Express │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Controllers │ │ Services │ │ Models │ │
|
||||
│ │ (Routes) │ │ (Business │ │ (Data │ │
|
||||
│ │ │ │ Logic) │ │ Access) │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Middlewares │ │ Utilities │ │
|
||||
│ │ (Auth, CORS) │ │ (Logger) │ │
|
||||
│ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ MySQL Protocol
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ MySQL 8.0 (Port 3306) │
|
||||
│ (Database) │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ users │ │ workers │ │ projects │ │
|
||||
│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
|
||||
│ │daily_work_ │ │ attendance │ │ issues │ │
|
||||
│ │ reports │ │ _records │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 배포 구조 (Docker Compose)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Docker Host (Synology NAS) │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────┐ │
|
||||
│ │ Container: web-ui (Nginx) │ │
|
||||
│ │ Port: 8080:80 │ │
|
||||
│ │ Volume: ./web-ui:/usr/share/nginx/html │ │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────────────────────────────────────────┐ │
|
||||
│ │ Container: api (Node.js) │ │
|
||||
│ │ Port: 20005:20005 │ │
|
||||
│ │ Volume: ./api.hyungi.net:/app │ │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────────────────────────────────────────┐ │
|
||||
│ │ Container: db (MySQL 8.0) │ │
|
||||
│ │ Port: 3306:3306 │ │
|
||||
│ │ Volume: mysql_data:/var/lib/mysql │ │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────┐ │
|
||||
│ │ Container: fastapi-bridge (Python) │ │
|
||||
│ │ Port: 8000:8000 │ │
|
||||
│ │ (Optional - AI 기능용) │ │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 기술 스택
|
||||
|
||||
### 프론트엔드
|
||||
| 기술 | 버전 | 용도 |
|
||||
|------|------|------|
|
||||
| HTML5 | - | 마크업 |
|
||||
| CSS3 | - | 스타일링 |
|
||||
| JavaScript (ES6+) | - | 클라이언트 로직 |
|
||||
| FullCalendar | 6.x | 캘린더 UI |
|
||||
| Chart.js | 3.x | 차트 시각화 |
|
||||
| jQuery | 3.x | DOM 조작 (레거시) |
|
||||
|
||||
### 백엔드
|
||||
| 기술 | 버전 | 용도 |
|
||||
|------|------|------|
|
||||
| Node.js | 20.x | 런타임 |
|
||||
| Express | 4.18+ | 웹 프레임워크 |
|
||||
| MySQL2 | 3.6+ | 데이터베이스 드라이버 |
|
||||
| JWT | 9.0+ | 인증 |
|
||||
| bcryptjs | 2.4+ | 비밀번호 해싱 |
|
||||
| dotenv | 16.3+ | 환경변수 관리 |
|
||||
|
||||
### 데이터베이스
|
||||
| 기술 | 버전 | 용도 |
|
||||
|------|------|------|
|
||||
| MySQL | 8.0+ | 관계형 데이터베이스 |
|
||||
|
||||
### 인프라
|
||||
| 기술 | 버전 | 용도 |
|
||||
|------|------|------|
|
||||
| Docker | 24+ | 컨테이너화 |
|
||||
| Docker Compose | 2.x | 오케스트레이션 |
|
||||
| Nginx | 1.25+ | 웹 서버 / 리버스 프록시 |
|
||||
|
||||
### 추가 도구
|
||||
| 기술 | 용도 |
|
||||
|------|------|
|
||||
| Python FastAPI | AI 기능 브릿지 (선택) |
|
||||
| OpenAI API | 작업 내용 분석 (선택) |
|
||||
|
||||
---
|
||||
|
||||
## 📂 디렉토리 구조
|
||||
|
||||
### 현재 구조
|
||||
|
||||
```
|
||||
TK-FB-Project/
|
||||
├── api.hyungi.net/ # 백엔드 API 서버
|
||||
│ ├── controllers/ # 컨트롤러 (라우트 핸들러)
|
||||
│ │ ├── dailyWorkReportController.js
|
||||
│ │ ├── workerController.js
|
||||
│ │ ├── projectController.js
|
||||
│ │ └── ...
|
||||
│ ├── models/ # 데이터 모델
|
||||
│ │ ├── dailyWorkReportModel.js
|
||||
│ │ ├── workerModel.js
|
||||
│ │ └── ...
|
||||
│ ├── routes/ # 라우트 정의
|
||||
│ │ ├── dailyWorkReportRoutes.js
|
||||
│ │ ├── workerRoutes.js
|
||||
│ │ └── ...
|
||||
│ ├── services/ # 비즈니스 로직 (일부)
|
||||
│ │ ├── authService.js
|
||||
│ │ ├── emailService.js
|
||||
│ │ └── ...
|
||||
│ ├── middleware/ # 미들웨어
|
||||
│ │ ├── errorMiddleware.js
|
||||
│ │ └── uploadMiddleware.js
|
||||
│ ├── utils/ # 유틸리티
|
||||
│ │ └── logger.js
|
||||
│ ├── uploads/ # 업로드 파일 저장소
|
||||
│ ├── index.js # 애플리케이션 진입점
|
||||
│ ├── package.json
|
||||
│ └── .env # 환경 변수
|
||||
│
|
||||
├── web-ui/ # 프론트엔드
|
||||
│ ├── pages/ # HTML 페이지 (51개)
|
||||
│ │ ├── index.html
|
||||
│ │ ├── daily-work-report.html
|
||||
│ │ ├── work-report-calendar.html
|
||||
│ │ └── ...
|
||||
│ ├── js/ # JavaScript (49개)
|
||||
│ │ ├── api-config.js
|
||||
│ │ ├── daily-work-report.js
|
||||
│ │ ├── work-report-calendar.js
|
||||
│ │ └── ...
|
||||
│ ├── css/ # CSS (22개)
|
||||
│ │ ├── common.css
|
||||
│ │ ├── daily-work-report.css
|
||||
│ │ └── ...
|
||||
│ └── assets/ # 정적 리소스
|
||||
│ └── images/
|
||||
│
|
||||
├── fastapi-bridge/ # Python FastAPI (선택)
|
||||
│ ├── main.py
|
||||
│ ├── requirements.txt
|
||||
│ └── ...
|
||||
│
|
||||
├── docs/ # 📚 프로젝트 문서
|
||||
│ ├── README.md
|
||||
│ ├── architecture/
|
||||
│ │ └── OVERVIEW.md # 이 파일
|
||||
│ ├── refactoring/
|
||||
│ │ ├── ANALYSIS.md
|
||||
│ │ ├── PLAN.md
|
||||
│ │ └── LOG.md
|
||||
│ ├── guides/
|
||||
│ │ ├── SETUP.md
|
||||
│ │ └── CODING_STYLE.md
|
||||
│ └── api/
|
||||
│
|
||||
├── docker-compose.yml # Docker Compose 설정
|
||||
├── .gitignore
|
||||
├── README.md
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### 목표 구조 (리팩토링 후)
|
||||
|
||||
```
|
||||
TK-FB-Project/
|
||||
├── api/ # 백엔드 (이름 변경)
|
||||
│ ├── src/
|
||||
│ │ ├── config/ # 설정 파일
|
||||
│ │ │ ├── database.js
|
||||
│ │ │ ├── cors.js
|
||||
│ │ │ └── routes.js
|
||||
│ │ ├── controllers/ # 라우트 핸들러만
|
||||
│ │ │ └── ...
|
||||
│ │ ├── services/ # 비즈니스 로직 (완성)
|
||||
│ │ │ └── ...
|
||||
│ │ ├── repositories/ # 데이터 접근 계층 (신규)
|
||||
│ │ │ └── ...
|
||||
│ │ ├── models/ # 데이터 모델 / 스키마
|
||||
│ │ │ └── ...
|
||||
│ │ ├── middlewares/ # 미들웨어
|
||||
│ │ │ ├── auth.js
|
||||
│ │ │ ├── permission.js
|
||||
│ │ │ └── errorHandler.js
|
||||
│ │ ├── utils/ # 유틸리티
|
||||
│ │ │ ├── errors.js
|
||||
│ │ │ ├── logger.js
|
||||
│ │ │ └── validator.js
|
||||
│ │ └── index.js # 진입점 (간결화)
|
||||
│ ├── tests/ # 테스트
|
||||
│ │ ├── unit/
|
||||
│ │ └── integration/
|
||||
│ └── package.json
|
||||
│
|
||||
├── web/ # 프론트엔드 (이름 변경)
|
||||
│ ├── public/ # 정적 파일
|
||||
│ │ └── assets/
|
||||
│ ├── src/
|
||||
│ │ ├── modules/ # 모듈화된 코드
|
||||
│ │ │ ├── common/
|
||||
│ │ │ │ ├── api-client.js
|
||||
│ │ │ │ ├── utils.js
|
||||
│ │ │ │ └── validator.js
|
||||
│ │ │ ├── calendar/
|
||||
│ │ │ │ ├── CalendarView.js
|
||||
│ │ │ │ ├── CalendarAPI.js
|
||||
│ │ │ │ └── CalendarUtils.js
|
||||
│ │ │ └── dashboard/
|
||||
│ │ ├── pages/ # 페이지별 스크립트
|
||||
│ │ └── styles/ # CSS
|
||||
│ │ ├── base/
|
||||
│ │ ├── components/
|
||||
│ │ ├── layouts/
|
||||
│ │ └── pages/
|
||||
│ └── index.html
|
||||
│
|
||||
├── database/ # 데이터베이스 관련
|
||||
│ ├── migrations/ # 마이그레이션
|
||||
│ ├── seeds/ # 시드 데이터
|
||||
│ └── schema/ # 스키마 정의
|
||||
│
|
||||
├── deployment/ # 배포 스크립트
|
||||
│ ├── docker/
|
||||
│ │ ├── api.Dockerfile
|
||||
│ │ ├── web.Dockerfile
|
||||
│ │ └── nginx.conf
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── docker-compose.dev.yml
|
||||
│ └── deploy.sh
|
||||
│
|
||||
├── docs/ # 문서
|
||||
└── scripts/ # 유틸리티 스크립트
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 데이터 흐름
|
||||
|
||||
### 1. 사용자 인증 플로우
|
||||
|
||||
```
|
||||
┌──────┐ ┌──────┐ ┌──────────┐ ┌──────┐
|
||||
│Client│ │ API │ │ Service │ │ DB │
|
||||
└──┬───┘ └──┬───┘ └────┬─────┘ └──┬───┘
|
||||
│ │ │ │
|
||||
│ POST /login │ │ │
|
||||
├────────────>│ │ │
|
||||
│ │ validate │ │
|
||||
│ ├───────────────>│ │
|
||||
│ │ │ findByUsername│
|
||||
│ │ ├──────────────>│
|
||||
│ │ │<──────────────┤
|
||||
│ │ │ user data │
|
||||
│ │ verify pwd │ │
|
||||
│ │<───────────────┤ │
|
||||
│ │ generate JWT │ │
|
||||
│ ├───────────────>│ │
|
||||
│ JWT Token│ │ │
|
||||
│<────────────┤ │ │
|
||||
│ │ │ │
|
||||
└─────────────┴────────────────┴───────────────┘
|
||||
```
|
||||
|
||||
### 2. 작업 보고서 생성 플로우
|
||||
|
||||
```
|
||||
┌──────┐ ┌─────┐ ┌──────────┐ ┌─────────┐ ┌────┐
|
||||
│Client│ │ API │ │ Service │ │ Repo │ │ DB │
|
||||
└──┬───┘ └──┬──┘ └────┬─────┘ └────┬────┘ └─┬──┘
|
||||
│ │ │ │ │
|
||||
│POST /reports │ │ │
|
||||
├──────────>│ │ │ │
|
||||
│ │ auth check │ │ │
|
||||
│ │ │ │ │
|
||||
│ │ validate │ │ │
|
||||
│ ├───────────>│ │ │
|
||||
│ │ │ checkDup │ │
|
||||
│ │ ├─────────────>│ │
|
||||
│ │ │ │ SELECT │
|
||||
│ │ │ ├─────────>│
|
||||
│ │ │ │<─────────┤
|
||||
│ │ │<─────────────┤ │
|
||||
│ │ │ create │ │
|
||||
│ │ ├─────────────>│ │
|
||||
│ │ │ │ INSERT │
|
||||
│ │ │ ├─────────>│
|
||||
│ │ │ │<─────────┤
|
||||
│ │ │<─────────────┤ │
|
||||
│ │ │ notify │ │
|
||||
│ │ │ (email/push) │ │
|
||||
│ │<───────────┤ │ │
|
||||
│<──────────┤ │ │ │
|
||||
│ 201 │ │ │ │
|
||||
└───────────┴────────────┴──────────────┴──────────┘
|
||||
```
|
||||
|
||||
### 3. 대시보드 데이터 조회 플로우
|
||||
|
||||
```
|
||||
Client → API → Service → Repository → DB
|
||||
↓
|
||||
Cache (Redis - 향후 도입 예정)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 보안 아키텍처
|
||||
|
||||
### 인증 (Authentication)
|
||||
|
||||
**JWT 기반 인증**:
|
||||
```javascript
|
||||
// 로그인 성공 시
|
||||
const token = jwt.sign(
|
||||
{
|
||||
userId: user.id,
|
||||
username: user.username,
|
||||
access_level: user.access_level
|
||||
},
|
||||
process.env.JWT_SECRET,
|
||||
{ expiresIn: '24h' }
|
||||
);
|
||||
|
||||
// 요청 시 헤더에 포함
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**토큰 검증 플로우**:
|
||||
```
|
||||
Request → Auth Middleware → Verify JWT → Attach user to req → Next
|
||||
↓ (invalid)
|
||||
401 Unauthorized
|
||||
```
|
||||
|
||||
### 권한 (Authorization)
|
||||
|
||||
**역할 기반 접근 제어 (RBAC)**:
|
||||
|
||||
| 역할 | 권한 |
|
||||
|------|------|
|
||||
| `system` | 모든 권한 (시스템 관리자) |
|
||||
| `admin` | 전체 데이터 조회 및 수정 |
|
||||
| `group_leader` | 그룹 내 데이터 관리 |
|
||||
| `worker` | 본인 데이터만 조회/수정 |
|
||||
|
||||
**권한 체크 미들웨어** (목표):
|
||||
```javascript
|
||||
// 특정 역할 필요
|
||||
router.get('/admin', requireRole('admin', 'system'), getAdminData);
|
||||
|
||||
// 본인 또는 관리자
|
||||
router.put('/reports/:id', requireOwnerOrAdmin, updateReport);
|
||||
```
|
||||
|
||||
### 데이터 보안
|
||||
|
||||
1. **비밀번호**: bcrypt로 해싱 (salt rounds: 10)
|
||||
2. **환경변수**: .env 파일 (Git 제외)
|
||||
3. **SQL Injection**: Prepared Statements 사용
|
||||
4. **XSS**: 입력값 sanitization
|
||||
5. **CORS**: 허용된 origin만 접근
|
||||
|
||||
---
|
||||
|
||||
## 📊 데이터베이스 설계
|
||||
|
||||
### ER 다이어그램
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ users │ │ workers │
|
||||
├─────────────┤ ├─────────────┤
|
||||
│ id (PK) │ ┌───>│ id (PK) │
|
||||
│ username │ │ │ name │
|
||||
│ password │ │ │ email │
|
||||
│ access_level│ │ │ position │
|
||||
│ worker_id(FK├────┘ │ is_active │
|
||||
└─────────────┘ └──────┬──────┘
|
||||
│
|
||||
│ 1:N
|
||||
│
|
||||
┌──────▼──────────┐
|
||||
│daily_work_ │
|
||||
│ reports │
|
||||
├─────────────────┤
|
||||
│ id (PK) │
|
||||
│ worker_id (FK) │
|
||||
│ project_id (FK) │
|
||||
│ report_date │
|
||||
│ work_content │
|
||||
│ work_hours │
|
||||
│ created_at │
|
||||
└──────┬──────────┘
|
||||
│ N:1
|
||||
│
|
||||
┌──────▼──────┐
|
||||
│ projects │
|
||||
├─────────────┤
|
||||
│ id (PK) │
|
||||
│ name │
|
||||
│ description │
|
||||
│ start_date │
|
||||
│ end_date │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
### 주요 테이블
|
||||
|
||||
| 테이블명 | 설명 | 주요 컬럼 |
|
||||
|----------|------|-----------|
|
||||
| `users` | 사용자 계정 | id, username, password, access_level |
|
||||
| `workers` | 작업자 정보 | id, name, email, position, group_id |
|
||||
| `daily_work_reports` | 일일 작업 보고서 | id, worker_id, project_id, report_date, work_content |
|
||||
| `projects` | 프로젝트 | id, name, description, start_date, end_date |
|
||||
| `attendance_records` | 근태 기록 | id, worker_id, date, clock_in, clock_out |
|
||||
| `issues` | 이슈 | id, project_id, reporter_id, title, status |
|
||||
| `work_types` | 작업 유형 | id, name, category |
|
||||
| `work_status_types` | 작업 상태 | id, name, color |
|
||||
|
||||
자세한 스키마는 [DATABASE_SCHEMA.md](../../DATABASE_SCHEMA.md) 참조
|
||||
|
||||
---
|
||||
|
||||
## 🚀 배포 프로세스
|
||||
|
||||
### 현재 배포 방식
|
||||
|
||||
```bash
|
||||
# 1. Docker Compose로 배포
|
||||
docker-compose up -d
|
||||
|
||||
# 2. 수동 업데이트
|
||||
docker-compose down
|
||||
git pull origin master
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
### 목표 CI/CD 파이프라인
|
||||
|
||||
```
|
||||
┌────────────┐ ┌────────────┐ ┌────────────┐
|
||||
│ Push │ │ Build │ │ Test │
|
||||
│ to GitHub ├─────>│ & Lint ├─────>│ (Jest) │
|
||||
└────────────┘ └────────────┘ └──────┬─────┘
|
||||
│
|
||||
▼
|
||||
┌────────────┐ ┌────────────┐
|
||||
│ Deploy │<─────│ Security │
|
||||
│ Production │ │ Scan │
|
||||
└────────────┘ └────────────┘
|
||||
```
|
||||
|
||||
**GitHub Actions 예시**:
|
||||
```yaml
|
||||
name: CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
- run: npm run lint
|
||||
|
||||
deploy:
|
||||
needs: test
|
||||
if: github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Deploy to Synology
|
||||
run: ./deployment/deploy.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 성능 고려사항
|
||||
|
||||
### 현재 성능 이슈
|
||||
|
||||
1. **N+1 쿼리 문제**: JOIN 사용 필요
|
||||
2. **SELECT * 사용**: 명시적 컬럼 지정 필요
|
||||
3. **인덱스 부족**: 주요 컬럼에 인덱스 추가 필요
|
||||
4. **캐싱 없음**: Redis 도입 검토
|
||||
|
||||
### 최적화 계획
|
||||
|
||||
```javascript
|
||||
// 1. 쿼리 최적화
|
||||
// Before: N+1 쿼리
|
||||
const reports = await getReports();
|
||||
for (const report of reports) {
|
||||
report.worker = await getWorker(report.worker_id);
|
||||
}
|
||||
|
||||
// After: JOIN 사용
|
||||
const reports = await db.query(`
|
||||
SELECT r.*, w.name as worker_name
|
||||
FROM daily_work_reports r
|
||||
JOIN workers w ON r.worker_id = w.id
|
||||
`);
|
||||
|
||||
// 2. 인덱스 추가
|
||||
CREATE INDEX idx_report_date ON daily_work_reports(report_date);
|
||||
CREATE INDEX idx_worker_id ON daily_work_reports(worker_id);
|
||||
|
||||
// 3. 캐싱 (Redis - 향후)
|
||||
const cachedData = await redis.get('dashboard:stats');
|
||||
if (cachedData) return JSON.parse(cachedData);
|
||||
|
||||
const data = await fetchDashboardStats();
|
||||
await redis.setex('dashboard:stats', 300, JSON.stringify(data));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔮 향후 계획
|
||||
|
||||
### Phase 1: 안정화 (현재)
|
||||
- 보안 강화
|
||||
- 코드 리팩토링
|
||||
- 테스트 작성
|
||||
|
||||
### Phase 2: 모듈화 (3개월)
|
||||
- 서비스 레이어 완성
|
||||
- 프론트엔드 모듈화
|
||||
- API 문서화
|
||||
|
||||
### Phase 3: 현대화 (6개월)
|
||||
- TypeScript 전환
|
||||
- React/Vue 도입
|
||||
- ORM 적용 (TypeORM/Prisma)
|
||||
|
||||
### Phase 4: 확장 (12개월)
|
||||
- 마이크로서비스 아키텍처
|
||||
- GraphQL API
|
||||
- 실시간 기능 (WebSocket)
|
||||
- 모바일 앱 (React Native)
|
||||
|
||||
---
|
||||
|
||||
## 📚 관련 문서
|
||||
|
||||
- [데이터베이스 스키마](../../DATABASE_SCHEMA.md)
|
||||
- [API 문서](../api/ENDPOINTS.md)
|
||||
- [개발 환경 설정](../guides/SETUP.md)
|
||||
- [리팩토링 계획](../refactoring/PLAN.md)
|
||||
|
||||
---
|
||||
|
||||
*마지막 업데이트: 2025-12-11*
|
||||
Reference in New Issue
Block a user