# 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 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/` - 고장코드 상세 ### TCMS 신호 - `GET /sb/signals/list` - 신호 목록 - `GET /sb/signals/` - 신호 상세 ### 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)를 참조하세요. ## 📄 라이선스 이 프로젝트는 내부 사용을 위한 것입니다. ## 🤝 기여 문제가 발생하거나 개선 사항이 있으면 이슈를 등록해주세요. --- **문의**: 시스템 관리자