Raw SQL을 Prisma ORM으로 마이그레이션

This commit is contained in:
hyeonsu 2025-09-01 14:52:00 +09:00
parent bde5f0884a
commit b365969c72
4 changed files with 384 additions and 2367 deletions

File diff suppressed because it is too large Load Diff

View File

@ -662,61 +662,53 @@ export async function getLangKeyList(
user: req.user,
});
// 실제 데이터베이스에서 데이터 조회
const client = new Client({
host: process.env.DB_HOST || "localhost",
port: parseInt(process.env.DB_PORT || "5432"),
database: process.env.DB_NAME || "ilshin",
user: process.env.DB_USER || "postgres",
password: process.env.DB_PASSWORD || "postgres",
// Prisma ORM을 사용한 다국어 키 목록 조회
const result = await prisma.multi_lang_key_master.findMany({
orderBy: [
{ company_code: "asc" },
{ menu_name: "asc" },
{ lang_key: "asc" },
],
select: {
key_id: true,
company_code: true,
menu_name: true,
lang_key: true,
description: true,
is_active: true,
created_date: true,
created_by: true,
updated_date: true,
updated_by: true,
},
});
await client.connect();
const langKeys = result.map((row) => ({
keyId: row.key_id,
companyCode: row.company_code,
menuName: row.menu_name,
langKey: row.lang_key,
description: row.description,
isActive: row.is_active,
createdDate: row.created_date?.toISOString(),
createdBy: row.created_by,
updatedDate: row.updated_date?.toISOString(),
updatedBy: row.updated_by,
}));
try {
const query = `
SELECT
key_id as "keyId",
company_code as "companyCode",
menu_name as "menuName",
lang_key as "langKey",
description,
is_active as "isActive",
created_date as "createdDate",
created_by as "createdBy",
updated_date as "updatedDate",
updated_by as "updatedBy"
FROM multi_lang_key_master
ORDER BY company_code, menu_name, lang_key
`;
// 프론트엔드에서 기대하는 응답 형식으로 변환
const response: ApiResponse<any[]> = {
success: true,
message: "다국어 키 목록 조회 성공",
data: langKeys,
};
const result = await client.query(query);
const langKeys = result.rows.map((row) => ({
...row,
createdDate: row.createdDate
? new Date(row.createdDate).toISOString()
: undefined,
updatedDate: row.updatedDate
? new Date(row.updatedDate).toISOString()
: undefined,
}));
logger.info("다국어 키 목록 조회 성공", {
totalCount: langKeys.length,
response: response,
});
// 프론트엔드에서 기대하는 응답 형식으로 변환
const response: ApiResponse<any[]> = {
success: true,
message: "다국어 키 목록 조회 성공",
data: langKeys,
};
logger.info("다국어 키 목록 조회 성공", {
totalCount: langKeys.length,
response: response,
});
res.status(200).json(response);
} finally {
await client.end();
}
res.status(200).json(response);
} catch (error) {
logger.error("다국어 키 목록 조회 실패:", error);
res.status(500).json({
@ -1026,56 +1018,36 @@ export async function saveMenu(
const menuData = req.body;
logger.info("메뉴 저장 요청", { menuData, user: req.user });
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
// Prisma ORM을 사용한 메뉴 저장
const savedMenu = await prisma.menu_info.create({
data: {
objid: Date.now(), // 고유 ID 생성
menu_type: menuData.menuType ? Number(menuData.menuType) : null,
parent_obj_id: menuData.parentObjId
? Number(menuData.parentObjId)
: null,
menu_name_kor: menuData.menuNameKor,
menu_name_eng: menuData.menuNameEng || null,
seq: menuData.seq ? Number(menuData.seq) : null,
menu_url: menuData.menuUrl || null,
menu_desc: menuData.menuDesc || null,
writer: req.user?.userId || "admin",
regdate: new Date(),
status: menuData.status || "active",
system_name: menuData.systemName || "PLM",
company_code: menuData.companyCode || "*",
lang_key: menuData.langKey || null,
lang_key_desc: menuData.langKeyDesc || null,
},
});
await client.connect();
// 실제 데이터베이스에 저장
const query = `
INSERT INTO menu_info (
objid, menu_type, parent_obj_id, menu_name_kor, menu_name_eng,
seq, menu_url, menu_desc, writer, regdate, status,
system_name, company_code, lang_key, lang_key_desc
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15
) RETURNING *
`;
const values = [
Date.now(), // objid
menuData.menuType || null, // menu_type
menuData.parentObjId || null, // parent_obj_id
menuData.menuNameKor, // menu_name_kor
menuData.menuNameEng || null, // menu_name_eng
menuData.seq || null, // seq
menuData.menuUrl || null, // menu_url
menuData.menuDesc || null, // menu_desc
req.user?.userId || "admin", // writer
new Date(), // regdate
menuData.status || "active", // status
menuData.systemName || "PLM", // system_name
menuData.companyCode || "*", // company_code
menuData.langKey || null, // lang_key
menuData.langKeyDesc || null, // lang_key_desc
];
const result = await client.query(query, values);
const savedMenu = result.rows[0];
await client.end();
logger.info("메뉴 저장 성공", { savedMenu });
const response: ApiResponse<any> = {
success: true,
message: "메뉴가 성공적으로 저장되었습니다.",
data: {
objid: savedMenu.objid,
objid: savedMenu.objid.toString(), // BigInt를 문자열로 변환
menuNameKor: savedMenu.menu_name_kor,
menuNameEng: savedMenu.menu_name_eng,
menuUrl: savedMenu.menu_url,
@ -1112,65 +1084,29 @@ export async function updateMenu(
user: req.user,
});
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
// Prisma ORM을 사용한 메뉴 수정
const updatedMenu = await prisma.menu_info.update({
where: {
objid: Number(menuId),
},
data: {
menu_type: menuData.menuType ? Number(menuData.menuType) : null,
parent_obj_id: menuData.parentObjId
? Number(menuData.parentObjId)
: null,
menu_name_kor: menuData.menuNameKor,
menu_name_eng: menuData.menuNameEng || null,
seq: menuData.seq ? Number(menuData.seq) : null,
menu_url: menuData.menuUrl || null,
menu_desc: menuData.menuDesc || null,
status: menuData.status || "active",
system_name: menuData.systemName || "PLM",
company_code: menuData.companyCode || "*",
lang_key: menuData.langKey || null,
lang_key_desc: menuData.langKeyDesc || null,
},
});
await client.connect();
// 실제 데이터베이스에서 메뉴 수정
const query = `
UPDATE menu_info
SET
menu_type = $1,
parent_obj_id = $2,
menu_name_kor = $3,
menu_name_eng = $4,
seq = $5,
menu_url = $6,
menu_desc = $7,
status = $8,
system_name = $9,
company_code = $10,
lang_key = $11,
lang_key_desc = $12
WHERE objid = $13
RETURNING *
`;
const values = [
menuData.menuType ? BigInt(menuData.menuType) : null, // menu_type
menuData.parentObjId ? BigInt(menuData.parentObjId) : null, // parent_obj_id
menuData.menuNameKor, // menu_name_kor
menuData.menuNameEng || null, // menu_name_eng
menuData.seq ? BigInt(menuData.seq) : null, // seq
menuData.menuUrl || null, // menu_url
menuData.menuDesc || null, // menu_desc
menuData.status || "active", // status
menuData.systemName || "PLM", // system_name
menuData.companyCode || "*", // company_code
menuData.langKey || null, // lang_key
menuData.langKeyDesc || null, // lang_key_desc
BigInt(menuId), // objid (WHERE 조건)
];
const result = await client.query(query, values);
if (result.rowCount === 0) {
await client.end();
res.status(404).json({
success: false,
message: "수정할 메뉴를 찾을 수 없습니다.",
});
return;
}
const updatedMenu = result.rows[0];
await client.end();
logger.info("메뉴 수정 성공", { updatedMenu });
const response: ApiResponse<any> = {
@ -1210,36 +1146,13 @@ export async function deleteMenu(
const { menuId } = req.params;
logger.info(`메뉴 삭제 요청: menuId = ${menuId}`, { user: req.user });
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
// Prisma ORM을 사용한 메뉴 삭제
const deletedMenu = await prisma.menu_info.delete({
where: {
objid: Number(menuId),
},
});
await client.connect();
// 실제 데이터베이스에서 메뉴 삭제
const query = `
DELETE FROM menu_info
WHERE objid = $1
RETURNING *
`;
const result = await client.query(query, [BigInt(menuId)]);
if (result.rowCount === 0) {
await client.end();
res.status(404).json({
success: false,
message: "삭제할 메뉴를 찾을 수 없습니다.",
});
return;
}
const deletedMenu = result.rows[0];
await client.end();
logger.info("메뉴 삭제 성공", { deletedMenu });
const response: ApiResponse<any> = {
@ -1287,15 +1200,7 @@ export async function deleteMenusBatch(
return;
}
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
await client.connect();
// Prisma ORM을 사용한 메뉴 일괄 삭제
let deletedCount = 0;
let failedCount = 0;
const deletedMenus: any[] = [];
@ -1304,17 +1209,18 @@ export async function deleteMenusBatch(
// 각 메뉴 ID에 대해 삭제 시도
for (const menuId of menuIds) {
try {
const query = `
DELETE FROM menu_info
WHERE objid = $1
RETURNING *
`;
const deletedMenu = await prisma.menu_info.delete({
where: {
objid: Number(menuId),
},
});
const result = await client.query(query, [BigInt(menuId)]);
if (result.rowCount && result.rowCount > 0) {
if (deletedMenu) {
deletedCount++;
deletedMenus.push(result.rows[0]);
deletedMenus.push({
...deletedMenu,
objid: deletedMenu.objid.toString(),
});
} else {
failedCount++;
failedMenuIds.push(menuId);
@ -1326,8 +1232,6 @@ export async function deleteMenusBatch(
}
}
await client.end();
logger.info("메뉴 일괄 삭제 완료", {
total: menuIds.length,
deletedCount,
@ -1561,125 +1465,94 @@ export const getUserInfo = async (req: AuthenticatedRequest, res: Response) => {
return;
}
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
// Prisma ORM을 사용한 사용자 상세 정보 조회
const user = await prisma.user_info.findUnique({
where: {
user_id: userId,
},
});
await client.connect();
try {
// 사용자 상세 정보 조회 쿼리
const query = `
SELECT
u.sabun,
u.user_id,
u.user_name,
u.user_name_eng,
u.user_name_cn,
u.dept_code,
u.dept_name,
u.position_code,
u.position_name,
u.email,
u.tel,
u.cell_phone,
u.user_type,
u.user_type_name,
u.regdate,
u.status,
u.end_date,
u.fax_no,
u.partner_objid,
u.rank,
u.photo,
u.locale,
u.company_code,
u.data_type,
d.dept_name as dept_name_full,
d.parent_dept_code,
d.location,
d.location_name,
d.sales_yn,
d.company_name as dept_company_name
FROM user_info u
LEFT JOIN dept_info d ON u.dept_code = d.dept_code
WHERE u.user_id = $1
`;
const result = await client.query(query, [userId]);
if (result.rows.length === 0) {
res.status(404).json({
success: false,
message: "사용자를 찾을 수 없습니다.",
error: {
code: "USER_NOT_FOUND",
details: `User ID: ${userId}`,
},
});
return;
}
const user = result.rows[0];
// 응답 데이터 가공
const userInfo = {
sabun: user.sabun,
userId: user.user_id,
userName: user.user_name,
userNameEng: user.user_name_eng,
userNameCn: user.user_name_cn,
deptCode: user.dept_code,
deptName: user.dept_name || user.dept_name_full,
positionCode: user.position_code,
positionName: user.position_name,
email: user.email,
tel: user.tel,
cellPhone: user.cell_phone,
userType: user.user_type,
userTypeName: user.user_type_name,
regdate: user.regdate ? user.regdate.toISOString() : null,
status: user.status || "active",
endDate: user.end_date ? user.end_date.toISOString() : null,
faxNo: user.fax_no,
partnerObjid: user.partner_objid,
rank: user.rank,
photo: user.photo
? `data:image/jpeg;base64,${user.photo.toString("base64")}`
: null,
locale: user.locale,
companyCode: user.company_code,
dataType: user.data_type,
// 부서 정보
deptInfo: {
deptCode: user.dept_code,
deptName: user.dept_name || user.dept_name_full,
parentDeptCode: user.parent_dept_code,
location: user.location,
locationName: user.location_name,
salesYn: user.sales_yn,
companyName: user.dept_company_name,
if (!user) {
res.status(404).json({
success: false,
message: "사용자를 찾을 수 없습니다.",
error: {
code: "USER_NOT_FOUND",
details: `User ID: ${userId}`,
},
};
const response = {
success: true,
data: userInfo,
message: "사용자 상세 정보 조회 성공",
};
logger.info("사용자 상세 정보 조회 성공", {
userId,
userName: user.user_name,
});
res.status(200).json(response);
} finally {
await client.end();
return;
}
// 부서 정보 별도 조회
const deptInfo = user.dept_code
? await prisma.dept_info.findUnique({
where: {
dept_code: user.dept_code,
},
select: {
dept_name: true,
parent_dept_code: true,
location: true,
location_name: true,
sales_yn: true,
company_name: true,
},
})
: null;
// 응답 데이터 가공
const userInfo = {
sabun: user.sabun,
userId: user.user_id,
userName: user.user_name,
userNameEng: user.user_name_eng,
userNameCn: user.user_name_cn,
deptCode: user.dept_code,
deptName: user.dept_name,
positionCode: user.position_code,
positionName: user.position_name,
email: user.email,
tel: user.tel,
cellPhone: user.cell_phone,
userType: user.user_type,
userTypeName: user.user_type_name,
regdate: user.regdate ? user.regdate.toISOString() : null,
status: user.status || "active",
endDate: user.end_date ? user.end_date.toISOString() : null,
faxNo: user.fax_no,
partnerObjid: user.partner_objid,
rank: user.rank,
photo: user.photo
? `data:image/jpeg;base64,${user.photo.toString("base64")}`
: null,
locale: user.locale,
companyCode: user.company_code,
dataType: user.data_type,
// 부서 정보
deptInfo: {
deptCode: user.dept_code,
deptName: deptInfo?.dept_name,
parentDeptCode: deptInfo?.parent_dept_code,
location: deptInfo?.location,
locationName: deptInfo?.location_name,
salesYn: deptInfo?.sales_yn,
companyName: deptInfo?.company_name,
},
};
const response = {
success: true,
data: userInfo,
message: "사용자 상세 정보 조회 성공",
};
logger.info("사용자 상세 정보 조회 성공", {
userId,
userName: user.user_name,
});
res.status(200).json(response);
} catch (error) {
logger.error("사용자 상세 정보 조회 실패", {
error,
@ -1955,98 +1828,66 @@ export const changeUserStatus = async (
return;
}
// 복잡한 상태 변경은 직접 쿼리 사용
const client = new Client({
connectionString: config.databaseUrl,
// Prisma ORM을 사용한 사용자 상태 변경
// 1. 사용자 존재 여부 확인
const currentUser = await prisma.user_info.findUnique({
where: {
user_id: userId,
},
select: {
user_id: true,
user_name: true,
status: true,
},
});
try {
// 1. Prisma ORM으로 사용자 존재 여부 확인
const currentUser = await prisma.user_info.findUnique({
where: {
user_id: userId,
},
select: {
user_id: true,
user_name: true,
status: true,
},
if (!currentUser) {
res.status(404).json({
result: false,
msg: "사용자를 찾을 수 없습니다.",
});
return;
}
// 2. 상태 변경 데이터 준비
let updateData: any = {
status: status,
};
// active/inactive에 따른 END_DATE 처리
if (status === "inactive") {
updateData.end_date = new Date();
} else if (status === "active") {
updateData.end_date = null;
}
// 3. Prisma ORM으로 상태 변경 실행
const updateResult = await prisma.user_info.update({
where: {
user_id: userId,
},
data: updateData,
});
if (updateResult) {
// 사용자 이력 저장은 user_info_history 테이블이 @@ignore 상태이므로 생략
logger.info("사용자 상태 변경 성공", {
userId,
oldStatus: currentUser.status,
newStatus: status,
updatedBy: req.user?.userId,
});
if (!currentUser) {
res.status(404).json({
result: false,
msg: "사용자를 찾을 수 없습니다.",
});
return;
}
await client.connect();
// 2. 상태 변경 쿼리 실행
let updateQuery = `
UPDATE user_info
SET status = $1
`;
const queryParams = [status];
// active/inactive에 따른 END_DATE 처리
if (status === "inactive") {
updateQuery += `, end_date = NOW()`;
} else if (status === "active") {
updateQuery += `, end_date = NULL`;
}
updateQuery += ` WHERE user_id = $2`;
queryParams.push(userId);
const updateResult = await client.query(updateQuery, queryParams);
if (updateResult.rowCount && updateResult.rowCount > 0) {
// 3. 사용자 이력 저장 (선택적)
try {
await client.query(
`
INSERT INTO user_info_history
(user_id, user_name, dept_code, dept_name, user_type_name, history_type, writer, reg_date, status, sabun)
VALUES ($1, $2, '', '', '', '사용자 상태 변경', $3, NOW(), $4, '')
`,
[
userId,
currentUser.user_name || userId,
req.user?.userId || "system",
status,
]
);
} catch (historyError) {
logger.warn("사용자 이력 저장 실패", {
error: historyError,
userId,
status,
});
// 이력 저장 실패는 치명적이지 않으므로 계속 진행
}
logger.info("사용자 상태 변경 성공", {
userId,
oldStatus: currentUser.status,
newStatus: status,
updatedBy: req.user?.userId,
});
res.json({
result: true,
msg: `사용자 상태가 ${status === "active" ? "활성" : "비활성"}으로 변경되었습니다.`,
});
} else {
res.status(400).json({
result: false,
msg: "사용자 상태 변경에 실패했습니다.",
});
}
} finally {
await client.end();
res.json({
result: true,
msg: `사용자 상태가 ${status === "active" ? "활성" : "비활성"}으로 변경되었습니다.`,
});
} else {
res.status(400).json({
result: false,
msg: "사용자 상태 변경에 실패했습니다.",
});
}
} catch (error) {
logger.error("사용자 상태 변경 중 오류 발생", {
@ -2315,63 +2156,36 @@ export const updateCompany = async (
return;
}
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
// Prisma ORM으로 회사명 중복 체크 (자기 자신 제외)
const duplicateCompany = await prisma.company_mng.findFirst({
where: {
company_name: company_name.trim(),
company_code: {
not: companyCode,
},
},
});
await client.connect();
if (duplicateCompany) {
res.status(400).json({
success: false,
message: "이미 등록된 회사명입니다.",
errorCode: "COMPANY_NAME_DUPLICATE",
});
return;
}
// Prisma ORM으로 회사 정보 수정
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];
const updatedCompany = await prisma.company_mng.update({
where: {
company_code: companyCode,
},
data: {
company_name: company_name.trim(),
status: status || "active",
},
});
logger.info("회사 정보 수정 성공", {
companyCode: updatedCompany.company_code,
@ -2392,8 +2206,17 @@ export const updateCompany = async (
};
res.status(200).json(response);
} finally {
await client.end();
} catch (updateError: any) {
if (updateError.code === "P2025") {
// Prisma error code for "Record to update not found"
res.status(404).json({
success: false,
message: "해당 회사를 찾을 수 없습니다.",
errorCode: "COMPANY_NOT_FOUND",
});
return;
}
throw updateError;
}
} catch (error) {
logger.error("회사 정보 수정 실패", { error, body: req.body });
@ -2639,9 +2462,6 @@ export const resetUserPassword = async (
return;
}
// 복잡한 암호화 로직은 직접 쿼리 사용
const client = new Client({ connectionString: config.databaseUrl });
try {
// 1. Prisma ORM으로 사용자 존재 여부 확인
const currentUser = await prisma.user_info.findUnique({
@ -2664,8 +2484,6 @@ export const resetUserPassword = async (
return;
}
await client.connect();
// 2. 비밀번호 암호화 (기존 Java 로직과 동일)
let encryptedPassword: string;
try {
@ -2693,31 +2511,18 @@ export const resetUserPassword = async (
return;
}
// 3. 비밀번호 업데이트 실행
const updateResult = await client.query(
"UPDATE user_info SET user_password = $1 WHERE user_id = $2",
[encryptedPassword, userId]
);
// 3. Prisma ORM으로 비밀번호 업데이트 실행
const updateResult = await prisma.user_info.update({
where: {
user_id: userId,
},
data: {
user_password: encryptedPassword,
},
});
if (updateResult.rowCount && updateResult.rowCount > 0) {
// 4. 이력 저장 (선택적)
try {
const writer = req.user?.userId || "system";
await client.query(
`
INSERT INTO user_info_history
(sabun, user_id, user_name, dept_code, dept_name, user_type_name, history_type, writer, regdate, status)
VALUES ('', $1, $2, '', '', '', '비밀번호 초기화', $3, NOW(), '')
`,
[userId, currentUser.user_name || userId, writer]
);
} catch (historyError) {
logger.warn("비밀번호 초기화 이력 저장 실패", {
error: historyError,
userId,
});
// 이력 저장 실패해도 비밀번호 초기화는 성공으로 처리
}
if (updateResult) {
// 이력 저장은 user_info_history 테이블이 @@ignore 상태이므로 생략
logger.info("비밀번호 초기화 성공", {
userId,
@ -2749,7 +2554,5 @@ export const resetUserPassword = async (
message: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
msg: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
});
} finally {
await client.end();
}
};

View File

@ -333,23 +333,36 @@ export class AdminService {
try {
logger.info(`AdminService.getMenuInfo 시작 - menuId: ${menuId}`);
// menu_info 모델이 @@ignore로 설정되어 있으므로 $queryRaw 사용
const menuInfo = await prisma.$queryRaw<any[]>`
SELECT
MI.*,
COALESCE(CM.COMPANY_NAME, '미지정') AS COMPANY_NAME
FROM MENU_INFO MI
LEFT JOIN COMPANY_MNG CM ON MI.COMPANY_CODE = CM.COMPANY_CODE
WHERE MI.OBJID = ${parseInt(menuId)}::numeric
LIMIT 1
`;
// Prisma ORM을 사용한 메뉴 정보 조회 (회사 정보 포함)
const menuInfo = await prisma.menu_info.findUnique({
where: {
objid: Number(menuId),
},
include: {
company: {
select: {
company_name: true,
},
},
},
});
if (!menuInfo || menuInfo.length === 0) {
if (!menuInfo) {
return null;
}
logger.info("메뉴 정보 조회 결과:", menuInfo[0]);
return menuInfo[0];
// 응답 형식 조정 (기존 형식과 호환성 유지)
const result = {
...menuInfo,
objid: menuInfo.objid.toString(), // BigInt를 문자열로 변환
menu_type: menuInfo.menu_type?.toString(),
parent_obj_id: menuInfo.parent_obj_id?.toString(),
seq: menuInfo.seq?.toString(),
company_name: menuInfo.company?.company_name || "미지정",
};
logger.info("메뉴 정보 조회 결과:", result);
return result;
} catch (error) {
logger.error("AdminService.getMenuInfo 오류:", error);
throw error;

View File

@ -155,23 +155,35 @@ export class AuthService {
return null;
}
// 권한 정보 조회 (기존 Java 로직과 동일)
const authInfo = await prisma.$queryRaw<Array<{ auth_name: string }>>`
SELECT ARRAY_TO_STRING(ARRAY_AGG(AM.AUTH_NAME), ',') AS AUTH_NAME
FROM AUTHORITY_MASTER AM, AUTHORITY_SUB_USER ASU
WHERE AM.OBJID = ASU.MASTER_OBJID
AND ASU.USER_ID = ${userId}
GROUP BY ASU.USER_ID
`;
// 권한 정보 조회 (Prisma ORM 사용)
const authInfo = await prisma.authority_sub_user.findMany({
where: {
user_id: userId,
},
include: {
authority_master: {
select: {
auth_name: true,
},
},
},
});
// 회사 정보 조회 (기존 Java 로직과 동일)
const companyInfo = await prisma.$queryRaw<
Array<{ company_name: string }>
>`
SELECT COALESCE(CM.COMPANY_NAME, '미지정') AS COMPANY_NAME
FROM COMPANY_MNG CM
WHERE CM.COMPANY_CODE = ${userInfo.company_code || "ILSHIN"}
`;
// 권한명들을 쉼표로 연결
const authNames = authInfo
.filter((auth) => auth.authority_master?.auth_name)
.map((auth) => auth.authority_master!.auth_name!)
.join(",");
// 회사 정보 조회 (Prisma ORM 사용으로 변경)
const companyInfo = await prisma.company_mng.findFirst({
where: {
company_code: userInfo.company_code || "ILSHIN",
},
select: {
company_name: true,
},
});
// PersonBean 형태로 변환 (null 값을 undefined로 변환)
const personBean: PersonBean = {
@ -189,9 +201,11 @@ export class AuthService {
userType: userInfo.user_type || undefined,
userTypeName: userInfo.user_type_name || undefined,
partnerObjid: userInfo.partner_objid || undefined,
authName: authInfo.length > 0 ? authInfo[0].auth_name : undefined,
authName: authNames || undefined,
companyCode: userInfo.company_code || "ILSHIN",
photo: userInfo.photo ? `data:image/jpeg;base64,${userInfo.photo.toString('base64')}` : undefined,
photo: userInfo.photo
? `data:image/jpeg;base64,${userInfo.photo.toString("base64")}`
: undefined,
locale: userInfo.locale || "KR",
};