모든 작업자가 개인 계정으로 로그인하여 본인의 연차와 출근 기록을 확인할 수 있는 시스템을 구축했습니다. 주요 기능: - 작업자-계정 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>
103 lines
4.3 KiB
JavaScript
103 lines
4.3 KiB
JavaScript
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.up = async function(knex) {
|
|
// 1. Roles 생성
|
|
await knex('roles').insert([
|
|
{ id: 1, name: 'System Admin', description: '시스템 전체 관리자. 모든 권한을 가짐.' },
|
|
{ id: 2, name: 'Admin', description: '관리자. 사용자 및 프로젝트 관리 등 대부분의 권한을 가짐.' },
|
|
{ id: 3, name: 'Leader', description: '그룹장. 팀원 작업 현황 조회 등 중간 관리자 권한.' },
|
|
{ id: 4, name: 'Worker', description: '일반 작업자. 자신의 작업 보고서 작성 및 조회 권한.' },
|
|
]);
|
|
|
|
// 2. Permissions 생성 (예시)
|
|
const permissions = [
|
|
// User
|
|
{ name: 'user:create', description: '사용자 생성' },
|
|
{ name: 'user:read', description: '사용자 정보 조회' },
|
|
{ name: 'user:update', description: '사용자 정보 수정' },
|
|
{ name: 'user:delete', description: '사용자 삭제' },
|
|
// Project
|
|
{ name: 'project:create', description: '프로젝트 생성' },
|
|
{ name: 'project:read', description: '프로젝트 조회' },
|
|
{ name: 'project:update', description: '프로젝트 수정' },
|
|
{ name: 'project:delete', description: '프로젝트 삭제' },
|
|
// Work Report
|
|
{ name: 'work-report:create', description: '작업 보고서 생성' },
|
|
{ name: 'work-report:read-own', description: '자신의 작업 보고서 조회' },
|
|
{ name: 'work-report:read-team', description: '팀의 작업 보고서 조회' },
|
|
{ name: 'work-report:read-all', description: '모든 작업 보고서 조회' },
|
|
{ name: 'work-report:update', description: '작업 보고서 수정' },
|
|
{ name: 'work-report:delete', description: '작업 보고서 삭제' },
|
|
// System
|
|
{ name: 'system:read-logs', description: '시스템 로그 조회' },
|
|
{ name: 'system:manage-settings', description: '시스템 설정 관리' },
|
|
];
|
|
await knex('permissions').insert(permissions);
|
|
|
|
// 3. Role-Permissions 매핑
|
|
const allPermissions = await knex('permissions').select('id', 'name');
|
|
const permissionMap = allPermissions.reduce((acc, p) => {
|
|
acc[p.name] = p.id;
|
|
return acc;
|
|
}, {});
|
|
|
|
const rolePermissions = {
|
|
// System Admin (모든 권한)
|
|
'System Admin': allPermissions.map(p => p.id),
|
|
// Admin
|
|
'Admin': [
|
|
permissionMap['user:create'], permissionMap['user:read'], permissionMap['user:update'], permissionMap['user:delete'],
|
|
permissionMap['project:create'], permissionMap['project:read'], permissionMap['project:update'], permissionMap['project:delete'],
|
|
permissionMap['work-report:read-all'], permissionMap['work-report:update'], permissionMap['work-report:delete'],
|
|
],
|
|
// Leader
|
|
'Leader': [
|
|
permissionMap['user:read'],
|
|
permissionMap['project:read'],
|
|
permissionMap['work-report:read-team'],
|
|
permissionMap['work-report:read-own'],
|
|
permissionMap['work-report:create'],
|
|
],
|
|
// Worker
|
|
'Worker': [
|
|
permissionMap['work-report:create'],
|
|
permissionMap['work-report:read-own'],
|
|
],
|
|
};
|
|
|
|
const rolePermissionInserts = [];
|
|
for (const roleName in rolePermissions) {
|
|
const roleId = (await knex('roles').where('name', roleName).first()).id;
|
|
rolePermissions[roleName].forEach(permissionId => {
|
|
rolePermissionInserts.push({ role_id: roleId, permission_id: permissionId });
|
|
});
|
|
}
|
|
await knex('role_permissions').insert(rolePermissionInserts);
|
|
|
|
// 4. 기존 사용자에게 역할 부여 (예: 기존 admin -> Admin, leader -> Leader, user -> Worker)
|
|
await knex.raw(`
|
|
UPDATE users SET role_id =
|
|
CASE
|
|
WHEN _role_old = 'system' THEN (SELECT id FROM roles WHERE name = 'System Admin')
|
|
WHEN _role_old = 'admin' THEN (SELECT id FROM roles WHERE name = 'Admin')
|
|
WHEN _role_old = 'leader' THEN (SELECT id FROM roles WHERE name = 'Leader')
|
|
ELSE (SELECT id FROM roles WHERE name = 'Worker')
|
|
END
|
|
`);
|
|
};
|
|
|
|
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.down = async function(knex) {
|
|
await knex('role_permissions').del();
|
|
await knex('user_permissions').del();
|
|
await knex('roles').del();
|
|
await knex('permissions').del();
|
|
|
|
// 역할 롤백 (단순화된 버전)
|
|
await knex.raw("UPDATE users SET _role_old = 'user' WHERE role_id IS NOT NULL");
|
|
}; |