feat: 다수 기능 개선 - 순찰, 출근, 작업분석, 모바일 UI 등

- 순찰/점검 기능 개선 (zone-detail 페이지 추가)
- 출근/근태 시스템 개선 (연차 조회, 근무현황)
- 작업분석 대분류 그룹화 및 마이그레이션 스크립트
- 모바일 네비게이션 UI 추가
- NAS 배포 도구 및 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-02-09 14:41:01 +09:00
parent 1548253f56
commit 2b1c7bfb88
633 changed files with 361224 additions and 1090 deletions

View File

@@ -29,7 +29,21 @@ const getAllWorkStatusTypes = async (callback) => {
const getAllErrorTypes = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query('SELECT id, name, description, severity, solution_guide, created_at, updated_at FROM error_types ORDER BY name ASC');
// issue_report_items에서 부적합(nonconformity) 타입의 항목만 조회
const [rows] = await db.query(`
SELECT
iri.item_id as id,
iri.item_name as name,
iri.description,
iri.severity,
irc.category_name as category,
iri.display_order,
iri.created_at
FROM issue_report_items iri
INNER JOIN issue_report_categories irc ON iri.category_id = irc.category_id
WHERE irc.category_type = 'nonconformity' AND iri.is_active = TRUE
ORDER BY irc.display_order, iri.display_order, iri.item_name ASC
`);
callback(null, rows);
} catch (err) {
console.error('에러 유형 조회 오류:', err);
@@ -301,9 +315,10 @@ const removeSpecificEntry = async (entry_id, deleted_by, callback) => {
/**
* 공통 SELECT 쿼리 부분
* error_type_id는 issue_report_items 테이블 참조 (issue-categories.html에서 관리)
*/
const getSelectQuery = () => `
SELECT
SELECT
dwr.id,
dwr.report_date,
dwr.worker_id,
@@ -317,7 +332,8 @@ const getSelectQuery = () => `
p.project_name,
wt.name as work_type_name,
wst.name as work_status_name,
et.name as error_type_name,
iri.item_name as error_type_name,
irc.category_name as error_category_name,
u.name as created_by_name,
dwr.created_at,
dwr.updated_at
@@ -326,7 +342,8 @@ const getSelectQuery = () => `
LEFT JOIN projects p ON dwr.project_id = p.project_id
LEFT JOIN work_types wt ON dwr.work_type_id = wt.id
LEFT JOIN work_status_types wst ON dwr.work_status_id = wst.id
LEFT JOIN error_types et ON dwr.error_type_id = et.id
LEFT JOIN issue_report_items iri ON dwr.error_type_id = iri.item_id
LEFT JOIN issue_report_categories irc ON iri.category_id = irc.category_id
LEFT JOIN users u ON dwr.created_by = u.user_id
`;
@@ -873,9 +890,11 @@ const createReportEntries = async ({ report_date, worker_id, entries }) => {
/**
* [V2] 공통 SELECT 쿼리 (새로운 스키마 기준)
* 주의: work_type_id 컬럼에는 실제로 task_id가 저장됨
* error_type_id는 issue_report_items 테이블 참조 (issue-categories.html에서 관리)
*/
const getSelectQueryV2 = () => `
SELECT
SELECT
dwr.id,
dwr.report_date,
dwr.worker_id,
@@ -887,17 +906,21 @@ const getSelectQueryV2 = () => `
dwr.created_by,
w.worker_name,
p.project_name,
t.task_name,
wt.name as work_type_name,
wst.name as work_status_name,
et.name as error_type_name,
iri.item_name as error_type_name,
irc.category_name as error_category_name,
u.name as created_by_name,
dwr.created_at
FROM daily_work_reports dwr
LEFT JOIN workers w ON dwr.worker_id = w.worker_id
LEFT JOIN projects p ON dwr.project_id = p.project_id
LEFT JOIN work_types wt ON dwr.work_type_id = wt.id
LEFT JOIN tasks t ON dwr.work_type_id = t.task_id
LEFT JOIN work_types wt ON t.work_type_id = wt.id
LEFT JOIN work_status_types wst ON dwr.work_status_id = wst.id
LEFT JOIN error_types et ON dwr.error_type_id = et.id
LEFT JOIN issue_report_items iri ON dwr.error_type_id = iri.item_id
LEFT JOIN issue_report_categories irc ON iri.category_id = irc.category_id
LEFT JOIN users u ON dwr.created_by = u.user_id
`;
@@ -967,9 +990,9 @@ const updateReportById = async (reportId, updateData) => {
}
}
// updated_by_user_id는 항상 업데이트
// updated_by는 항상 업데이트
if (updateData.updated_by_user_id) {
setClauses.push('updated_by_user_id = ?');
setClauses.push('updated_by = ?');
queryParams.push(updateData.updated_by_user_id);
}