- admin 계정 전용 테스트 금지 (권한 미들웨어 스킵 문제) - workers/sso_users department_id 불일치 주의 - const vs function 전역 스코프 충돌 - 캐시 버스팅 누락 방지 - nginx 프록시 경로 우선순위 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
5.3 KiB
Markdown
83 lines
5.3 KiB
Markdown
# CLAUDE.md — TK Factory Services
|
|
|
|
## 프로젝트 개요
|
|
공장관리 플랫폼. 8개 마이크로서비스, 21개+ Docker 컨테이너. Synology NAS 배포, Cloudflare Tunnel.
|
|
|
|
## 서비스 맵
|
|
| 서비스 | 디렉토리 | 스택 | API/Web 포트 | DB |
|
|
|--------|----------|------|-------------|-----|
|
|
| Gateway | gateway/ | nginx | 30000 | - |
|
|
| SSO Auth | sso-auth-service/ | Node.js | 30050 | MariaDB |
|
|
| System1 공장관리 | system1-factory/ | Node.js + nginx | 30005/30080 | MariaDB |
|
|
| System2 신고 | system2-report/ | Node.js + nginx | 30105/30180 | MariaDB |
|
|
| System3 부적합 | system3-nonconformance/ | FastAPI + nginx | 30200/30280 | MariaDB |
|
|
| tkuser 사용자 | user-management/ | Node.js + nginx | 30300/30380 | MariaDB |
|
|
| tkpurchase 소모품 | tkpurchase/ | Node.js + nginx | 30400/30480 | MariaDB |
|
|
| tksafety 안전 | tksafety/ | Node.js + nginx | 30500/30580 | MariaDB |
|
|
| tksupport 행정 | tksupport/ | Node.js + nginx | 30600/30680 | MariaDB |
|
|
| tkeg BOM | tkeg/ | FastAPI + React(Vite) | 30700/30780 | PostgreSQL |
|
|
|
|
System1에는 FastAPI bridge도 있음 (30008, AI 연동용).
|
|
|
|
## 기술 스택
|
|
- **프론트엔드**: Vanilla JS + Tailwind CDN + Font Awesome (빌드 없음). tkeg만 React+Vite+MUI
|
|
- **백엔드(Node)**: Express + mysql2/Knex. 패턴: Routes → Controllers → Services → Models → DB
|
|
- **백엔드(Python)**: FastAPI + SQLAlchemy (System3, tkeg)
|
|
- **DB**: MariaDB 공유(hyungi) + PostgreSQL(tkeg: tk_bom) + Redis(세션)
|
|
- **인증**: JWT SSO — sso_token 쿠키(domain=.technicalkorea.net) + localStorage 폴백
|
|
- **접근레벨**: worker(1) < group_leader(2) < support_team(3) < admin(4) < system(5)
|
|
|
|
## 코드 규칙
|
|
1. **캐시 버스팅 필수**: JS/CSS 수정 시 HTML `<script>`/`<link>` 태그의 `?v=YYYYMMDDNN` 반드시 갱신
|
|
2. **API 응답 포맷**: `{ success: true, data: {...}, message: "..." }` — res.success(), res.paginated() 등
|
|
3. **커밋 메시지**: `type(scope): 한국어 설명` (예: `fix(tkfb): 모바일 레이아웃 수정`)
|
|
4. **CSS 전역**: system1-factory → tkfb.css (모든 페이지 로드). 모바일 = @media (max-width: 768px)
|
|
|
|
## 배포
|
|
전제: Tailscale SSH 키 인증 설정 완료 (hyungi@100.71.132.52)
|
|
```bash
|
|
git push && ssh hyungi@100.71.132.52 "cd /volume1/docker/tk-factory-services && git pull && export PATH=\$PATH:/volume2/@appstore/ContainerManager/usr/bin && docker compose up -d --build <서비스명>"
|
|
```
|
|
상세: DEPLOY-GUIDE.md 참조. 아키텍처: ARCHITECTURE.md 참조.
|
|
|
|
## 개발 주의사항 — 실수 기록
|
|
|
|
### admin 계정으로만 테스트하지 말 것
|
|
admin(role=admin/system)은 대부분의 권한 체크를 건너뜀. 반드시 **일반 사용자(role=user) 계정으로 테스트**할 것.
|
|
- `pagePermission.js`: admin은 L18에서 `return next()`로 미들웨어 전체 스킵
|
|
- `tkfb-core.js initAuth()`: admin은 `accessibleKeys` 조회 자체를 안 함
|
|
- **실제 사례 (2026-04-01)**: `getPool()` async 함수에 `await` 누락 → admin만 통과, 일반 사용자 전원 500 에러. admin 계정으로만 테스트하여 배포 전 미발견
|
|
|
|
### workers 테이블과 sso_users 테이블 불일치
|
|
모든 사용자가 `workers` 테이블에 있지 않음 (생산지원팀 등 사무직). department_id 조회 시 반드시 **sso_users fallback** 사용:
|
|
```sql
|
|
COALESCE(w.department_id, su.department_id) AS department_id
|
|
```
|
|
- `dashboardModel.js getUserInfo()` — 수정 완료
|
|
- `pageAccessRoutes.js` 부서 조회 — 수정 완료
|
|
- **신규 코드 작성 시**: workers JOIN 후 department_id 사용하면 동일 버그 재발
|
|
|
|
### 전역 스코프 const vs function 충돌
|
|
`const`로 선언한 변수명과 다른 스크립트 파일의 `function` 선언이 같은 이름이면 `SyntaxError: Identifier already declared` 발생. 해당 스크립트 **전체**가 실행 안 됨.
|
|
- **실제 사례 (2026-04-01)**: `tkfb-core.js`에 `const escHtml = escapeHtml;` 추가 → 4개 JS 파일에서 `function escHtml()` 재선언 → 모바일 전체 미작동
|
|
- **규칙**: 전역 alias 추가 시 `grep -r "function 함수명" --include="*.js"` 로 충돌 확인 필수
|
|
|
|
### 캐시 버스팅 누락
|
|
JS/CSS 수정 후 HTML의 `?v=YYYYMMDDNN` 갱신을 빠뜨리면 브라우저 캐시로 구버전 실행됨.
|
|
- 특히 `tkfb-core.js`는 **35개 HTML**에서 참조 — 일괄 갱신 필수
|
|
- `shared-bottom-nav.js`는 5개 HTML에서 참조
|
|
- **규칙**: JS/CSS 수정 시 해당 파일을 참조하는 모든 HTML의 버전 갱신. `grep -r "파일명" --include="*.html"` 로 대상 확인
|
|
|
|
### nginx 프록시 경로 우선순위
|
|
nginx location 블록은 **더 구체적인 경로가 먼저** 매칭됨. `/api/auth/`를 `/api/` 뒤에 넣으면 `/api/`가 먼저 잡힘.
|
|
- **실제 사례 (2026-04-01)**: `/api/auth/change-password` 요청이 system1-api로 라우팅되어 404. `/api/auth/` location을 `/api/` 앞에 추가하여 해결
|
|
|
|
## 멀티 에이전트 워크플로우
|
|
이 프로젝트는 Cowork(설계/검토) + Claude Code(코딩) 멀티 에이전트 방식을 지원한다.
|
|
- **워크플로우 가이드**: `.cowork/WORKFLOW-GUIDE.md`
|
|
- **스프린트 계획/스펙**: `.cowork/sprints/sprint-NNN/`
|
|
- **에러 기록**: `.cowork/errors/ERROR-LOG.md`
|
|
- **템플릿**: `.cowork/templates/`
|
|
|
|
Claude Code Worker는 자신의 섹션 스펙(section-*.md)만 읽고 작업할 것. 다른 섹션 파일 수정 금지.
|