2025. 1. 26. 17:11ㆍ프로젝트
자가진단 설문은 사용자가 시스템을 등록하고 그 시스템을 자가진단 설문을 하는 기능입니다.
코드는 다음과 같습니다.
import express from "express";
import pool from "../db/connection.js"; // DB 연결 파일
const router = express.Router();
// Self-assessment 저장
const handleSelfAssessmentSave = async (req, res) => {
const {
organization,
userGroup,
personalInfoSystem,
memberInfoHomepage,
externalDataProvision = "없음",
cctvOperation,
taskOutsourcing,
personalInfoDisposal,
systemId,
} = req.body;
const user_id = req.session.user?.id;
if (!user_id) {
return res.status(401).json({ message: "로그인이 필요합니다." });
}
if (!organization || !userGroup || !systemId) {
return res
.status(400)
.json({ message: "필수 입력 항목이 누락되었습니다." });
}
try {
const query = `
INSERT INTO self_assessment (
user_id, system_id, organization, user_scale, personal_info_system,
member_info_homepage, external_data_provision, cctv_operation,
task_outsourcing, personal_info_disposal
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
organization = VALUES(organization),
user_scale = VALUES(user_scale),
personal_info_system = VALUES(personal_info_system),
member_info_homepage = VALUES(member_info_homepage),
external_data_provision = VALUES(external_data_provision),
cctv_operation = VALUES(cctv_operation),
task_outsourcing = VALUES(task_outsourcing),
personal_info_disposal = VALUES(personal_info_disposal)
`;
const values = [
user_id,
systemId,
organization,
userGroup,
personalInfoSystem,
memberInfoHomepage,
externalDataProvision,
cctvOperation,
taskOutsourcing,
personalInfoDisposal,
];
await pool.query(query, values);
res.status(201).json({ message: "Self-assessment saved successfully." });
} catch (err) {
console.error("Self-assessment 저장 실패:", err.message);
res
.status(500)
.json({ message: "Internal server error.", error: err.message });
}
};
// 정량 데이터 저장
const handleQuantitativeSave = async (req, res) => {
const { quantitativeResponses } = req.body;
if (!quantitativeResponses || !Array.isArray(quantitativeResponses)) {
return res
.status(400)
.json({ message: "Invalid quantitative responses format." });
}
try {
const query = `
INSERT INTO quantitative (
question_number, unit, evaluation_method, score, question,
legal_basis, criteria_and_references, file_upload, response,
additional_comment, feedback, system_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
unit = VALUES(unit),
evaluation_method = VALUES(evaluation_method),
score = VALUES(score),
legal_basis = VALUES(legal_basis),
criteria_and_references = VALUES(criteria_and_references),
file_upload = VALUES(file_upload),
response = VALUES(response),
additional_comment = VALUES(additional_comment),
feedback = VALUES(feedback)
`;
for (const {
questionNumber,
unit,
evaluationMethod,
score,
question,
legalBasis,
criteriaAndReferences,
fileUpload,
response: answer,
additionalComment,
feedback,
systemId,
} of quantitativeResponses) {
// 기본값 설정
await pool.query(query, [
questionNumber, // 필수
unit || "단위 없음", // 기본값
evaluationMethod || "정량평가", // 기본값
score || 0, // 기본값
question || "질문 없음", // 기본값
legalBasis || "근거 법령 없음", // 기본값
criteriaAndReferences || "평가기준 없음", // 기본값
fileUpload || null, // 파일 업로드는 null 허용
answer || "응답 없음", // 기본값
additionalComment || "추가 의견 없음", // 기본값
feedback || "피드백 없음", // 기본값
systemId, // 필수
]);
}
res
.status(200)
.json({ message: "Quantitative responses saved successfully." });
} catch (error) {
console.error("Error saving quantitative responses:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
// 정성 데이터 저장
const handleQualitativeSave = async (req, res) => {
const { qualitativeResponses } = req.body;
// 데이터 유효성 검사
if (!qualitativeResponses || !Array.isArray(qualitativeResponses)) {
return res
.status(400)
.json({ message: "Invalid qualitative responses format." });
}
try {
// SQL 쿼리 정의
const query = `
INSERT INTO qualitative (
question_number, response, additional_comment, system_id, user_id,
indicator, indicator_definition, evaluation_criteria, reference_info, file_path
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
response = VALUES(response),
additional_comment = VALUES(additional_comment),
indicator = VALUES(indicator),
indicator_definition = VALUES(indicator_definition),
evaluation_criteria = VALUES(evaluation_criteria),
reference_info = VALUES(reference_info),
file_path = VALUES(file_path)
`;
// 반복적으로 데이터베이스 작업 수행
for (const {
questionNumber,
response,
additionalComment,
systemId,
userId,
indicator,
indicatorDefinition,
evaluationCriteria,
referenceInfo,
filePath,
} of qualitativeResponses) {
// 데이터 삽입/업데이트
await pool.query(query, [
questionNumber,
response,
additionalComment || "", // 기본값: 빈 문자열
systemId,
userId,
indicator || "", // 기본값: 빈 문자열
indicatorDefinition || "", // 기본값: 빈 문자열
evaluationCriteria || "", // 기본값: 빈 문자열
referenceInfo || "", // 기본값: 빈 문자열
filePath || null, // 기본값: null
]);
}
// 성공 응답
res
.status(200)
.json({ message: "All qualitative responses saved successfully." });
} catch (error) {
// 에러 처리
console.error("Error saving qualitative responses:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
// 정량 데이터 가져오기
const getQuantitativeData = async (req, res) => {
const { systemId } = req.query;
if (!systemId) {
return res.status(400).json({ message: "System ID is required." });
}
try {
const query = `
SELECT question_number, unit, evaluation_method, score, question,
legal_basis, criteria_and_references, file_upload, response,
additional_comment, feedback
FROM quantitative
WHERE system_id = ?
`;
const [results] = await pool.query(query, [systemId]);
res.status(200).json(results);
} catch (error) {
console.error("Error fetching quantitative data:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
// 정성 데이터 가져오기
const getQualitativeData = async (req, res) => {
const { systemId } = req.query;
if (!systemId) {
return res.status(400).json({ message: "System ID is required." });
}
try {
const query = `
SELECT question_number, indicator, indicator_definition, evaluation_criteria,
reference_info, response, additional_comment, file_path
FROM qualitative
WHERE system_id = ?
`;
const [results] = await pool.query(query, [systemId]);
res.status(200).json(results);
} catch (error) {
console.error("Error fetching qualitative data:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
export {
handleSelfAssessmentSave,
handleQuantitativeSave,
handleQualitativeSave,
getQuantitativeData,
getQualitativeData,
};
이 코드는 자가진단(Self-assessment), 정량(Quantitative), 정성(Qualitative) 데이터를 저장하고 조회하는 API입니다.
1. 자가진단 Self-assessment
const handleSelfAssessmentSave = async (req, res) => {
const {
organization,
userGroup,
personalInfoSystem,
memberInfoHomepage,
externalDataProvision = "없음",
cctvOperation,
taskOutsourcing,
personalInfoDisposal,
systemId,
} = req.body;
const user_id = req.session.user?.id;
if (!user_id) {
return res.status(401).json({ message: "로그인이 필요합니다." });
}
if (!organization || !userGroup || !systemId) {
return res
.status(400)
.json({ message: "필수 입력 항목이 누락되었습니다." });
}
try {
const query = `
INSERT INTO self_assessment (
user_id, system_id, organization, user_scale, personal_info_system,
member_info_homepage, external_data_provision, cctv_operation,
task_outsourcing, personal_info_disposal
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
organization = VALUES(organization),
user_scale = VALUES(user_scale),
personal_info_system = VALUES(personal_info_system),
member_info_homepage = VALUES(member_info_homepage),
external_data_provision = VALUES(external_data_provision),
cctv_operation = VALUES(cctv_operation),
task_outsourcing = VALUES(task_outsourcing),
personal_info_disposal = VALUES(personal_info_disposal)
`;
const values = [
user_id,
systemId,
organization,
userGroup,
personalInfoSystem,
memberInfoHomepage,
externalDataProvision,
cctvOperation,
taskOutsourcing,
personalInfoDisposal,
];
await pool.query(query, values);
res.status(201).json({ message: "Self-assessment saved successfully." });
} catch (err) {
console.error("Self-assessment 저장 실패:", err.message);
res
.status(500)
.json({ message: "Internal server error.", error: err.message });
}
};
Self-assessment 저장 하는 코드
const {
organization,
userGroup,
personalInfoSystem,
memberInfoHomepage,
externalDataProvision = "없음",
cctvOperation,
taskOutsourcing,
personalInfoDisposal,
systemId,
} = req.body;
req.body 를 통해 프론트 부분에서 사용자가 입력한 값들을 저장합니다.
const user_id = req.session.user?.id;
if (!user_id) {
return res.status(401).json({ message: "로그인이 필요합니다." });
}
세션에서 user_id를 가져와 사용자를 인증합니다.
const query = `
INSERT INTO self_assessment (
user_id, system_id, organization, user_scale, personal_info_system,
member_info_homepage, external_data_provision, cctv_operation,
task_outsourcing, personal_info_disposal
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
organization = VALUES(organization),
user_scale = VALUES(user_scale),
personal_info_system = VALUES(personal_info_system),
member_info_homepage = VALUES(member_info_homepage),
external_data_provision = VALUES(external_data_provision),
cctv_operation = VALUES(cctv_operation),
task_outsourcing = VALUES(task_outsourcing),
personal_info_disposal = VALUES(personal_info_disposal)
`;
ON DUPLICATE KEY UPDATE
organization = VALUES(organization),
user_scale = VALUES(user_scale),
personal_info_system = VALUES(personal_info_system),
member_info_homepage = VALUES(member_info_homepage),
external_data_provision = VALUES(external_data_provision),
cctv_operation = VALUES(cctv_operation),
task_outsourcing = VALUES(task_outsourcing),
personal_info_disposal = VALUES(personal_info_disposal)
ON DUPLICATE KEY UPDATE
중복된 키(PRIMARY KEY나 UNIQUE KEY)가 발견되면, 데이터를 삽입하지 않고 지정된 컬럼을 업데이트합니다.
이 기능은 새로운 데이터를 삽입하려 할 때, 중복 문제가 발생해도 기존 데이터를 덮어쓸 수 있게 합니다.
2. 정량 데이터 저장 handleQuantitativeSave
const handleQuantitativeSave = async (req, res) => {
const { quantitativeResponses } = req.body;
if (!quantitativeResponses || !Array.isArray(quantitativeResponses)) {
return res
.status(400)
.json({ message: "Invalid quantitative responses format." });
}
try {
const query = `
INSERT INTO quantitative (
question_number, unit, evaluation_method, score, question,
legal_basis, criteria_and_references, file_upload, response,
additional_comment, feedback, system_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
unit = VALUES(unit),
evaluation_method = VALUES(evaluation_method),
score = VALUES(score),
legal_basis = VALUES(legal_basis),
criteria_and_references = VALUES(criteria_and_references),
file_upload = VALUES(file_upload),
response = VALUES(response),
additional_comment = VALUES(additional_comment),
feedback = VALUES(feedback)
`;
for (const {
questionNumber,
unit,
evaluationMethod,
score,
question,
legalBasis,
criteriaAndReferences,
fileUpload,
response: answer,
additionalComment,
feedback,
systemId,
} of quantitativeResponses) {
// 기본값 설정
await pool.query(query, [
questionNumber, // 필수
unit || "단위 없음", // 기본값
evaluationMethod || "정량평가", // 기본값
score || 0, // 기본값
question || "질문 없음", // 기본값
legalBasis || "근거 법령 없음", // 기본값
criteriaAndReferences || "평가기준 없음", // 기본값
fileUpload || null, // 파일 업로드는 null 허용
answer || "응답 없음", // 기본값
additionalComment || "추가 의견 없음", // 기본값
feedback || "피드백 없음", // 기본값
systemId, // 필수
]);
}
res
.status(200)
.json({ message: "Quantitative responses saved successfully." });
} catch (error) {
console.error("Error saving quantitative responses:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
const handleQuantitativeSave = async (req, res) => {
const { quantitativeResponses } = req.body;
이것도 마찬가지로 프론트쪽에서 사용자가 작성한 데이터를 저장합니다.
const query = `
INSERT INTO quantitative (
question_number, unit, evaluation_method, score, question,
legal_basis, criteria_and_references, file_upload, response,
additional_comment, feedback, system_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
unit = VALUES(unit),
evaluation_method = VALUES(evaluation_method),
score = VALUES(score),
legal_basis = VALUES(legal_basis),
criteria_and_references = VALUES(criteria_and_references),
file_upload = VALUES(file_upload),
response = VALUES(response),
additional_comment = VALUES(additional_comment),
feedback = VALUES(feedback)
`;
ON DUPLICATE KEY UPDATE
중복 키가 발생하면 데이터를 업데이트합니다.
VALUES(column_name): INSERT 쿼리에서 전달된 값을 참조하여 해당 컬럼을 업데이트합니다.
for (const {
questionNumber,
unit,
evaluationMethod,
score,
question,
legalBasis,
criteriaAndReferences,
fileUpload,
response: answer,
additionalComment,
feedback,
systemId,
} of quantitativeResponses) {
// 기본값 설정
await pool.query(query, [
questionNumber, // 필수
unit || "단위 없음", // 기본값
evaluationMethod || "정량평가", // 기본값
score || 0, // 기본값
question || "질문 없음", // 기본값
legalBasis || "근거 법령 없음", // 기본값
criteriaAndReferences || "평가기준 없음", // 기본값
fileUpload || null, // 파일 업로드는 null 허용
answer || "응답 없음", // 기본값
additionalComment || "추가 의견 없음", // 기본값
feedback || "피드백 없음", // 기본값
systemId, // 필수
]);
}
quantitativeResponses의 첫 번째 데이터 객체를 읽습니다.
해당 데이터를 query와 함께 데이터베이스에 삽입하거나 업데이트합니다.
모든 데이터가 처리될 때까지 배열의 각 객체에 대해 위 작업을 반복합니다.
3. 정성 데이터 저장 handleQualitativeSave
const handleQualitativeSave = async (req, res) => {
const { qualitativeResponses } = req.body;
// 데이터 유효성 검사
if (!qualitativeResponses || !Array.isArray(qualitativeResponses)) {
return res
.status(400)
.json({ message: "Invalid qualitative responses format." });
}
try {
// SQL 쿼리 정의
const query = `
INSERT INTO qualitative (
question_number, response, additional_comment, system_id, user_id,
indicator, indicator_definition, evaluation_criteria, reference_info, file_path
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
response = VALUES(response),
additional_comment = VALUES(additional_comment),
indicator = VALUES(indicator),
indicator_definition = VALUES(indicator_definition),
evaluation_criteria = VALUES(evaluation_criteria),
reference_info = VALUES(reference_info),
file_path = VALUES(file_path)
`;
// 반복적으로 데이터베이스 작업 수행
for (const {
questionNumber,
response,
additionalComment,
systemId,
userId,
indicator,
indicatorDefinition,
evaluationCriteria,
referenceInfo,
filePath,
} of qualitativeResponses) {
// 데이터 삽입/업데이트
await pool.query(query, [
questionNumber,
response,
additionalComment || "", // 기본값: 빈 문자열
systemId,
userId,
indicator || "", // 기본값: 빈 문자열
indicatorDefinition || "", // 기본값: 빈 문자열
evaluationCriteria || "", // 기본값: 빈 문자열
referenceInfo || "", // 기본값: 빈 문자열
filePath || null, // 기본값: null
]);
}
// 성공 응답
res
.status(200)
.json({ message: "All qualitative responses saved successfully." });
} catch (error) {
// 에러 처리
console.error("Error saving qualitative responses:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
정량 데이터 저장 코드와 같은 구조로 for if 문으로 반복적으로
요청 데이터의 배열(qualitativeResponses)을 순회하며 각 객체를 처리합니다.
객체의 값을 구조 분해 할당으로 개별 변수에 저장합니다.
4. (정량, 정성) 데이터 가져오기
// 정량 데이터 가져오기
const getQuantitativeData = async (req, res) => {
const { systemId } = req.query;
if (!systemId) {
return res.status(400).json({ message: "System ID is required." });
}
try {
const query = `
SELECT question_number, unit, evaluation_method, score, question,
legal_basis, criteria_and_references, file_upload, response,
additional_comment, feedback
FROM quantitative
WHERE system_id = ?
`;
const [results] = await pool.query(query, [systemId]);
res.status(200).json(results);
} catch (error) {
console.error("Error fetching quantitative data:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
// 정성 데이터 가져오기
const getQualitativeData = async (req, res) => {
const { systemId } = req.query;
if (!systemId) {
return res.status(400).json({ message: "System ID is required." });
}
try {
const query = `
SELECT question_number, indicator, indicator_definition, evaluation_criteria,
reference_info, response, additional_comment, file_path
FROM qualitative
WHERE system_id = ?
`;
const [results] = await pool.query(query, [systemId]);
res.status(200).json(results);
} catch (error) {
console.error("Error fetching qualitative data:", error.message);
res
.status(500)
.json({ message: "Internal server error.", error: error.message });
}
};
'프로젝트' 카테고리의 다른 글
개인정보-컴플라이언스-웹애플리케이션(8) - (피드백) 백엔드 코드 (0) | 2025.01.26 |
---|---|
개인정보-컴플라이언스-웹애플리케이션(7) - (자가진단 설문 결과) 백엔드 코드 (0) | 2025.01.26 |
개인정보-컴플라이언스-웹애플리케이션(5) - (시스템) 백엔드 코드 (0) | 2025.01.24 |
개인정보-컴플라이언스-웹애플리케이션(4) - 테이블(db), (유저,관리자) 백엔드 코드 (0) | 2025.01.24 |
개인정보-컴플라이언스-웹애플리케이션(3) - 프론트 구조 및 백엔드 구조 (1) | 2025.01.23 |