485 lines
11 KiB
Markdown
485 lines
11 KiB
Markdown
# 1호선 고장코드 (Tr_Code)
|
|
|
|
Flask + HTMX 기반의 철도 차량 고장코드 및 TCMS 신호 조회 웹 애플리케이션입니다.
|
|
|
|
## 📋 목차
|
|
|
|
- [주요 기능](#주요-기능)
|
|
- [시스템 아키텍처](#시스템-아키텍처)
|
|
- [설치 및 배포](#설치-및-배포)
|
|
- [환경 설정](#환경-설정)
|
|
- [회원 인증 시스템](#회원-인증-시스템) ⭐ NEW!
|
|
- [서비스 관리](#서비스-관리)
|
|
- [개발 환경](#개발-환경)
|
|
- [API 엔드포인트](#api-엔드포인트)
|
|
- [문제 해결](#문제-해결)
|
|
|
|
## 🎯 주요 기능
|
|
|
|
### 🔐 회원 관리 및 인증 (NEW!)
|
|
- **이메일 코드 인증** - 6자리 숫자 코드 입력 (링크 클릭 방식 대신)
|
|
- **생체인증** - WebAuthn API 활용 (지문, 얼굴 인식)
|
|
- **비밀번호 재설정** - 이메일 코드 인증 후 재설정
|
|
- **humetro.busan.kr 도메인 제한** (회사 이메일만 가입 가능)
|
|
- 부서별 사용자 관리 (신평차량, 노포차량, 차량처)
|
|
- 사번 기반 사용자 식별
|
|
- 동적 부서 목록 로드 (Supabase departments 테이블)
|
|
- 부서별 권한 관리 기반 구축 (조회/수정 권한 제어 가능)
|
|
- 세션 기반 로그인 상태 유지
|
|
|
|
### 고장코드 조회
|
|
- 제조사별 필터링 (우진, 로템 등)
|
|
- 장치별, 차량 타입별 검색
|
|
- 실시간 검색 (HTMX 기반)
|
|
- 코드 그룹핑 옵션
|
|
- 상세 정보 모달 표시
|
|
|
|
### TCMS 신호 조회
|
|
- 신호 분류별 필터링
|
|
- 제조사/차량별 검색
|
|
- 신호 상태값 확인
|
|
|
|
### MMI 코드 조회
|
|
- MMI 코드 데이터베이스 검색
|
|
- 차량분류별 필터링
|
|
|
|
### UI/UX
|
|
- 반응형 디자인 (모바일 최적화)
|
|
- 다크모드 지원
|
|
- PWA 지원 (오프라인 사용 가능)
|
|
- 빠른 페이지 전환 (HTMX)
|
|
- 로그인 사용자 정보 표시
|
|
|
|
## 🏗️ 시스템 아키텍처
|
|
|
|
```
|
|
외부 클라이언트 (브라우저/PWA)
|
|
↓ HTTPS/HTTP
|
|
NPM 리버스 프록시 (Proxmox, 선택적)
|
|
↓ HTTP
|
|
M1T 서버 nginx (:80)
|
|
↓ Unix Socket
|
|
gunicorn (Tr_Code.sock)
|
|
↓
|
|
Flask App (app.py)
|
|
↓ localhost:8000
|
|
Supabase (Docker)
|
|
```
|
|
|
|
### 기술 스택
|
|
|
|
**백엔드**
|
|
- Flask 3.0.3 - 웹 프레임워크
|
|
- Gunicorn 23.0.0 - WSGI 서버
|
|
- httpx - 비동기 HTTP 클라이언트
|
|
|
|
**프론트엔드**
|
|
- HTMX - 동적 UI
|
|
- TailwindCSS - 스타일링
|
|
- Jinja2 템플릿
|
|
|
|
**데이터베이스**
|
|
- Supabase (PostgreSQL)
|
|
- PostgREST API
|
|
|
|
**인프라**
|
|
- nginx - 리버스 프록시
|
|
- systemd - 프로세스 관리
|
|
- Ubuntu 22.04 LTS
|
|
|
|
## 🚀 설치 및 배포
|
|
|
|
### 1. 시스템 요구사항
|
|
|
|
```bash
|
|
# OS
|
|
Ubuntu 22.04 LTS 이상
|
|
|
|
# Python
|
|
Python 3.10 이상
|
|
|
|
# 필수 패키지
|
|
sudo apt update
|
|
sudo apt install -y python3 python3-venv python3-pip nginx
|
|
```
|
|
|
|
### 2. 프로젝트 설치
|
|
|
|
```bash
|
|
# 프로젝트 클론 또는 복사
|
|
cd /home/ckh08045
|
|
git clone <repository> Tr_Code
|
|
cd Tr_Code
|
|
|
|
# 가상환경 생성
|
|
python3 -m venv .
|
|
|
|
# 가상환경 활성화
|
|
source bin/activate
|
|
|
|
# 의존성 설치
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
### 3. 환경 설정
|
|
|
|
#### 3.1 데이터베이스 스키마 생성
|
|
|
|
회원 관리 시스템을 사용하려면 먼저 데이터베이스 스키마를 생성해야 합니다:
|
|
|
|
```bash
|
|
# database_schema.sql 파일의 내용을 Supabase SQL 에디터에서 실행
|
|
# 부서, 사용자, 권한 테이블이 자동으로 생성됩니다
|
|
```
|
|
|
|
#### 3.2 `.env` 파일 생성
|
|
|
|
```bash
|
|
# env.example 파일을 .env로 복사
|
|
cp env.example .env
|
|
|
|
# SECRET_KEY 생성
|
|
python -c "import secrets; print(secrets.token_hex(32))"
|
|
|
|
# .env 파일 편집
|
|
nano .env
|
|
```
|
|
|
|
`.env` 파일 내용:
|
|
|
|
```bash
|
|
# Supabase 설정 (localhost - 같은 서버에서 실행 중)
|
|
SUPABASE_URL=http://localhost:8000
|
|
SUPABASE_ANON_KEY=your_anon_key_here
|
|
|
|
# Flask 세션 보안 키 (반드시 변경!)
|
|
SECRET_KEY=위에서-생성한-랜덤-키-입력
|
|
|
|
# Kong Basic Auth (선택사항)
|
|
SUPABASE_BASIC_USER=
|
|
SUPABASE_BASIC_PASSWORD=
|
|
|
|
# Flask 설정
|
|
PORT=5000
|
|
```
|
|
|
|
## 🔐 회원 인증 시스템
|
|
|
|
### 빠른 시작
|
|
|
|
회원 관리 및 인증 시스템 설정을 위한 문서:
|
|
|
|
📖 **[ENV_SETUP_GUIDE.md](ENV_SETUP_GUIDE.md)** - 환경 변수 설정 가이드
|
|
📖 **[AUTH_SETUP.md](AUTH_SETUP.md)** - 상세 인증 시스템 설정
|
|
📖 **[EMAIL_CODE_AUTH_GUIDE.md](EMAIL_CODE_AUTH_GUIDE.md)** - 이메일 코드 인증 가이드
|
|
📖 **[BIOMETRIC_AUTH_GUIDE.md](BIOMETRIC_AUTH_GUIDE.md)** - 생체인증 가이드
|
|
📖 **[AUTHENTICATION_SUMMARY.md](AUTHENTICATION_SUMMARY.md)** - 기술 문서
|
|
📖 **[DEPARTMENTS_API.md](DEPARTMENTS_API.md)** - 부서 API 문서
|
|
|
|
### 주요 기능
|
|
|
|
- ✅ **이메일 코드 인증** - 6자리 숫자 코드 입력 방식 (스팸/피싱 의심 방지)
|
|
- ✅ **생체인증** - WebAuthn/Credential Management API (지문, 얼굴 인식)
|
|
- ✅ **비밀번호 재설정** - 이메일 코드 인증 후 재설정
|
|
- ✅ **humetro.busan.kr 도메인만 가입 가능**
|
|
- ✅ 부서별 사용자 관리 (동적 부서 목록)
|
|
- ✅ 사번 기반 사용자 식별
|
|
- ✅ 부서별 권한 관리 (조회/수정 권한 제어 가능)
|
|
|
|
### Docker 기반 Supabase 환경
|
|
|
|
> ⚠️ **중요**: Docker 기반 Supabase는 대시보드 Authentication 설정이 제한적입니다.
|
|
> 이메일 도메인 검증은 **애플리케이션 레벨에서만** 처리됩니다.
|
|
|
|
### 3단계 설정
|
|
|
|
```bash
|
|
# 1. 데이터베이스 스키마 생성 (Supabase SQL 에디터)
|
|
# database_schema.sql 실행
|
|
|
|
# 2. .env 파일 설정
|
|
cp env.example .env
|
|
python -c "import secrets; print(secrets.token_hex(32))"
|
|
# 출력된 키를 .env의 SECRET_KEY에 설정
|
|
|
|
# 3. 서버 실행
|
|
python app.py
|
|
```
|
|
|
|
### 사용 방법
|
|
|
|
1. `http://localhost:5000` 접속 → 로그인 페이지
|
|
2. "회원가입" 클릭
|
|
3. 정보 입력 (humetro.busan.kr 이메일 사용)
|
|
4. 로그인
|
|
|
|
### 4. Systemd 서비스 설정
|
|
|
|
`/etc/systemd/system/Tr_Code.service`:
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Gunicorn instance to serve Tr_Code
|
|
After=network.target
|
|
|
|
[Service]
|
|
User=ckh08045
|
|
Group=ckh08045
|
|
WorkingDirectory=/home/ckh08045/Tr_Code
|
|
Environment="PATH=/home/ckh08045/Tr_Code/bin"
|
|
ExecStart=/home/ckh08045/Tr_Code/bin/gunicorn --workers 3 --bind unix:Tr_Code.sock -m 007 app:app
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
### 5. nginx 설정
|
|
|
|
`/etc/nginx/sites-available/tr_code`:
|
|
|
|
```nginx
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
|
|
client_max_body_size 10M;
|
|
|
|
location /static/ {
|
|
alias /home/ckh08045/Tr_Code/static/;
|
|
expires 30d;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
location / {
|
|
proxy_pass http://unix:/home/ckh08045/Tr_Code/Tr_Code.sock;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
|
|
proxy_connect_timeout 60s;
|
|
proxy_send_timeout 60s;
|
|
proxy_read_timeout 60s;
|
|
}
|
|
}
|
|
```
|
|
|
|
**nginx 활성화:**
|
|
|
|
```bash
|
|
# 심볼릭 링크 생성
|
|
sudo ln -sf /etc/nginx/sites-available/tr_code /etc/nginx/sites-enabled/
|
|
|
|
# 기본 사이트 비활성화
|
|
sudo rm -f /etc/nginx/sites-enabled/default
|
|
|
|
# nginx 사용자를 애플리케이션 그룹에 추가 (Unix 소켓 접근 권한)
|
|
sudo usermod -a -G ckh08045 www-data
|
|
|
|
# 설정 테스트
|
|
sudo nginx -t
|
|
|
|
# nginx 재시작
|
|
sudo systemctl restart nginx
|
|
```
|
|
|
|
### 6. 서비스 시작
|
|
|
|
```bash
|
|
# systemd 설정 리로드
|
|
sudo systemctl daemon-reload
|
|
|
|
# 서비스 활성화 (부팅 시 자동 시작)
|
|
sudo systemctl enable Tr_Code
|
|
|
|
# 서비스 시작
|
|
sudo systemctl start Tr_Code
|
|
|
|
# 상태 확인
|
|
sudo systemctl status Tr_Code
|
|
```
|
|
|
|
## ⚙️ 환경 설정
|
|
|
|
### 환경변수 설명
|
|
|
|
| 변수 | 설명 | 기본값 |
|
|
|------|------|--------|
|
|
| `SUPABASE_URL` | Supabase 서버 주소 | `http://localhost:8000` |
|
|
| `SUPABASE_ANON_KEY` | Supabase Anonymous Key | - |
|
|
| `SUPABASE_BASIC_USER` | Kong Basic Auth 사용자명 (선택) | - |
|
|
| `SUPABASE_BASIC_PASSWORD` | Kong Basic Auth 비밀번호 (선택) | - |
|
|
| `PORT` | Flask 개발 서버 포트 | `5000` |
|
|
|
|
### Supabase 연결
|
|
|
|
- **같은 서버**: `http://localhost:8000` 사용 (최적 성능)
|
|
- **다른 서버**: `http://ip:port` 형식으로 지정
|
|
- **Kong 프록시**: Basic Auth 정보 추가
|
|
|
|
## 🔧 서비스 관리
|
|
|
|
### 서비스 명령어
|
|
|
|
```bash
|
|
# 시작
|
|
sudo systemctl start Tr_Code
|
|
|
|
# 중지
|
|
sudo systemctl stop Tr_Code
|
|
|
|
# 재시작
|
|
sudo systemctl restart Tr_Code
|
|
|
|
# 상태 확인
|
|
sudo systemctl status Tr_Code
|
|
|
|
# 로그 확인
|
|
sudo journalctl -u Tr_Code -f
|
|
|
|
# 부팅 시 자동 시작 활성화
|
|
sudo systemctl enable Tr_Code
|
|
|
|
# 부팅 시 자동 시작 비활성화
|
|
sudo systemctl disable Tr_Code
|
|
```
|
|
|
|
### nginx 명령어
|
|
|
|
```bash
|
|
# 설정 테스트
|
|
sudo nginx -t
|
|
|
|
# 재시작
|
|
sudo systemctl restart nginx
|
|
|
|
# 리로드 (무중단)
|
|
sudo systemctl reload nginx
|
|
|
|
# 에러 로그 확인
|
|
sudo tail -f /var/log/nginx/error.log
|
|
|
|
# 액세스 로그 확인
|
|
sudo tail -f /var/log/nginx/access.log
|
|
```
|
|
|
|
## 💻 개발 환경
|
|
|
|
### 로컬 개발 서버
|
|
|
|
```bash
|
|
# 가상환경 활성화
|
|
source bin/activate
|
|
|
|
# 개발 모드로 실행 (디버그 활성화)
|
|
python app.py
|
|
|
|
# 접속
|
|
# http://localhost:5000
|
|
```
|
|
|
|
### 코드 수정 후
|
|
|
|
```bash
|
|
# 서비스 재시작
|
|
sudo systemctl restart Tr_Code
|
|
```
|
|
|
|
## 📡 API 엔드포인트
|
|
|
|
### 헬스체크
|
|
- `GET /health` - 애플리케이션 상태
|
|
- `GET /sb/health` - Supabase 연결 상태
|
|
|
|
### 고장코드
|
|
- `GET /sb` - 메인 페이지
|
|
- `GET /sb/faults/list` - 고장코드 목록
|
|
- `GET /sb/faults/<code>` - 고장코드 상세
|
|
|
|
### TCMS 신호
|
|
- `GET /sb/signals/list` - 신호 목록
|
|
- `GET /sb/signals/<id>` - 신호 상세
|
|
|
|
### MMI 코드
|
|
- `GET /sb?section=mmicode` - MMI 코드 목록
|
|
|
|
### 디버그
|
|
- `GET /sb/signals/test` - Signals 테이블 테스트
|
|
- `GET /sb/signals/debug` - 상세 디버그 정보
|
|
|
|
## 🐛 문제 해결
|
|
|
|
### 서비스가 시작되지 않을 때
|
|
|
|
```bash
|
|
# 로그 확인
|
|
sudo journalctl -u Tr_Code -n 50
|
|
|
|
# 가상환경 경로 확인
|
|
ls -la /home/ckh08045/Tr_Code/bin/gunicorn
|
|
|
|
# 권한 확인
|
|
ls -la /home/ckh08045/Tr_Code/
|
|
```
|
|
|
|
### nginx Permission Denied
|
|
|
|
```bash
|
|
# www-data 사용자가 소켓에 접근할 수 있는지 확인
|
|
sudo usermod -a -G ckh08045 www-data
|
|
sudo systemctl restart nginx
|
|
```
|
|
|
|
### Supabase 연결 실패
|
|
|
|
```bash
|
|
# Supabase 컨테이너 상태 확인
|
|
docker ps | grep supabase
|
|
|
|
# 포트 확인
|
|
sudo netstat -tlnp | grep 8000
|
|
|
|
# .env 파일 확인
|
|
cat .env
|
|
|
|
# 연결 테스트
|
|
curl http://localhost:8000/rest/v1/
|
|
```
|
|
|
|
### 502 Bad Gateway
|
|
|
|
```bash
|
|
# gunicorn 서비스 상태 확인
|
|
sudo systemctl status Tr_Code
|
|
|
|
# 소켓 파일 확인
|
|
ls -la /home/ckh08045/Tr_Code/Tr_Code.sock
|
|
|
|
# nginx 에러 로그
|
|
sudo tail -f /var/log/nginx/error.log
|
|
```
|
|
|
|
## 📱 PWA 지원
|
|
|
|
PWA(Progressive Web App)로 변환하여 모바일 앱처럼 사용할 수 있습니다.
|
|
|
|
자세한 내용은 [PWA_README.md](PWA_README.md)를 참조하세요.
|
|
|
|
## 📄 라이선스
|
|
|
|
이 프로젝트는 내부 사용을 위한 것입니다.
|
|
|
|
## 🤝 기여
|
|
|
|
문제가 발생하거나 개선 사항이 있으면 이슈를 등록해주세요.
|
|
|
|
---
|
|
|
|
**문의**: 시스템 관리자
|
|
|
|
|