Files
TK-FB-Project/docs/architecture/OVERVIEW.md
Hyungi Ahn 1e7155b864 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>
2025-12-11 10:16:57 +09:00

625 lines
27 KiB
Markdown

# 시스템 아키텍처 개요
> 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*