- 실시간 작업장 현황을 지도로 시각화 - 작업장 관리 페이지에서 정의한 구역 정보 활용 - TBM 작업자 및 방문자 현황 표시 주요 변경사항: - dashboard.html: 작업장 현황 섹션 추가 (기존 작업 현황 테이블 제거) - workplace-status.js: 지도 렌더링 및 데이터 통합 로직 구현 - modern-dashboard.js: 삭제된 DOM 요소 조건부 체크 추가 시각화 방식: - 인원 없음: 회색 테두리 + 작업장 이름 - 내부 작업자: 파란색 영역 + 인원 수 - 외부 방문자: 보라색 영역 + 인원 수 - 둘 다: 초록색 영역 + 총 인원 수 기술 구현: - Canvas API 기반 사각형 영역 렌더링 - map-regions API를 통한 데이터 일관성 보장 - 클릭 이벤트로 상세 정보 모달 표시 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
9.5 KiB
9.5 KiB
TK-FB-Project 통합 개발 가이드
이 문서는 프로젝트의 실행, 규칙, 테스트, 호환성 등 모든 개발 관련 사항을 통합한 가이드입니다.
🏗 프로젝트 개요 및 아키텍처
생산팀 내부 포털 개발 및 유지보수
기술 스택
- Backend: Node.js, Express.js (Port: 20005)
- Frontend: Vanilla HTML/CSS/JS (Port: 20000)
- Database: MariaDB (Port: 20306), phpMyAdmin (Port: 20080)
- Infra: Docker Compose (Synology NAS, Mac Mini)
- Bridge: FastAPI (Port: 20010, Python 3.11+) - 2025.07 도입
아키텍처 모식도
브라우저 → FastAPI (8000) → Express (3005) → MariaDB
↓
정적 파일 서빙
Note: 현재 개발 환경 포트는 위 기술 스택 섹션 참조
🚀 실행 가이드
필수: 환경 변수 설정
.env.example을 .env로 복사하고 설정하세요. 절대 커밋 금지!
Docker 실행
./start.sh # 간편 실행 (권장)
./stop.sh # 중지
docker-compose up -d # 수동 실행
📏 코딩 컨벤션
네이밍
| 대상 | 스타일 | 예시 |
|---|---|---|
| JS 변수/함수 | camelCase | calculateTotal |
| JS 클래스 | PascalCase | UserReport |
| 파일명 | kebab-case | work-report.js |
| DB 테이블/컬럼 | snake_case | user_accounts |
| API URL | plural, kebab | /api/work-reports |
코드 품질
- 파일 분리: 750줄 초과 시 리팩토링 고려 (Controller/Service/Model 분리 필수).
- Early Return: 중첩 조건문 지양.
- 주석: JSDoc 활용 권장.
🎨 UI/UX 디자인 가이드
디자인 원칙
- 모던하고 깔끔한 디자인: 이모지 사용 지양, 아이콘 또는 심플한 텍스트 사용
- 일관성: 모든 페이지에서 동일한 디자인 시스템 적용
- 컴포넌트 재사용: navbar, footer 등은 컴포넌트로 관리
이모지 사용 금지
❌ 금지:
<!-- 나쁜 예 -->
<button>📊 대시보드</button>
<h1>🔧 작업 관리</h1>
✅ 권장:
<!-- 좋은 예 - 아이콘 라이브러리 사용 또는 심플한 텍스트 -->
<button class="btn-primary">
<i class="icon-dashboard"></i>
대시보드
</button>
<h1>작업 관리</h1>
색상 가이드
- Primary: 하늘색 계열 (
#0ea5e9,#38bdf8,#7dd3fc) - 기본 배경: 흰색/밝은 회색 계열
- 텍스트:
#1f2937(dark gray) - 보조 텍스트:
#6b7280(medium gray)
컴포넌트 구조
- 네비게이션:
web-ui/components/navbar.html참조 - 일관된 헤더: 모든 페이지에서
<div id="navbar-container"></div>사용 - CSS 로딩 순서:
design-system.css→ 페이지별 CSS
페이지 구조 (2026-01-20 개편)
web-ui/pages/
├── dashboard.html # 메인 대시보드
├── work/ # 작업 관련 페이지
│ ├── report-create.html # 작업보고서 작성
│ ├── report-view.html # 작업보고서 조회
│ └── analysis.html # 작업 분석
├── admin/ # 관리자 기능
│ ├── index.html # 관리 메뉴 허브
│ ├── projects.html # 프로젝트 관리
│ ├── workers.html # 작업자 관리
│ ├── codes.html # 코드 관리
│ └── accounts.html # 계정 관리
├── profile/ # 사용자 프로필
│ ├── info.html # 내 정보
│ └── password.html # 비밀번호 변경
└── .archived-*/ # 미사용 페이지 보관
네이밍 규칙:
- 메인 페이지: 단일 명사 (
dashboard.html) - 관리 페이지: 복수형 명사 (
projects.html,workers.html) - 기능 페이지: 동사-명사 (
report-create.html,report-view.html) - 폴더명: 단수형, 소문자 (
work/,admin/,profile/)
네비게이션 구조:
- 1차:
dashboard.html(메인 진입점) - 2차:
admin/index.html(관리 허브) - 모든 페이지: navbar를 통해 profile, 작업 페이지로 이동 가능
표준 컴포넌트 (2026-01-20 업데이트)
네비게이션 헤더
모든 페이지는 표준 navbar 컴포넌트를 사용합니다:
<!-- HTML에 컨테이너 추가 -->
<div id="navbar-container"></div>
<!-- 스크립트로 로드 -->
<script src="/js/load-navbar.js"></script>
특징:
- 자동으로 사용자 정보 표시 (이름, 역할)
- 프로필 메뉴 (내 프로필, 비밀번호 변경, 로그아웃)
- 관리자 전용 메뉴 자동 표시/숨김
- 현재 시각 실시간 표시
- 대시보드 버튼
CSS 변수 시스템
모든 스타일은 design-system.css의 CSS 변수를 사용합니다:
/* 색상 - 하늘색 계열 primary */
var(--primary-500) /* 기본 하늘색: #0ea5e9 */
var(--primary-400) /* 밝은 하늘색: #38bdf8 */
var(--header-gradient) /* 헤더 그라디언트 */
/* 간격 */
var(--space-2) /* 8px */
var(--space-4) /* 16px */
var(--space-6) /* 24px */
/* 타이포그래피 */
var(--text-sm) /* 14px */
var(--text-base) /* 16px */
var(--font-medium) /* 500 */
/* 기타 */
var(--radius-md) /* 8px 둥근 모서리 */
var(--shadow-md) /* 그림자 */
var(--transition-fast) /* 150ms */
금지: 하드코딩된 색상 값 사용 (#0ea5e9 대신 var(--primary-500) 사용)
페이지 레이아웃 템플릿
web-ui/templates/ 디렉토리에 4가지 표준 템플릿 제공:
- dashboard-layout.html: 메인 대시보드, 통계 페이지
- work-layout.html: 작업 관련 페이지 (보고서, 분석)
- admin-layout.html: 관리자 페이지 (테이블, CRUD)
- simple-layout.html: 프로필, 설정 등 단순 페이지
새 페이지 생성 시:
# 템플릿 복사
cp web-ui/templates/work-layout.html web-ui/pages/work/new-page.html
# 내용 수정
# - <title> 변경
# - 페이지별 CSS/JS 추가
# - 콘텐츠 작성
상세한 사용법은 web-ui/templates/README.md 참조.
🔐 페이지 접근 권한 관리
권한 체크 방식
- 관리자 전용 페이지:
admin-only클래스 사용 - 페이지별 권한 체크:
pages테이블 기반 권한 확인 - 클라이언트 측:
auth-check.js에서 자동 권한 검증
페이지 등록 (pages 테이블)
새 페이지 생성 시 반드시 pages 테이블에 등록:
-- 마이그레이션 예시
INSERT INTO pages (page_name, page_url, page_category, description, display_order, is_active)
VALUES
('출입 신청', '/pages/work/visit-request.html', 'work', '작업장 출입 및 안전교육 신청', 150, 1),
('안전관리', '/pages/admin/safety-management.html', 'admin', '출입 신청 승인 및 안전교육 관리', 210, 1);
페이지 권한 할당
- Admin: 모든 페이지 자동 접근 가능
- 일반 사용자:
page_access테이블에 명시적 권한 부여 필요
-- 특정 사용자에게 페이지 권한 부여
INSERT INTO page_access (user_id, page_id, granted_by, granted_at)
VALUES (123, 45, 1, NOW());
HTML 페이지 설정
<!-- 관리자 전용 페이지 -->
<a href="/pages/admin/safety-management.html" class="quick-action-card admin-only">
<div class="action-content">
<h3>안전관리</h3>
</div>
</a>
<!-- 모든 사용자 접근 가능 -->
<a href="/pages/work/visit-request.html" class="quick-action-card">
<div class="action-content">
<h3>출입 신청</h3>
</div>
</a>
API 라우트 보호
const { verifyToken } = require('../middlewares/authMiddleware');
// 모든 라우트에 인증 필요
router.use(verifyToken);
// 관리자 전용 라우트
router.put('/requests/:id/approve', (req, res) => {
// verifyToken에서 req.user 제공
// 필요시 추가 권한 체크
});
📡 API 개발 가이드
- RESTful: 명사형 리소스 사용 (
POST /usersO,/createUserX). - 응답 포맷:
{ "success": true, "data": {...}, "message": "..." } - 계층 구조:
Controller: 요청/응답 처리, 유효성 검사.Service: 비즈니스 로직, 트랜잭션 관리.Model: DB 쿼리 실행.
MySQL 8.0 호환성 주의사항 (중요)
Synology NAS(MySQL 8.0)의 Strict Mode로 인해 db.execute() 사용 시 Incorrect arguments 에러가 발생할 수 있습니다.
- 해결책:
db.query()사용 권장 (특히 복잡한 JOIN/Subquery). - 가이드:
models/WorkAnalysis.js등의getRecentWork참조.
🧪 테스트 가이드 (Jest)
중요도
- Service Layer ⭐ (최우선: 비즈니스 로직 검증)
- Controller Layer (요청 처리 검증)
- Integration (E2E)
실행
npm test # 전체 실행
npm run test:watch # 변경 감지
npm run test:coverage # 커버리지 측정
작성 패턴 (Service 예시)
// Service는 DB Model을 Mocking하여 테스트
const service = require('../service');
jest.mock('../model');
it('should create report', async () => {
Model.create.mockResolvedValue(123); // Mock DB response
const result = await service.createReport(...);
expect(result).toEqual(...);
});
📝 Git 관리
- 커밋 메시지:
type: subject(예:feat: 작업보고서 API 추가) - Types:
feat,fix,docs,style,refactor,test,chore - 브랜치:
main(배포),develop(통합),feature/*(기능)