From 6cac3dfa3f5159496642a2f093db0428e3942e72 Mon Sep 17 00:00:00 2001 From: kjs Date: Mon, 25 Aug 2025 14:24:00 +0900 Subject: [PATCH] =?UTF-8?q?=ED=9A=8C=EC=82=AC=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EA=B8=B0=EB=8A=A5=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/controllers/adminController.ts | 327 ++++++++++++++++++ backend-node/src/routes/adminRoutes.ts | 6 + 2 files changed, 333 insertions(+) diff --git a/backend-node/src/controllers/adminController.ts b/backend-node/src/controllers/adminController.ts index 3bf5e82e..a73cf117 100644 --- a/backend-node/src/controllers/adminController.ts +++ b/backend-node/src/controllers/adminController.ts @@ -1976,3 +1976,330 @@ export const saveUser = async (req: AuthenticatedRequest, res: Response) => { }); } }; + +/** + * POST /api/admin/companies + * 회사 등록 API + * 기존 Java AdminController의 회사 등록 기능 포팅 + */ +export const createCompany = async ( + req: AuthenticatedRequest, + res: Response +): Promise => { + try { + logger.info("회사 등록 요청", { + body: req.body, + user: req.user, + }); + + const { company_name } = req.body; + + // 필수 입력값 검증 + if (!company_name || !company_name.trim()) { + res.status(400).json({ + success: false, + message: "회사명을 입력해주세요.", + errorCode: "COMPANY_NAME_REQUIRED", + }); + return; + } + + // PostgreSQL 클라이언트 생성 + const client = new Client({ + connectionString: + process.env.DATABASE_URL || + "postgresql://postgres:postgres@localhost:5432/ilshin", + }); + + await client.connect(); + + try { + // 회사명 중복 체크 + const duplicateCheckQuery = ` + SELECT COUNT(*) as count + FROM company_mng + WHERE company_name = $1 + `; + + const duplicateResult = await client.query(duplicateCheckQuery, [ + company_name.trim(), + ]); + + if (parseInt(duplicateResult.rows[0].count) > 0) { + res.status(400).json({ + success: false, + message: "이미 등록된 회사명입니다.", + errorCode: "COMPANY_NAME_DUPLICATE", + }); + return; + } + + // 회사 코드 생성 (COMPANY_1, COMPANY_2, ...) + const codeQuery = ` + SELECT COALESCE(MAX(CAST(SUBSTRING(company_code FROM 9) AS INTEGER)), 0) + 1 as next_number + FROM company_mng + WHERE company_code LIKE 'COMPANY_%' + `; + + const codeResult = await client.query(codeQuery); + const nextNumber = codeResult.rows[0].next_number; + const companyCode = `COMPANY_${nextNumber}`; + + // 회사 정보 저장 + const insertQuery = ` + INSERT INTO company_mng ( + company_code, + company_name, + writer, + regdate, + status + ) VALUES ($1, $2, $3, $4, $5) + RETURNING * + `; + + const writer = req.user + ? `${req.user.userName}(${req.user.userId})` + : "시스템"; + const insertValues = [ + companyCode, + company_name.trim(), + writer, + new Date(), + "active", + ]; + + const insertResult = await client.query(insertQuery, insertValues); + const createdCompany = insertResult.rows[0]; + + logger.info("회사 등록 성공", { + companyCode: createdCompany.company_code, + companyName: createdCompany.company_name, + writer: createdCompany.writer, + }); + + const response = { + success: true, + message: "회사가 성공적으로 등록되었습니다.", + data: { + company_code: createdCompany.company_code, + company_name: createdCompany.company_name, + writer: createdCompany.writer, + regdate: createdCompany.regdate, + status: createdCompany.status, + }, + }; + + res.status(201).json(response); + } finally { + await client.end(); + } + } catch (error) { + logger.error("회사 등록 실패", { error, body: req.body }); + res.status(500).json({ + success: false, + message: "회사 등록 중 오류가 발생했습니다.", + errorCode: "COMPANY_CREATE_ERROR", + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}; + +/** + * PUT /api/admin/companies/:companyCode + * 회사 정보 수정 API + */ +export const updateCompany = async ( + req: AuthenticatedRequest, + res: Response +): Promise => { + try { + const { companyCode } = req.params; + const { company_name, status } = req.body; + + logger.info("회사 정보 수정 요청", { + companyCode, + body: req.body, + user: req.user, + }); + + // 필수 입력값 검증 + if (!company_name || !company_name.trim()) { + res.status(400).json({ + success: false, + message: "회사명을 입력해주세요.", + errorCode: "COMPANY_NAME_REQUIRED", + }); + return; + } + + // PostgreSQL 클라이언트 생성 + const client = new Client({ + connectionString: + process.env.DATABASE_URL || + "postgresql://postgres:postgres@localhost:5432/ilshin", + }); + + await client.connect(); + + try { + // 회사명 중복 체크 (자기 자신 제외) + const duplicateCheckQuery = ` + SELECT COUNT(*) as count + FROM company_mng + WHERE company_name = $1 AND company_code != $2 + `; + + const duplicateResult = await client.query(duplicateCheckQuery, [ + company_name.trim(), + companyCode, + ]); + + if (parseInt(duplicateResult.rows[0].count) > 0) { + res.status(400).json({ + success: false, + message: "이미 등록된 회사명입니다.", + errorCode: "COMPANY_NAME_DUPLICATE", + }); + return; + } + + // 회사 정보 수정 + const updateQuery = ` + UPDATE company_mng + SET company_name = $1, status = $2 + WHERE company_code = $3 + RETURNING * + `; + + const updateValues = [ + company_name.trim(), + status || "active", + companyCode, + ]; + + const updateResult = await client.query(updateQuery, updateValues); + + if (updateResult.rows.length === 0) { + res.status(404).json({ + success: false, + message: "해당 회사를 찾을 수 없습니다.", + errorCode: "COMPANY_NOT_FOUND", + }); + return; + } + + const updatedCompany = updateResult.rows[0]; + + logger.info("회사 정보 수정 성공", { + companyCode: updatedCompany.company_code, + companyName: updatedCompany.company_name, + status: updatedCompany.status, + }); + + const response = { + success: true, + message: "회사 정보가 수정되었습니다.", + data: { + company_code: updatedCompany.company_code, + company_name: updatedCompany.company_name, + writer: updatedCompany.writer, + regdate: updatedCompany.regdate, + status: updatedCompany.status, + }, + }; + + res.status(200).json(response); + } finally { + await client.end(); + } + } catch (error) { + logger.error("회사 정보 수정 실패", { error, body: req.body }); + res.status(500).json({ + success: false, + message: "회사 정보 수정 중 오류가 발생했습니다.", + errorCode: "COMPANY_UPDATE_ERROR", + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}; + +/** + * DELETE /api/admin/companies/:companyCode + * 회사 삭제 API + */ +export const deleteCompany = async ( + req: AuthenticatedRequest, + res: Response +): Promise => { + try { + const { companyCode } = req.params; + + logger.info("회사 삭제 요청", { + companyCode, + user: req.user, + }); + + // PostgreSQL 클라이언트 생성 + const client = new Client({ + connectionString: + process.env.DATABASE_URL || + "postgresql://postgres:postgres@localhost:5432/ilshin", + }); + + await client.connect(); + + try { + // 회사 존재 여부 확인 + const checkQuery = ` + SELECT company_code, company_name + FROM company_mng + WHERE company_code = $1 + `; + + const checkResult = await client.query(checkQuery, [companyCode]); + + if (checkResult.rows.length === 0) { + res.status(404).json({ + success: false, + message: "해당 회사를 찾을 수 없습니다.", + errorCode: "COMPANY_NOT_FOUND", + }); + return; + } + + // 회사 삭제 + const deleteQuery = ` + DELETE FROM company_mng + WHERE company_code = $1 + `; + + await client.query(deleteQuery, [companyCode]); + + logger.info("회사 삭제 성공", { + companyCode, + companyName: checkResult.rows[0].company_name, + }); + + const response = { + success: true, + message: "회사가 삭제되었습니다.", + data: { + company_code: companyCode, + company_name: checkResult.rows[0].company_name, + }, + }; + + res.status(200).json(response); + } finally { + await client.end(); + } + } catch (error) { + logger.error("회사 삭제 실패", { error }); + res.status(500).json({ + success: false, + message: "회사 삭제 중 오류가 발생했습니다.", + errorCode: "COMPANY_DELETE_ERROR", + error: error instanceof Error ? error.message : "Unknown error", + }); + } +}; diff --git a/backend-node/src/routes/adminRoutes.ts b/backend-node/src/routes/adminRoutes.ts index 9e11161f..fc098728 100644 --- a/backend-node/src/routes/adminRoutes.ts +++ b/backend-node/src/routes/adminRoutes.ts @@ -14,6 +14,9 @@ import { saveUser, // 사용자 등록/수정 getCompanyList, getCompanyListFromDB, // 실제 DB에서 회사 목록 조회 + createCompany, // 회사 등록 + updateCompany, // 회사 수정 + deleteCompany, // 회사 삭제 getUserLocale, setUserLocale, getLanguageList, @@ -56,6 +59,9 @@ router.get("/departments", getDepartmentList); // 부서 목록 조회 // 회사 관리 API router.get("/companies", getCompanyList); router.get("/companies/db", getCompanyListFromDB); // 실제 DB에서 회사 목록 조회 +router.post("/companies", createCompany); // 회사 등록 +router.put("/companies/:companyCode", updateCompany); // 회사 수정 +router.delete("/companies/:companyCode", deleteCompany); // 회사 삭제 // 사용자 로케일 API router.get("/user-locale", getUserLocale);