모든 작업자가 개인 계정으로 로그인하여 본인의 연차와 출근 기록을 확인할 수 있는 시스템을 구축했습니다. 주요 기능: - 작업자-계정 1:1 통합 (기존 작업자 자동 계정 생성) - 연차 관리 시스템 (연도별 잔액 관리) - 출근 기록 시스템 (일일 근태 기록) - 나의 대시보드 페이지 (개인 정보 조회) 데이터베이스: - workers 테이블에 salary, base_annual_leave 컬럼 추가 - work_attendance_types, vacation_types 테이블 생성 - daily_attendance_records 테이블 생성 - worker_vacation_balance 테이블 생성 - 기존 작업자 자동 계정 생성 (username: 이름 기반) - Guest 역할 추가 백엔드 API: - 한글→영문 변환 유틸리티 (hangulToRoman.js) - UserRoutes에 개인 정보 조회 API 추가 - GET /api/users/me (내 정보) - GET /api/users/me/attendance-records (출근 기록) - GET /api/users/me/vacation-balance (연차 잔액) - GET /api/users/me/work-reports (작업 보고서) - GET /api/users/me/monthly-stats (월별 통계) 프론트엔드: - 나의 대시보드 페이지 (my-dashboard.html) - 연차 정보 위젯 (총/사용/잔여) - 월별 출근 캘린더 - 근무 시간 통계 - 최근 작업 보고서 목록 - 네비게이션 바에 "나의 대시보드" 메뉴 추가 배포 시 주의사항: - 마이그레이션 실행 필요 - 자동 생성된 계정 초기 비밀번호: 1234 - 작업자들에게 첫 로그인 후 비밀번호 변경 안내 필요 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
260 lines
9.7 KiB
Markdown
260 lines
9.7 KiB
Markdown
# 개발 로그 - 2026-01-19
|
|
|
|
## 타임라인
|
|
|
|
### 09:00 - API 에러 파싱 및 Rate Limit 문제 해결
|
|
- **작업**: 수정
|
|
- **대상**: `web-ui/js/api-config.js`, `web-ui/js/modules/calendar/CalendarAPI.js`
|
|
- **문제**:
|
|
1. 에러 응답을 파싱할 때 Response body를 두 번 읽으려 해서 `[object Object]` 오류
|
|
2. HTTP 429 (Too Many Requests) 오류 발생 - 한 달치 데이터를 동시에 요청
|
|
- **원인**:
|
|
- `api-config.js`의 에러 처리에서 response.json()과 response.text()를 순차적으로 호출
|
|
- CalendarAPI의 fallback 로직이 42개의 일일 데이터를 Promise.all로 동시 요청
|
|
- **해결방법**:
|
|
1. Content-Type 헤더를 확인하여 JSON/텍스트 구분
|
|
2. 에러 객체를 문자열로 제대로 변환 (여러 형식 지원)
|
|
3. Fallback 로직을 배치 방식으로 변경 (5개씩, 100ms 대기)
|
|
- **변경 내용**:
|
|
```javascript
|
|
// 에러 메시지 추출 개선
|
|
if (errorData.error) {
|
|
errorMessage = typeof errorData.error === 'string'
|
|
? errorData.error
|
|
: JSON.stringify(errorData.error);
|
|
}
|
|
|
|
// Rate limit 방지 배치 처리
|
|
const BATCH_SIZE = 5;
|
|
const DELAY_BETWEEN_BATCHES = 100;
|
|
```
|
|
- **파일**:
|
|
- `web-ui/js/api-config.js:117-151`
|
|
- `web-ui/js/modules/calendar/CalendarAPI.js:91-146`
|
|
|
|
---
|
|
|
|
### 09:30 - 불필요한 load-navbar.js 제거 및 컴포넌트 로더 에러 개선
|
|
- **작업**: 수정
|
|
- **대상**: `web-ui/pages/common/daily-work-report-viewer.html`, `web-ui/js/component-loader.js`
|
|
- **문제**:
|
|
1. navbar-container가 없는 페이지에서 에러 로그 발생
|
|
2. daily-work-report-viewer.html이 자체 헤더를 사용하는데 navbar 로더가 불필요
|
|
- **해결방법**:
|
|
1. daily-work-report-viewer.html에서 load-navbar.js 제거
|
|
2. component-loader.js의 에러를 warning으로 변경
|
|
- **파일**:
|
|
- `web-ui/pages/common/daily-work-report-viewer.html:339`
|
|
- `web-ui/js/component-loader.js:14`
|
|
|
|
---
|
|
|
|
### 10:00 - 권한 시스템 단순화 및 페이지 접근 권한 관리 기능 구현
|
|
- **작업**: 생성, 수정
|
|
- **대상**: 권한 시스템 전체 개편
|
|
- **요구사항**:
|
|
- Admin 제외 모든 사용자에게 동일한 권한 부여
|
|
- Admin이 사용자별로 페이지 접근 권한 설정 가능
|
|
- 계정 관리 페이지에서 권한 관리
|
|
|
|
#### 10:10 - 데이터베이스 마이그레이션 작성
|
|
- **작업**: 생성
|
|
- **대상**: `api.hyungi.net/db/migrations/20260119000000_simplify_permissions_and_add_page_access.js`
|
|
- **변경 내용**:
|
|
1. **테이블 생성**:
|
|
- `pages`: 페이지 목록 (page_key, page_name, page_path, category, is_admin_only 등)
|
|
- `user_page_access`: 사용자별 페이지 접근 권한 (user_id, page_id, can_access, granted_by)
|
|
2. **권한 단순화**:
|
|
- Leader와 Worker 역할을 User로 통합
|
|
- User에게 모든 일반 기능 권한 부여 (Admin 기능 제외)
|
|
- Leader 역할 삭제
|
|
3. **기본 페이지 등록**:
|
|
- Dashboard: user, leader
|
|
- Management: worker, project, work, code
|
|
- Common: daily-work-report
|
|
- Admin: user-management (Admin 전용)
|
|
4. **기존 사용자 마이그레이션**:
|
|
- Leader → User로 변환
|
|
- 모든 일반 사용자에게 일반 페이지 접근 권한 부여
|
|
- **파일**: `api.hyungi.net/db/migrations/20260119000000_simplify_permissions_and_add_page_access.js:1-178`
|
|
|
|
#### 10:30 - 페이지 접근 권한 관리 API 작성
|
|
- **작업**: 생성
|
|
- **대상**: `api.hyungi.net/routes/pageAccessRoutes.js`
|
|
- **구현 엔드포인트**:
|
|
1. `GET /api/pages`: 모든 페이지 목록 조회
|
|
2. `GET /api/users/:userId/page-access`: 특정 사용자의 페이지 접근 권한 조회
|
|
3. `POST /api/users/:userId/page-access`: 페이지 접근 권한 부여/회수
|
|
4. `DELETE /api/users/:userId/page-access/:pageId`: 특정 페이지 권한 회수
|
|
5. `GET /api/page-access/summary`: 전체 사용자 권한 요약 (Admin용)
|
|
- **기능**:
|
|
- Admin/System Admin은 모든 페이지 자동 접근 가능
|
|
- 일반 사용자는 user_page_access 테이블 기반 권한 체크
|
|
- Admin만 권한 설정 가능 (권한 검증)
|
|
- **파일**:
|
|
- `api.hyungi.net/routes/pageAccessRoutes.js:1-237`
|
|
- `api.hyungi.net/config/routes.js:42,129` (라우트 등록)
|
|
|
|
#### 10:45 - Admin 사용자 관리 페이지에 권한 관리 UI 추가
|
|
- **작업**: 수정
|
|
- **대상**: `web-ui/pages/admin/manage-user.html`, `web-ui/js/manage-user.js`
|
|
- **UI 구현**:
|
|
1. **모달 추가**:
|
|
- 페이지 접근 권한 관리 모달
|
|
- 카테고리별 페이지 목록 (대시보드, 관리, 공통)
|
|
- 체크박스로 권한 ON/OFF
|
|
2. **사용자 목록에 버튼 추가**:
|
|
- "페이지 권한" 버튼 (Admin/System 제외한 사용자만)
|
|
- 기존 "삭제" 버튼과 함께 표시
|
|
3. **스타일링**:
|
|
- 모달 디자인
|
|
- 페이지 아이템 레이아웃
|
|
- 카테고리별 구분
|
|
- **JavaScript 기능**:
|
|
1. `openPageAccessModal()`: 사용자 선택 시 권한 조회 및 모달 표시
|
|
2. `renderPageAccessList()`: 카테고리별 페이지 목록 렌더링
|
|
3. `savePageAccessChanges()`: 체크박스 상태 기반 권한 업데이트
|
|
4. `closePageAccessModal()`: 모달 닫기
|
|
- **파일**:
|
|
- `web-ui/pages/admin/manage-user.html:102-281` (모달 추가)
|
|
- `web-ui/js/manage-user.js:225-233,320-512` (권한 관리 로직)
|
|
|
|
---
|
|
|
|
### 11:30 - 모든 페이지 스크립트 태그 통일 (type="module" 추가)
|
|
- **작업**: 수정
|
|
- **대상**: 웹 페이지 HTML 파일들
|
|
- **문제**:
|
|
- `api-config.js`와 `load-navbar.js`를 모듈로 import하는데 일부 페이지에서 `type="module"` 누락
|
|
- "Unexpected token '{'. import call expects one or two arguments" 오류
|
|
- **해결방법**:
|
|
- 모든 페이지의 api-config.js와 load-navbar.js 스크립트 태그에 `type="module"` 추가
|
|
- Task agent로 일괄 수정
|
|
- **수정된 파일**:
|
|
- `web-ui/pages/analysis/work-analysis-modular.html`
|
|
- `web-ui/pages/analysis/work-analysis-legacy.html`
|
|
- `web-ui/pages/profile/admin-settings.html`
|
|
- 기타 23개 파일 (이미 적용됨)
|
|
|
|
---
|
|
|
|
### 11:45 - admin-settings.html 페이지 헤더 중복 제거
|
|
- **작업**: 수정
|
|
- **대상**: `web-ui/pages/profile/admin-settings.html`
|
|
- **문제**:
|
|
- work-report-header와 page-header가 중복되어 표시됨
|
|
- 뒤로가기 버튼도 중복
|
|
- **해결방법**:
|
|
- work-report-header 제거
|
|
- page-header만 유지하여 일관된 구조 유지
|
|
- **파일**: `web-ui/pages/profile/admin-settings.html:13-28`
|
|
|
|
---
|
|
|
|
### 12:00 - /api/users 엔드포인트 500 에러 수정
|
|
- **작업**: 수정
|
|
- **대상**: `api.hyungi.net/routes/authRoutes.js`
|
|
- **문제**:
|
|
- admin-settings.html 페이지에서 `/api/users` 호출 시 500 Internal Server Error 발생
|
|
- 에러 메시지: `{"message":"사용자 목록을 조회하는데 실패했습니다","code":"DATABASE_ERROR"}`
|
|
- **원인**:
|
|
- 권한 마이그레이션으로 `users` 테이블 구조 변경됨
|
|
- `access_level` 필드가 `_access_level_old`로 변경되고 `role_id` 추가됨
|
|
- 기존 쿼리가 여전히 `access_level` 필드를 조회하려 시도
|
|
- `roles` 테이블과 JOIN 없이 조회
|
|
- **해결방법**:
|
|
1. `users` 테이블과 `roles` 테이블 LEFT JOIN
|
|
2. `access_level` 대신 `_access_level_old`와 `role_name` 조회
|
|
3. 응답에 `role_id`, `role_name` 필드 추가
|
|
4. 하위 호환성을 위해 `access_level` 필드 유지 (role_name 기반)
|
|
- **변경 내용**:
|
|
```sql
|
|
-- 이전
|
|
SELECT user_id, username, name, email, access_level, ...
|
|
FROM Users
|
|
WHERE 1=1
|
|
|
|
-- 이후
|
|
SELECT
|
|
u.user_id, u.username, u.name, u.email,
|
|
u.role_id, r.name as role_name,
|
|
u._access_level_old as access_level, ...
|
|
FROM users u
|
|
LEFT JOIN roles r ON u.role_id = r.id
|
|
WHERE 1=1
|
|
```
|
|
- **응답 구조 변경**:
|
|
```javascript
|
|
{
|
|
user_id: number,
|
|
username: string,
|
|
name: string,
|
|
email: string,
|
|
role_id: number, // 새로 추가
|
|
role_name: string, // 새로 추가
|
|
access_level: string, // 하위 호환성 (role_name 기반)
|
|
worker_id: number,
|
|
is_active: boolean,
|
|
last_login_at: datetime,
|
|
created_at: datetime
|
|
}
|
|
```
|
|
- **파일**: `api.hyungi.net/routes/authRoutes.js:601-650`
|
|
- **영향받는 페이지**:
|
|
- admin-settings.html (사용자 목록)
|
|
- manage-user.html (사용자 관리)
|
|
|
|
---
|
|
|
|
## 요약
|
|
|
|
### 백엔드 변경
|
|
1. **권한 시스템 개편**:
|
|
- 마이그레이션: `20260119000000_simplify_permissions_and_add_page_access.js`
|
|
- API 라우트: `pageAccessRoutes.js` 신규 생성
|
|
- Leader/Worker → User 통합
|
|
|
|
2. **새 API 엔드포인트** (5개):
|
|
- GET /api/pages
|
|
- GET /api/users/:userId/page-access
|
|
- POST /api/users/:userId/page-access
|
|
- DELETE /api/users/:userId/page-access/:pageId
|
|
- GET /api/page-access/summary
|
|
|
|
### 프론트엔드 변경
|
|
1. **버그 수정**:
|
|
- API 에러 파싱 개선
|
|
- Rate limit 방지 (배치 처리)
|
|
- 컴포넌트 로더 에러 → warning
|
|
|
|
2. **페이지 권한 관리 UI** (manage-user.html):
|
|
- 모달 기반 권한 관리 인터페이스
|
|
- 카테고리별 페이지 목록
|
|
- 체크박스로 권한 설정
|
|
|
|
3. **스크립트 태그 통일**:
|
|
- 모든 페이지에 `type="module"` 적용
|
|
- import 오류 해결
|
|
|
|
4. **헤더 통일**:
|
|
- admin-settings.html 중복 헤더 제거
|
|
- 일관된 page-header 구조
|
|
|
|
### 데이터베이스 변경
|
|
- **신규 테이블** (2개):
|
|
- `pages`: 페이지 메타데이터
|
|
- `user_page_access`: 사용자별 페이지 접근 권한
|
|
|
|
- **roles 테이블 변경**:
|
|
- Leader 역할 삭제
|
|
- Worker → User로 이름 변경 및 권한 확대
|
|
|
|
### 테스트 필요
|
|
- [ ] 마이그레이션 실행 확인
|
|
- [ ] 일반 사용자 페이지 접근 권한 확인
|
|
- [ ] Admin 권한 설정 기능 테스트
|
|
- [ ] 모든 페이지 스크립트 로드 확인
|
|
- [ ] 헤더 통일 시각적 확인
|
|
|
|
---
|