29 Commits

Author SHA1 Message Date
Hyungi Ahn
0de9d5bb48 feat(sso): 인앱 브라우저 SSO 토큰 릴레이 — 카톡 WebView 쿠키 미공유 해결
카카오톡 인앱 WebView는 서브도메인 간 쿠키를 공유하지 않아
tkds에서 로그인 후 tkfb로 리다이렉트 시 인증이 풀리는 문제.

- sso-relay.js: URL hash의 _sso= 토큰을 로컬 쿠키+localStorage로 설정
- gateway dashboard: 로그인 후 redirect URL에 #_sso=<token> 추가
- 전 서비스 HTML: core JS 직전에 sso-relay.js 로드 (81개 파일)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:44:02 +09:00
Hyungi Ahn
46a1f8310d fix(cache): tkds→tkfb 변경 후 전 서비스 캐시 버스팅 갱신
tkfb-core.js v=2026040104, tksupport/tksafety/tkpurchase/tkuser-core.js,
system2 api-base.js, system3 app.js 캐시 버스팅 일괄 갱신.
브라우저 캐시에 남은 구버전(tkds 리다이렉트) 강제 갱신.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:31:14 +09:00
Hyungi Ahn
28a5924e76 fix: tkds.technicalkorea.net → tkfb.technicalkorea.net 일괄 전환
tkds 도메인 폐기. 로그인 리다이렉트, CORS, 알림벨 등 16개 파일에서
tkds → tkfb로 변경. tkds로 접속 시 gateway에 /pages/ 경로가 없어
404 발생하던 문제 해결.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:26:32 +09:00
Hyungi Ahn
48e3b58865 fix(cors): 인앱 브라우저 CORS 차단 해결 — 카톡 WebView 대응
- new Error() → cb(null, false): 500 에러 대신 CORS 헤더 미포함으로 거부
- *.technicalkorea.net 와일드카드 추가: 서브도메인 간 통신 보장

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:15:49 +09:00
Hyungi Ahn
943ed63d77 feat(sprint-002): tkpurchase+tksafety requirePage 전환 완료
- tkpurchase scheduleRoutes: requireAdmin → requirePage('purchasing_schedule')
- tksafety checklistRoutes: requireAdmin → requirePage('safety_checklist')
- tksafety riskRoutes: requireAdmin → requirePage('safety_risk_assessment')
- tksafety visitRequestRoutes: requireAdmin → requirePage('safety_visit_management')
- visitRequestRoutes import 구문 에러 수정

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 07:59:45 +09:00
Hyungi Ahn
3d314c1fb4 fix(infra): nginx 동적 DNS resolve + Docker 헬스체크 추가
컨테이너 재생성 시 502 Bad Gateway 방지:
- 모든 nginx proxy_pass를 set $upstream 변수 방식으로 전환 (9개 파일, 24개 location)
- resolver 127.0.0.11 valid=10s ipv6=off 통합 선언
- ai-api location의 개별 resolver 8.8.8.8 제거 (server-level로 통합)
- 10개 API 서비스에 healthcheck 추가 (Node: wget, Python: urllib)
- 모든 web/gateway depends_on을 condition: service_healthy로 강화

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:53:34 +09:00
Hyungi Ahn
0c149673fb refactor: shared 모듈 추출 Phase 1~4 (notifyHelper, errors, logger, auth, dbPool)
Phase 1: notifyHelper.js → shared/utils/ (4개 서비스 중복 제거)
Phase 2: auth.js → shared/middleware/ (system1/system2 통합)
Phase 3: errors.js + logger.js → shared/utils/ (system1/system2 통합)
Phase 4: DB pool → shared/config/database.js (Group B 4개 서비스 통합)

