feat: 데이터베이스 및 웹 UI 대규모 리팩토링

- 삭제된 DB 테이블들과 관련 코드 정리:
  * 12개 사용하지 않는 테이블 삭제 (activity_logs, CuttingPlan, DailyIssueReports 등)
  * 관련 모델, 컨트롤러, 라우트 파일들 삭제
  * index.js에서 삭제된 라우트들 제거

- 웹 UI 페이지 정리:
  * 21개 사용하지 않는 페이지 삭제
  * issue-reports 폴더 전체 삭제
  * 모든 사용자 권한을 그룹장 대시보드로 통일

- 데이터베이스 스키마 정리:
  * v1 스키마로 통일 (daily_work_reports 테이블)
  * JSON 데이터 임포트 스크립트 구현
  * 외래키 관계 정리 및 데이터 일관성 확보

- 통합 Docker Compose 설정:
  * 모든 서비스를 단일 docker-compose.yml로 통합
  * 20000번대 포트 유지
  * JWT 시크릿 및 환경변수 설정

- 문서화:
  * DATABASE_SCHEMA.md: 현재 DB 스키마 문서화
  * DELETED_TABLES.md: 삭제된 테이블 목록
  * DELETED_PAGES.md: 삭제된 페이지 목록
This commit is contained in:
Hyungi Ahn
2025-11-03 09:26:50 +09:00
parent 2a3feca45b
commit 94ecc7333d
71 changed files with 15664 additions and 4385 deletions

View File

