- 공통 유틸리티 추출 (common/utils.js, common/base-state.js) - TBM 모바일 인라인 JS/CSS 외부 파일로 분리 (tbm-mobile.js, tbm-mobile.css) - 미사용 코드 삭제 (index.js, work-report-*.js 등 5개 파일) - TBM/작업보고 state.js, utils.js를 공통 모듈 기반으로 전환 - 작업보고서 SSO 인증 호환 수정 (token/user 함수) - tbmModel.js: incomplete-reports 쿼리에서 users→sso_users 조인 수정, leader_name 조인 추가 - docker-compose.yml: system1-web 볼륨 마운트 추가 - 모바일 인계(handover) 기능 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13 KiB
13 KiB
TK 공장관리 3-System 분리 및 통합 - 진행 상황
최종 업데이트: 2026-02-09
전체 목표
TK-FB-Project(공장관리+신고)와 M-Project(부적합관리)를 3개 독립 시스템으로 분리하고 SSO + 데이터 연동으로 통합.
| 시스템 | 설명 | 기반 코드 |
|---|---|---|
| System 1 - 공장관리 | TK-FB에서 신고 기능 제거 | TK-FB-Project |
| System 2 - 신고 | TK-FB에서 추출한 독립 서비스 | TK-FB-Project (workIssue 코드) |
| System 3 - 부적합관리 (TKQC) | M-Project 기반 | M-Project |
배포 대상: Synology DS923+ NAS (192.168.0.3)
현재 NAS 운영 상태
TK-FB (공장관리+신고 - 기존 시스템, 운영 중)
| 컨테이너 | 상태 | 포트 |
|---|---|---|
| tkfb_web | Up | - |
| tkfb_api | Up (healthy) | - |
| tkfb_fastapi | Up | - |
| tkfb_db (MariaDB) | Up (healthy) | - |
| tkfb_redis | Up | - |
| tkfb_phpmyadmin | Up | - |
| tkfb_cloudflared | Up | - |
- 도메인:
tkfb.technicalkorea.net(Cloudflare Tunnel) - 위치:
/volume1/Technicalkorea Document/tkfb-package/
TKQC (부적합관리 - 신규 배포 완료)
| 컨테이너 | 상태 | 포트 |
|---|---|---|
| tkqc-db (PostgreSQL 15) | Up (healthy) | 16432 |
| tkqc-backend (FastAPI) | Up | 16000 |
| tkqc-nginx | Up | 16080 |
- 도메인:
tkqc.technicalkorea.net(Cloudflare Tunnel) - 위치:
/volume1/docker/tkqc/tkqc-package/ - cloudflared가 tkfb_network + tkqc-network 양쪽 연결됨
단계별 진행 상황
Phase 0: M-Project(TKQC) NAS 배포 ✅ 완료
- M-Project 배포 패키지 생성 (deploy/package.sh)
- NAS로 패키지 전송 및 설치
- Docker 컨테이너 빌드 및 실행 (tkqc-db, tkqc-backend, tkqc-nginx)
- PostgreSQL 마이그레이션 실행 (001~020 SQL)
- nginx.conf 수정 (Docker 내부 IP 허용, uploads 프록시)
- Cloudflare Tunnel에
tkqc.technicalkorea.net추가 - cloudflared를 tkqc-network에 연결
- 컨테이너 이름 m-project → tkqc로 리네임
- 헬스체크 확인 (API: healthy, Web: 200)
- Cloudflare 대시보드에서 서비스 URL 변경 필요
- 변경:
http://m-project-nginx:80→http://tkqc-nginx:80 - (사용자가 직접 Cloudflare 대시보드에서 수정)
- 변경:
Phase 1: 준비 - 로컬 코드 구조 생성 ✅ 완료
tk-factory-services/디렉토리 구조 생성- 통합
docker-compose.yml작성 (13개 서비스, 포트 30000~30880) .env.example작성
Phase 2: SSO 인증 서비스 - 로컬 코드 작성 ✅ 완료
sso-auth-service/코드 작성index.js- Express 서버routes/authRoutes.js- 인증 라우트controllers/authController.js- 로그인/검증/리프레시/유저 CRUDmodels/userModel.js- MariaDB 유저 모델Dockerfile,package.json
- bcrypt + pbkdf2_sha256 이중 비밀번호 해시 지원
- JWT 기반 인증 (SSO_JWT_SECRET 공유)
- 실제 테스트 미완료 (NAS 배포 전)
- sso_users 테이블 생성 및 기존 유저 마이그레이션 미완료
Phase 3: 시스템별 코드 분리 - 로컬 코드 작성 ✅ 완료
System 1 - 공장관리
- TK-FB-Project에서 복사 (api, web, fastapi-bridge)
config/routes.js에서 workIssue 라우트 제거- auth 미들웨어 SSO JWT 시크릿 연동 (백엔드: JWT_SECRET=SSO_JWT_SECRET 이미 설정)
- 프론트엔드 토큰 키 통일 (
token/user→sso_token/sso_user, 52개 파일 변경) - SSO 쿠키 기반 인증 통합 (api-base.js, app-init.js, auth-check.js, auth.js)
window.getSSOToken(),window.getSSOUser(),window.getLoginUrl()글로벌 함수- 쿠키
sso_token우선 → localStoragesso_token폴백
- nginx.conf 생성 (API, uploads, FastAPI 프록시)
- 신고 관련 프론트엔드 페이지 → System 2로 서브도메인 리다이렉트
issue-report.html,issue-detail.html,report-status.html→ 동적 서브도메인 리다이렉트sidebar-nav.html크로스시스템 링크 →data-system속성 + JS 동적 해석
- 로그인 플로우: 인증 없으면 중앙 로그인 (
tkfb.technicalkorea.net/login)으로 리다이렉트 - 실제 테스트 미완료
System 2 - 신고
- TK-FB에서 workIssue 관련 코드 추출
workIssueModel.js,workIssueController.js,workIssueRoutes.jsmProjectService.js(baseUrl → system3-api:8000으로 변경)imageUploadService.js,dateUtils.js,logger.js,errors.js
- 독립 Express 서버 구성 (index.js, package.json, Dockerfile)
- 프론트엔드 페이지 복사 (issue-report, issue-detail, report-status)
- auth 미들웨어 SSO JWT 시크릿 연동 (백엔드: JWT_SECRET=SSO_JWT_SECRET 이미 설정)
- 프론트엔드 인프라 구축:
api-base.js,app-init.js신규 생성 - SSO 쿠키 기반 인증 통합 (쿠키 우선, localStorage 폴백, 중앙 로그인 리다이렉트)
- 인라인 JS 토큰 읽기 →
window.getSSOToken()폴백 패턴 적용 (28곳) - M-Project(TKQC) 연동 실제 테스트 미완료
- 실제 테스트 미완료
System 3 - 부적합관리 (TKQC)
- M-Project에서 복사 (api, web)
auth_service.py→ bcrypt + pbkdf2 이중 지원 코드 추가requirements.txt에 bcrypt 추가- SSO JWT 연동:
verify_token()전체 payload 반환, DB에 없는 SSO 유저 임시 객체 생성 - SSO 쿠키 기반 인증 통합 (api.js, auth-manager.js, app.js, common-header.js)
_cookieGet('sso_token')우선 → localStorage 폴백- 인증 실패 시 중앙 로그인 리다이렉트
- 인라인 JS
localStorage.getItem('access_token')→TokenManager.getToken()일괄 치환 (9개 HTML, 81곳) - SSO JWT 시크릿 연동 실제 테스트 미완료
Phase 4: Gateway + 서브도메인 라우팅 ✅ 코드 완료
아키텍처 변경: Path-based(
/factory/,/report/,/nc/) → 서브도메인 기반 라우팅으로 전환.이유: 프론트엔드 JS가 root-relative URL (
/api/...,/pages/...)을 사용하므로 경로 기반 라우팅이 근본적으로 불가능.해결: 각 시스템에 독립 서브도메인을 부여하고, SSO 쿠키(
domain=.technicalkorea.net)로 인증 공유.
gateway/nginx.conf- 서브도메인 기반 라우팅tkfb.technicalkorea.net→ Gateway (포털/로그인) + System 1 프록시tkreport.technicalkorea.net→ System 2 (Cloudflare Tunnel 직접)tkqc.technicalkorea.net→ System 3 (Cloudflare Tunnel 직접)
gateway/html/portal.html- 서브도메인 기반 시스템 카드 링크gateway/html/login.html- SSO 쿠키 설정 (domain=.technicalkorea.net, 7일 만료)- 로그인 성공 → 쿠키 + localStorage 이중 저장,
?redirect=파라미터 지원
- 로그인 성공 → 쿠키 + localStorage 이중 저장,
gateway/html/shared/nav-header.js- SSOAuth 글로벌 객체 (쿠키 우선)gateway/Dockerfilesystem1-factory/web/nginx.conf신규 생성 (API/uploads/FastAPI 프록시)docker-compose.yml에 cloudflared 서비스 추가- Cloudflare Tunnel 서브도메인 설정 (사용자 대시보드 작업)
- 실제 배포 및 테스트 미완료
Phase 5: 마이그레이션 스크립트 - 로컬 코드 작성 ✅ 완료
scripts/migrate-users.sql- SSO 통합 유저 테이블 생성 + 데이터 이전scripts/backup.sh- 전체 백업 스크립트scripts/deploy.sh- 배포 스크립트scripts/health-check.sh- 헬스체크 스크립트- 실제 실행 미완료
Phase 6: NAS 통합 배포 ❌ 미착수
- 전체 백업 (MariaDB, PostgreSQL, uploads, git)
- tk-factory-services를 NAS로 전송
- .env 파일 생성 (NAS 기존 DB 패스워드 등 수집)
- 기존 TK-FB 중지 + TKQC 중지
- 통합 docker-compose.yml로 전체 서비스 기동
- SSO 유저 마이그레이션 실행
- 전체 서비스 헬스체크
- Cloudflare Tunnel 서브도메인 설정 업데이트:
tkfb.technicalkorea.net→http://tk-gateway:80tkreport.technicalkorea.net→http://tk-system2-web:80tkqc.technicalkorea.net→http://tk-system3-web:80
Phase 7: 테스트 및 Go-Live ❌ 미착수
- SSO 로그인 → 3개 시스템 간 이동 테스트 (재로그인 없이)
- 신고 생성 → 부적합 자동 생성 연동 테스트
- 사진 업로드 테스트
- 알림 기능 테스트
- 기존 데이터 정합성 확인
- 프로덕션 Go-Live
완료율 요약
| 단계 | 상태 | 완료도 |
|---|---|---|
| Phase 0: TKQC NAS 배포 | ✅ 거의 완료 | 95% (CF 대시보드 URL 변경만 남음) |
| Phase 1: 디렉토리 구조 | ✅ 완료 | 100% |
| Phase 2: SSO 코드 작성 | ✅ 코드 완료 | 70% (코드만 완료, 테스트/배포 미완) |
| Phase 3: 시스템 분리 + SSO 쿠키 통합 | ✅ 코드 완료 | 80% (코드+프론트엔드 SSO 완료, 실제 테스트 미완) |
| Phase 4: Gateway + 서브도메인 라우팅 | ✅ 코드 완료 | 80% (코드 완료, CF Tunnel 설정/테스트 미완) |
| Phase 5: 스크립트 | ✅ 코드 완료 | 50% (코드만 완료, 실행 미완) |
| Phase 6: NAS 통합 배포 | ❌ 미착수 | 0% |
| Phase 7: 테스트/Go-Live | ❌ 미착수 | 0% |
전체 진행률: 약 55% (코드 작성 + SSO 프론트엔드 통합 완료, NAS 배포/테스트 남음)
주요 파일 위치
로컬 (Mac)
- 통합 프로젝트:
/Users/hyungiahn/Documents/code/tk-factory-services/ - TK-FB 원본:
/Users/hyungiahn/Documents/code/TK-FB-Project/ - M-Project 원본:
/Users/hyungiahn/Documents/code/M-Project/ - M-Project 배포 도구:
/Users/hyungiahn/Documents/code/M-Project/deploy/
NAS (192.168.0.3)
- TK-FB 운영:
/volume1/Technicalkorea Document/tkfb-package/ - TKQC 운영:
/volume1/docker/tkqc/tkqc-package/ - SSH:
hyungi/fukdon-riwbaq-fiQfy2
포트 계획 (통합 배포 시)
| 현재 포트 | 통합 후 포트 | 서비스 |
|---|---|---|
| - | 30000 | Gateway Nginx (통합 포털) |
| tkfb API | 30005 | System 1 API |
| tkfb FastAPI | 30008 | System 1 FastAPI Bridge |
| - | 30050 | SSO Auth |
| tkfb Web | 30080 | System 1 Web |
| - | 30105 | System 2 API |
| - | 30180 | System 2 Web |
| 16000 → 30200 | 30200 | System 3 API |
| 16080 → 30280 | 30280 | System 3 Web |
| tkfb MariaDB | 30306 | MariaDB (공유) |
| 16432 → 30432 | 30432 | PostgreSQL |
| tkfb phpMyAdmin | 30880 | phpMyAdmin |
다음에 할 일 (우선순위)
- NAS 접속 확인 (현재 LAN/Tailscale 모두 타임아웃)
- .env 파일 생성 - NAS에서 기존 DB 패스워드 등 수집
- Phase 6: NAS 통합 배포
- 전체 백업 → 프로젝트 전송 → docker-compose up
- Cloudflare Tunnel 서브도메인 설정 (사용자 대시보드 작업)
tkfb.technicalkorea.net→http://tk-gateway:80tkreport.technicalkorea.net→http://tk-system2-web:80tkqc.technicalkorea.net→http://tk-system3-web:80
- Phase 7: 전체 SSO 로그인/시스템 간 이동 테스트
아키텍처 변경 이력
2026-02-09: Path-based → 서브도메인 기반 라우팅
문제: Gateway에서 /factory/, /report/, /nc/ 경로 기반 라우팅 시, 프론트엔드 JS가 root-relative URL (fetch('/api/...'), <a href="/pages/...">)을 사용하여 경로 프리픽스 없이 요청 → 라우팅 불가.
해결: 서브도메인 기반 라우팅 + 쿠키 기반 SSO
| 서브도메인 | Cloudflare Tunnel 대상 | 시스템 |
|---|---|---|
tkfb.technicalkorea.net |
http://tk-gateway:80 |
포털 + System 1 (프록시) |
tkreport.technicalkorea.net |
http://tk-system2-web:80 |
System 2 |
tkqc.technicalkorea.net |
http://tk-system3-web:80 |
System 3 |
SSO 쿠키 전략: sso_token, sso_user 쿠키를 domain=.technicalkorea.net으로 설정하여 서브도메인 간 공유. localStorage는 폴백용으로 유지 (개발 환경 및 하위호환).
해결했던 이슈 (참고)
| 이슈 | 해결 방법 |
|---|---|
| nginx uploads 볼륨 read-only 에러 | nginx에서 uploads 볼륨 제거, backend 프록시로 변경 |
users.department 컬럼 누락 |
마이그레이션 수동 실행 (ALTER TABLE) |
| nginx 403 Forbidden (Docker IP 차단) | allow 172.16.0.0/12, allow 10.0.0.0/8 추가 |
| SCP subsystem 실패 | scp -O (레거시 프로토콜) 사용 |
| sudo 패스워드 파이프 실패 (for 루프) | SQL 파일 합쳐서 한번에 실행 |
| 네트워크 충돌 (리네임 시) | cloudflared 연결 해제 후 네트워크 삭제 |
| 새 볼륨 비어있음 (리네임 후) | 마이그레이션 재실행 |