- Docker 빌드 컨텍스트를 루트로 변경 (6개 API 서비스)
- 기존 파일은 re-export 패턴으로 consumer 변경 0개 유지
- .dockerignore 추가로 빌드 최적화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 19:07:22 +09:00
Hyungi Ahn
84cf222b81 feat(tkuser): 알림 시스템 이관 system1-factory → tkuser
- Phase 1: tkuser에 알림 CRUD, Push/ntfy 발송, 내부 알림 API 추가
- Phase 2: notifyHelper URL을 tkuser-api:3000으로 전환 (system2, tkpurchase, tksafety, system1)
- Phase 3: notification-bell.js API 도메인 tkuser로 변경 + 캐시 버스팅 v=4
- Phase 4: system1에서 알림 코드 제거 (routes, controllers, models, utils)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 15:56:41 +09:00
Hyungi Ahn
17f7c6f3b0 fix(tksafety): uploads/risk 디렉토리 생성을 lazy로 변경 — 볼륨 권한 충돌 해결
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 08:07:13 +09:00
Hyungi Ahn
e9b69ed87b feat(tksafety): 위험성평가 모듈 Phase 1 구현 — DB·API·Excel·프론트엔드
5개 테이블(risk_projects/processes/items/mitigations/templates) + 마스터 시딩,
프로젝트·항목·감소대책 CRUD API, ExcelJS 평가표 내보내기,
프로젝트 목록·평가 수행 페이지, 사진 업로드(multer), 네비게이션·CSS 추가.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 08:05:19 +09:00
Hyungi Ahn
fe5f7cd155 feat(ux): 전체 시스템 모바일 UX 개선 — 햄버거메뉴·필터반응형·터치타겟·iOS줌방지
7개 시스템(tkpurchase/tksafety/tksupport/tkuser/system1/system2/system3)의
모바일 사용성 일괄 개선. system1(tkfb)의 모바일 메뉴 패턴을 3개 신규 시스템에 적용.

주요 변경:
- 모바일 햄버거 메뉴: tkpurchase/tksafety/tksupport에 toggleMobileMenu+overlay 추가
- 필터 반응형: 768px 이하 2열 그리드 전환 (filter-bar/filter-actions 클래스)
- 터치 타겟 44px: 테이블 액션 버튼 36px+gap, tksafety ±버튼 w-11
- iOS 줌 방지: input/select/textarea font-size 16px
- tkuser: 탭 가로스크롤+fade힌트, 사이드바·grid·드롭다운 반응형
- system1: 대시보드 인라인 width 제거, 이동설비 그리드 1열
- system2: 사진그리드 4열, 유형버튼 2열 (480px 이하)
- system3: 카드 내 액션 버튼 stopPropagation 추가
- 캐시 무효화: 전체 HTML ?v=2026031401

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 17:57:47 +09:00
Hyungi Ahn
2d8ac92404 fix(ux): 데스크탑 UX 일괄 개선 — fade-in·ESC·스크롤잠금·z-index·sticky
A1: fade-in querySelectorAll 전환 (5개 core.js) — 복수 요소 모두 표시
A2: 모달 ESC 키 닫기 (5개 core.js)
A3: 모바일 메뉴 body 스크롤 잠금 (tkfb-core.js)
A4: Gateway 대시보드 max-width 800→1080px
B1: 모달 z-index 50→60 — 헤더 위에 표시 (4개 CSS)
B3: 테이블 sticky header (tkfb.css, tkpurchase.css)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 09:51:40 +09:00
Hyungi Ahn
1abdb92a71 fix(tksafety): 작업별 항목 표시 안 되는 버그 — check_type 'task' vs 'work_type' 불일치 수정
DB에 저장된 check_type='task'를 프론트에서 'work_type'으로 필터링하여 매칭 0건.
HTML option value와 JS 필터를 모두 'task'로 통일.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 21:13:20 +09:00
Hyungi Ahn
07aac305d6 feat(tksafety): 체크리스트 작업별 항목에 tkuser 작업(task) 참조 연동
- getAllChecks: tasks/work_types/weather_conditions JOIN + 프론트엔드 필드명 alias
- createCheck/updateCheck: item_type→check_type 등 프론트-DB 필드 매핑
- 모달에 작업(task) 드롭다운 추가, 공정 선택 시 동적 로드
- renderWorktypeItems: work_type → task 2단 그룹핑
- openEditItem: async/await로 task 목록 로드 후 값 설정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 21:07:29 +09:00
Hyungi Ahn
3e50639914 feat(training): 안전교육 실시 페이지 수정/삭제 기능 추가
대기 목록·완료 이력 양쪽에 수정/삭제 버튼 추가.
교육 기록 삭제 시 트랜잭션으로 출입 신청 상태를 approved로 복원.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 20:31:29 +09:00
Hyungi Ahn
12367dd3a1 fix(security): 전체 서비스 보안 점검 — XSS·인가·토큰·헤더·에러마스킹 일괄 수정
Phase 1 CRITICAL XSS:
- marked.parse() → DOMPurify.sanitize() (system3 ai-assistant, issues-management)
- toast innerHTML에 escapeHtml 적용 (system1 api-base, system3 common-header)
- onclick 핸들러 → data 속성 + addEventListener (system2 issue-detail)