@@ -201,12 +201,12 @@ class WorkAnalysis {
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 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 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 Users u ON dwr.created_by = u.user_id
LEFT JOIN users u ON dwr.created_by = u.user_id
WHERE dwr.report_date BETWEEN ? AND ?
ORDER BY dwr.created_at DESC
LIMIT ?

View File

@@ -1,89 +0,0 @@
const { getDb } = require('../dbPool');
const create = async (plan, callback) => {
try {
const db = await getDb();
const {
project_id, drawing_name,
pipe_spec, area_number,
spool_number, length
} = plan;
const [result] = await db.query(
`INSERT INTO CuttingPlan
(project_id, drawing_name, pipe_spec, area_number, spool_number, length)
VALUES (?, ?, ?, ?, ?, ?)`,
[project_id, drawing_name, pipe_spec, area_number, spool_number, length]
);
callback(null, result.insertId);
} catch (err) {
callback(err);
}
};
const getAll = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM CuttingPlan ORDER BY cutting_plan_id DESC`
);
callback(null, rows);
} catch (err) {
callback(new Error(err.message || String(err)));
}
};
const getById = async (cutting_plan_id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM CuttingPlan WHERE cutting_plan_id = ?`,
[cutting_plan_id]
);
callback(null, rows[0]);
} catch (err) {
callback(err);
}
};
const update = async (plan, callback) => {
try {
const db = await getDb();
const {
cutting_plan_id, project_id, drawing_name,
pipe_spec, area_number, spool_number, length
} = plan;
const [result] = await db.query(
`UPDATE CuttingPlan
SET project_id = ?,
drawing_name = ?,
pipe_spec = ?,
area_number = ?,
spool_number = ?,
length = ?
WHERE cutting_plan_id = ?`,
[project_id, drawing_name, pipe_spec, area_number, spool_number, length, cutting_plan_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
const remove = async (cutting_plan_id, callback) => {
try {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM CuttingPlan WHERE cutting_plan_id = ?`,
[cutting_plan_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
module.exports = { create, getAll, getById, update, remove };

View File

@@ -54,7 +54,7 @@ const createDailyReport = async (reportData, callback) => {
const [existingReports] = await conn.query(
`SELECT dwr.created_by, u.name as created_by_name, COUNT(*) as count, SUM(dwr.work_hours) as total_hours
FROM daily_work_reports dwr
LEFT JOIN Users u ON dwr.created_by = u.user_id
LEFT JOIN users u ON dwr.created_by = u.user_id
WHERE dwr.report_date = ? AND dwr.worker_id = ?
GROUP BY dwr.created_by`,
[report_date, worker_id]
@@ -82,7 +82,7 @@ const [existingReports] = await conn.query(
const [finalReports] = await conn.query(
`SELECT dwr.created_by, u.name as created_by_name, COUNT(*) as count, SUM(dwr.work_hours) as total_hours
FROM daily_work_reports dwr
LEFT JOIN Users u ON dwr.created_by = u.user_id
LEFT JOIN users u ON dwr.created_by = u.user_id
WHERE dwr.report_date = ? AND dwr.worker_id = ?
GROUP BY dwr.created_by`,
[report_date, worker_id]
@@ -164,7 +164,7 @@ const getMyAccumulatedHours = async (date, worker_id, created_by, callback) => {
ORDER BY created_at
) as my_entries
FROM daily_work_reports dwr
LEFT JOIN Projects p ON dwr.project_id = p.project_id
LEFT JOIN projects p ON dwr.project_id = p.project_id
WHERE dwr.report_date = ? AND dwr.worker_id = ? AND dwr.created_by = ?
`;
@@ -216,8 +216,8 @@ const getContributorsByDate = async (date, worker_id, callback) => {
ORDER BY dwr.created_at SEPARATOR ', '
) as entry_details
FROM daily_work_reports dwr
LEFT JOIN Users u ON dwr.created_by = u.user_id
LEFT JOIN Projects p ON dwr.project_id = p.project_id
LEFT JOIN users u ON dwr.created_by = u.user_id
LEFT JOIN projects p ON dwr.project_id = p.project_id
WHERE dwr.report_date = ? AND dwr.worker_id = ?
GROUP BY dwr.created_by
ORDER BY total_hours DESC, first_entry ASC
@@ -245,9 +245,9 @@ const removeSpecificEntry = async (entry_id, deleted_by, callback) => {
const [entryInfo] = await conn.query(
`SELECT dwr.*, w.worker_name, p.project_name, u.name as created_by_name
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 Users u ON dwr.created_by = u.user_id
LEFT JOIN workers w ON dwr.worker_id = w.worker_id
LEFT JOIN projects p ON dwr.project_id = p.project_id
LEFT JOIN users u ON dwr.created_by = u.user_id
WHERE dwr.id = ?`,
[entry_id]
);
@@ -333,12 +333,12 @@ const getSelectQuery = () => `
dwr.created_at,
dwr.updated_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 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 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 Users u ON dwr.created_by = u.user_id
LEFT JOIN users u ON dwr.created_by = u.user_id
`;
/**
@@ -524,7 +524,7 @@ const getSummaryByDate = async (date, callback) => {
COUNT(*) as work_entries_count,
SUM(CASE WHEN dwr.work_status_id = 2 THEN 1 ELSE 0 END) as error_count
FROM daily_work_reports dwr
LEFT JOIN Workers w ON dwr.worker_id = w.worker_id
LEFT JOIN workers w ON dwr.worker_id = w.worker_id
WHERE dwr.report_date = ?
GROUP BY dwr.worker_id, dwr.report_date
ORDER BY w.worker_name ASC
@@ -553,7 +553,7 @@ const getSummaryByWorker = async (worker_id, callback) => {
COUNT(*) as work_entries_count,
SUM(CASE WHEN dwr.work_status_id = 2 THEN 1 ELSE 0 END) as error_count
FROM daily_work_reports dwr
LEFT JOIN Workers w ON dwr.worker_id = w.worker_id
LEFT JOIN workers w ON dwr.worker_id = w.worker_id
WHERE dwr.worker_id = ?
GROUP BY dwr.report_date, dwr.worker_id
ORDER BY dwr.report_date DESC
@@ -587,8 +587,8 @@ const getMonthlySummary = async (year, month, callback) => {
GROUP_CONCAT(DISTINCT p.project_name ORDER BY p.project_name) as projects,
GROUP_CONCAT(DISTINCT wt.name ORDER BY wt.name) as work_types
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 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
WHERE dwr.report_date BETWEEN ? AND ?
GROUP BY dwr.report_date, dwr.worker_id
@@ -798,21 +798,21 @@ const createReportEntries = async ({ report_date, worker_id, entries }) => {
const insertedIds = [];
const sql = `
INSERT INTO daily_work_reports
(report_date, worker_id, project_id, task_id, work_hours, is_error, error_type_code_id, created_by_user_id)
(report_date, worker_id, project_id, work_type_id, work_hours, work_status_id, error_type_id, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`;
for (const entry of entries) {
const { project_id, task_id, work_hours, is_error, error_type_code_id, created_by_user_id } = entry;
const { project_id, work_type_id, work_hours, work_status_id, error_type_id, created_by } = entry;
const [result] = await conn.query(sql, [
report_date,
worker_id,
project_id,
task_id,
work_type_id,
work_hours,
is_error,
error_type_code_id,
created_by_user_id
work_status_id || 1,
error_type_id,
created_by
]);
insertedIds.push(result.insertId);
}
@@ -840,27 +840,29 @@ const createReportEntries = async ({ report_date, worker_id, entries }) => {
*/
const getSelectQueryV2 = () => `
SELECT
dwr.report_id,
dwr.id,
dwr.report_date,
dwr.worker_id,
dwr.project_id,
dwr.task_id,
dwr.work_type_id,
dwr.work_status_id,
dwr.error_type_id,
dwr.work_hours,
dwr.is_error,
dwr.error_type_code_id,
dwr.created_by_user_id,
dwr.created_by,
w.worker_name,
p.project_name,
t.task_name,
c.code_name as error_type_name,
wt.name as work_type_name,
wst.name as work_status_name,
et.name as error_type_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 tasks t ON dwr.task_id = t.task_id
LEFT JOIN users u ON dwr.created_by_user_id = u.user_id
LEFT JOIN codes c ON dwr.error_type_code_id = c.code_id AND c.code_type_id = 'ERROR_TYPE'
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 users u ON dwr.created_by = u.user_id
`;
/**
@@ -881,9 +883,9 @@ const getReportsWithOptions = async (options) => {
whereConditions.push('dwr.worker_id = ?');
queryParams.push(options.worker_id);
}
if (options.created_by_user_id) {
whereConditions.push('dwr.created_by_user_id = ?');
queryParams.push(options.created_by_user_id);
if (options.created_by) {
whereConditions.push('dwr.created_by = ?');
queryParams.push(options.created_by);
}
// 필요에 따라 다른 조건 추가 가능 (project_id 등)

View File

@@ -1,94 +0,0 @@
const { getDb } = require('../dbPool');
const create = async (equipment, callback) => {
try {
const db = await getDb();
const {
factory_id, equipment_name,
model, status, purchase_date, description
} = equipment;
const [result] = await db.query(
`INSERT INTO EquipmentList
(factory_id, equipment_name, model, status, purchase_date, description)
VALUES (?, ?, ?, ?, ?, ?)`,
[factory_id, equipment_name, model, status, purchase_date, description]
);
callback(null, result.insertId);
} catch (err) {
callback(err);
}
};
const getAll = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM EquipmentList ORDER BY equipment_id DESC`
);
callback(null, rows);
} catch (err) {
callback(err);
}
};
const getById = async (equipment_id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM EquipmentList WHERE equipment_id = ?`,
[equipment_id]
);
callback(null, rows[0]);
} catch (err) {
callback(err);
}
};
const update = async (equipment, callback) => {
try {
const db = await getDb();
const {
equipment_id, factory_id, equipment_name,
model, status, purchase_date, description
} = equipment;
const [result] = await db.query(
`UPDATE EquipmentList
SET factory_id = ?,
equipment_name = ?,
model = ?,
status = ?,
purchase_date = ?,
description = ?
WHERE equipment_id = ?`,
[factory_id, equipment_name, model, status, purchase_date, description, equipment_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(new Error(err.message || String(err)));
}
};
const remove = async (equipment_id, callback) => {
try {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM EquipmentList WHERE equipment_id = ?`,
[equipment_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
module.exports = {
create,
getAll,
getById,
update,
remove
};

View File

@@ -1,86 +0,0 @@
const { getDb } = require('../dbPool');
const create = async (factory, callback) => {
try {
const db = await getDb();
const { factory_name, address, description, map_image_url } = factory;
const [result] = await db.query(
`INSERT INTO FactoryInfo
(factory_name, address, description, map_image_url)
VALUES (?, ?, ?, ?)`,
[factory_name, address, description, map_image_url]
);
callback(null, result.insertId);
} catch (err) {
callback(err);
}
};
const getAll = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM FactoryInfo ORDER BY factory_id DESC`
);
callback(null, rows);
} catch (err) {
callback(err);
}
};
const getById = async (factory_id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM FactoryInfo WHERE factory_id = ?`,
[factory_id]
);
callback(null, rows[0]);
} catch (err) {
callback(err);
}
};
const update = async (factory, callback) => {
try {
const db = await getDb();
const { factory_id, factory_name, address, description, map_image_url } = factory;
const [result] = await db.query(
`UPDATE FactoryInfo
SET factory_name = ?,
address = ?,
description = ?,
map_image_url = ?
WHERE factory_id = ?`,
[factory_name, address, description, map_image_url, factory_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(new Error(err.message || String(err)));
}
};
const remove = async (factory_id, callback) => {
try {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM FactoryInfo WHERE factory_id = ?`,
[factory_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
module.exports = {
create,
getAll,
getById,
update,
remove
};

View File

@@ -1,12 +0,0 @@
// models/pingModel.js
/**
* 단순 ping 비즈니스 로직 레이어
* 필요하다면 여기서 더 복잡한 처리나 다른 서비스 호출 등을 관리
*/
exports.ping = () => {
return {
message: 'pong',
timestamp: new Date().toISOString()
};
};

View File

@@ -1,31 +0,0 @@
const { getDb } = require('../dbPool');
// 전체 조회
const getAll = async () => {
const db = await getDb();
const [rows] = await db.query(`SELECT * FROM PipeSpecs ORDER BY material, diameter_in`);
return rows;
};
// 등록
const create = async ({ material, diameter_in, schedule }) => {
const db = await getDb();
const [result] = await db.query(
`INSERT INTO PipeSpecs (material, diameter_in, schedule)
VALUES (?, ?, ?)`,
[material, diameter_in, schedule]
);
return result.insertId;
};
// 삭제
const remove = async (spec_id) => {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM PipeSpecs WHERE spec_id = ?`,
[spec_id]
);
return result.affectedRows;
};
module.exports = { getAll, create, remove };

View File

@@ -1,100 +0,0 @@
const { getDb } = require('../dbPool');
const create = async (processData, callback) => {
try {
const db = await getDb();
const {
project_id, process_name,
process_start, process_end,
planned_worker_count, process_description, note
} = processData;
const [result] = await db.query(
`INSERT INTO Processes
(project_id, process_name, process_start, process_end,
planned_worker_count, process_description, note)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
[project_id, process_name, process_start, process_end,
planned_worker_count, process_description, note]
);
callback(null, result.insertId);
} catch (err) {
callback(err);
}
};
const getAll = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM Processes ORDER BY process_id DESC`
);
callback(null, rows);
} catch (err) {
callback(err);
}
};
const getById = async (process_id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM Processes WHERE process_id = ?`,
[process_id]
);
callback(null, rows[0]);
} catch (err) {
callback(err);
}
};
const update = async (processData, callback) => {
try {
const db = await getDb();
const {
process_id, project_id,
process_name, process_start, process_end,
planned_worker_count, process_description, note
} = processData;
const [result] = await db.query(
`UPDATE Processes
SET project_id = ?,
process_name = ?,
process_start = ?,
process_end = ?,
planned_worker_count = ?,
process_description = ?,
note = ?
WHERE process_id = ?`,
[project_id, process_name, process_start, process_end,
planned_worker_count, process_description, note, process_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(new Error(err.message || String(err)));
}
};
const remove = async (process_id, callback) => {
try {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM Processes WHERE process_id = ?`,
[process_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
module.exports = {
create,
getAll,
getById,
update,
remove
};

View File

@@ -7,7 +7,7 @@ const create = async (worker, callback) => {
const { worker_name, join_date, job_type, salary, annual_leave, status } = worker;
const [result] = await db.query(
`INSERT INTO Workers
`INSERT INTO workers
(worker_name, join_date, job_type, salary, annual_leave, status)
VALUES (?, ?, ?, ?, ?, ?)`,
[worker_name, join_date, job_type, salary, annual_leave, status]
@@ -23,7 +23,7 @@ const create = async (worker, callback) => {
const getAll = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query(`SELECT * FROM Workers ORDER BY worker_id DESC`);
const [rows] = await db.query(`SELECT * FROM workers ORDER BY worker_id DESC`);
callback(null, rows);
} catch (err) {
callback(err);
@@ -34,7 +34,7 @@ const getAll = async (callback) => {
const getById = async (worker_id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(`SELECT * FROM Workers WHERE worker_id = ?`, [worker_id]);
const [rows] = await db.query(`SELECT * FROM workers WHERE worker_id = ?`, [worker_id]);
callback(null, rows[0]);
} catch (err) {
callback(err);
@@ -48,7 +48,7 @@ const update = async (worker, callback) => {
const { worker_id, worker_name, join_date, job_type, salary, annual_leave, status } = worker;
const [result] = await db.query(
`UPDATE Workers
`UPDATE workers
SET worker_name = ?,
join_date = ?,
job_type = ?,
@@ -70,7 +70,7 @@ const remove = async (worker_id, callback) => {
try {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM Workers WHERE worker_id = ?`,
`DELETE FROM workers WHERE worker_id = ?`,
[worker_id]
);
callback(null, result.affectedRows);