Phase 2 HIGH 인가:
- getUserBalance 본인확인 추가 (tksupport vacationController)

Phase 3 HIGH 토큰+CSP:
- localStorage 토큰 저장 제거 — 쿠키 전용 (7개 서비스)
- unsafe-eval CSP 제거 (system1 security.js)

Phase 4 MEDIUM:
- nginx 보안 헤더 추가 (8개 서비스)
- 500 에러 메시지 마스킹 (5개 API)
- path traversal 방지 (system3 file_service.py)
- cookie fallback 데드코드 제거 (4개 auth.js)
- /login/form rate limiting 추가 (sso-auth)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 19:50:00 +09:00
Hyungi Ahn
7161351607 refactor(gateway): gateway↔system1 분리 — gateway=문짝, system1-web=독립
gateway에서 system1 프록시 제거, 대시보드+로그인+공유JS만 담당.
system1-web에 /auth/, /ai-api/ 프록시 이관. tkds-web 제거(gateway 흡수).
notification-bell URL tkfb→tkds, system3 로그인 URL tkds/dashboard로 변경.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 19:19:45 +09:00
Hyungi Ahn
f4999df334 feat(tkds): 독립 대시보드 서비스 분리 (tkds.technicalkorea.net)
대시보드를 gateway(tkfb)에서 분리하여 독립 서비스 tkds로 이동.
- tkds/web: nginx + dashboard.html 신규 서비스 (port 30780)
- gateway: /login 복원, /dashboard → tkds 301 리다이렉트
- 전체 시스템 getLoginUrl() → tkds.technicalkorea.net/dashboard로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 17:38:53 +09:00
Hyungi Ahn
b1154a8bc7 feat(notifications): 알림 유형 개선 - 카테고리 그룹화 + 구매팀 세분화
- equipment/maintenance 삭제, partner_work/day_labor 신규 추가
- 알림 수신자 관리 UI: 카테고리별 그룹 렌더링 (생산/안전/구매/시스템)
- tkpurchase 컨트롤러 알림 타입 변경
- notification-bell 라벨 및 notifications.html 아이콘 업데이트
- 전 서비스 cache busting 갱신

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:29:29 +09:00
Hyungi Ahn
7fd646e9ba feat: 실시간 알림 시스템 (Web Push + 알림 벨 + 서비스간 알림 연동)
- Phase 1: 모든 서비스 헤더에 알림 벨 UI 추가 (notification-bell.js)
- Phase 2: VAPID Web Push 구독/전송 (push-sw.js, pushSubscription API)
- Phase 3: 내부 알림 API + notifyHelper로 서비스간 알림 연동
  - tksafety: 출입 승인/반려, 안전교육 완료, 방문자 체크인
  - tkpurchase: 일용공 신청, 작업보고서 제출
  - system2-report: 신고 접수/확인/처리완료
- Phase 4: 30일 이상 알림 자동 정리 cron, Redis 캐싱
- CORS에 tkuser/tkpurchase/tksafety 서브도메인 추가
- HTML cache busting 버전 갱신

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:01:44 +09:00
Hyungi Ahn
1ad82fd52c fix(tksafety): UNION ALL collation 불일치 해결 (utf8mb4_general_ci/unicode_ci)
대시보드 UNION 쿼리에서 테이블 간 collation 불일치로 500 에러 발생.
unicode_ci 테이블 컬럼에 COLLATE utf8mb4_general_ci 명시하여 해결.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:58:28 +09:00
Hyungi Ahn
2fc4179052 fix(tksafety): DB 스키마 불일치로 인한 API 500 에러 수정
- departments.name → department_name (3곳)
- users → sso_users 테이블 참조 수정 (7곳)
- tbm_sessions.start_time → created_at (존재하지 않는 컬럼)
- tbm_team_assignments JOIN: ta.user_id → ta.worker_id
- workers leader JOIN: leader.worker_id → leader.user_id
- tbm_weather_conditions → weather_conditions 테이블명 수정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:51:06 +09:00
Hyungi Ahn
03119a0849 fix(tksafety): Dockerfile *.html 와일드카드로 변경하여 HTML 404 해결
개별 COPY 대신 와일드카드 사용으로 모든 HTML 파일 nginx에 포함

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:36:34 +09:00
Hyungi Ahn
6a20056e05 feat(tksafety): 통합 출입신고 관리 시스템 구현
- DB 마이그레이션: request_type, visitor_name, department_id, check_in/out_time 컬럼 + status ENUM 확장
- 4소스 UNION 대시보드: 방문(외부/내부) + TBM + 협력업체 통합 조회
- 체크인/체크아웃 API + 내부 출입 신고(승인 불필요) 지원
- 통합 출입 현황판 페이지 신규 (entry-dashboard.html)
- 출입 신청/관리 페이지에 유형 필터 + 체크인/아웃 버튼 추가
- safety_entry_dashboard 권한 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:24:13 +09:00
Hyungi Ahn
e2def8ab14 feat(tksafety): 테마 색상 주황→파랑 변경 (tkfb와 시각적 구분)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:43:49 +09:00
Hyungi Ahn
9fda89a374 feat: 안전 코드 tksafety 이관 + 사용자 관리 정리 + UI Tailwind 전환
Phase 1: tksafety에 출입신청/체크리스트 API·웹 추가, tkfb 안전 코드 삭제
Phase 2: 사용자 관리 페이지 삭제, API 축소, 알림 수신자 tkuser 이관
Phase 3: tkuser 권한 페이지 정의 업데이트
Phase 4: 전체 34개 페이지 Tailwind CSS + tkfb-core.js 전환,
         미사용 CSS 20개·인프라 JS 10개·템플릿·컴포넌트 삭제

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:46:22 +09:00
Hyungi Ahn
1006e8479e fix: 로그아웃 후 자동 재로그인 버그 수정
쿠키를 단일 진실 출처로 만들어 서브도메인 간 로그아웃 불일치 해결:
- login.html: logout=1 파라미터 시 localStorage+쿠키 전부 정리 후 토큰 체크 스킵
- 각 시스템 logout 함수에 &logout=1 추가 (6개 파일)
- 각 시스템 initAuth에 쿠키 우선 검증 추가 (7개 파일)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:00:19 +09:00
Hyungi Ahn
efc3c14db5 fix: 배포 후 버그 수정 — 테이블명/컬럼명 불일치, navbar active, API 검증 강화, 대시보드 통계 라우트 추가
- checkinModel: partner_checkins → partner_work_checkins, countActive() 추가
- workReportModel: partner_work_reports → daily_work_reports
- partner-portal: check_out_at/check_in_at → check_out_time/check_in_time
- checkinModel findTodayByCompany: LEFT JOIN has_work_report
- tkpurchase-core/tksafety-core: navbar match '' 제거
- checkinController: checkOut에 업무현황 검증, stats() 추가
- workReportController: checkin_id 필수 + schedule 일치 검증
- checkinRoutes: GET / 대시보드 통계 라우트 추가
- nginx.conf: visit.html → tksafety 리다이렉트
- migration-purchase-safety.sql: DDL 동기화
- migration-purchase-safety-patch.sql: 신규 패치

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 07:22:25 +09:00
Hyungi Ahn
b800792152 feat: 구매/안전 시스템 전면 개편 — tkpurchase 개편 + tksafety 신규 + 권한 보강
Phase 1: tkuser 협력업체 CRUD 이관 (읽기전용 → 전체 CRUD)
Phase 2: tkpurchase 개편 — 일용공 신청/확정, 작업일정, 업무현황, 계정관리, 협력업체 포털
Phase 3: tksafety 신규 시스템 — 방문관리 + 안전교육 신고
Phase 4: SSO 인증 보강 (partner_company_id JWT, 만료일 체크), 권한 테이블 기반 접근 제어

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:42:59 +09:00