주요기능 Prisma ORM으로 변경
This commit is contained in:
parent
14218bad11
commit
cb88faa68e
|
|
@ -180,9 +180,7 @@ export const getUserList = async (req: AuthenticatedRequest, res: Response) => {
|
||||||
const {
|
const {
|
||||||
page = 1,
|
page = 1,
|
||||||
countPerPage = 20,
|
countPerPage = 20,
|
||||||
// 통합 검색 (전체 필드 대상)
|
|
||||||
search,
|
search,
|
||||||
// 고급 검색 (개별 필드별)
|
|
||||||
searchField,
|
searchField,
|
||||||
searchValue,
|
searchValue,
|
||||||
search_sabun,
|
search_sabun,
|
||||||
|
|
@ -193,125 +191,97 @@ export const getUserList = async (req: AuthenticatedRequest, res: Response) => {
|
||||||
search_userName,
|
search_userName,
|
||||||
search_tel,
|
search_tel,
|
||||||
search_email,
|
search_email,
|
||||||
// 기존 필터
|
|
||||||
deptCode,
|
deptCode,
|
||||||
status,
|
status,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
// Prisma ORM을 사용한 사용자 목록 조회
|
||||||
const client = new Client({
|
let whereConditions: any = {};
|
||||||
connectionString: config.databaseUrl,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 기본 사용자 목록 조회 쿼리
|
|
||||||
let query = `
|
|
||||||
SELECT
|
|
||||||
u.sabun,
|
|
||||||
u.user_id,
|
|
||||||
u.user_name,
|
|
||||||
u.user_name_eng,
|
|
||||||
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.company_code,
|
|
||||||
u.locale,
|
|
||||||
d.dept_name as dept_name_full
|
|
||||||
FROM user_info u
|
|
||||||
LEFT JOIN dept_info d ON u.dept_code = d.dept_code
|
|
||||||
WHERE 1=1
|
|
||||||
`;
|
|
||||||
|
|
||||||
const queryParams: any[] = [];
|
|
||||||
let paramIndex = 1;
|
|
||||||
let searchType = "none";
|
let searchType = "none";
|
||||||
|
|
||||||
// 검색 조건 처리
|
// 검색 조건 처리
|
||||||
if (search && typeof search === "string" && search.trim()) {
|
if (search && typeof search === "string" && search.trim()) {
|
||||||
// 통합 검색 (우선순위: 모든 주요 필드에서 검색)
|
// 통합 검색
|
||||||
searchType = "unified";
|
searchType = "unified";
|
||||||
const searchTerm = search.trim();
|
const searchTerm = search.trim();
|
||||||
|
|
||||||
query += ` AND (
|
whereConditions.OR = [
|
||||||
UPPER(COALESCE(u.sabun, '')) LIKE UPPER($${paramIndex}) OR
|
{ sabun: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.user_type_name, '')) LIKE UPPER($${paramIndex}) OR
|
{ user_type_name: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.dept_name, '')) LIKE UPPER($${paramIndex}) OR
|
{ dept_name: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.position_name, '')) LIKE UPPER($${paramIndex}) OR
|
{ position_name: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.user_id, '')) LIKE UPPER($${paramIndex}) OR
|
{ user_id: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.user_name, '')) LIKE UPPER($${paramIndex}) OR
|
{ user_name: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.tel, '')) LIKE UPPER($${paramIndex}) OR
|
{ tel: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.cell_phone, '')) LIKE UPPER($${paramIndex}) OR
|
{ cell_phone: { contains: searchTerm, mode: "insensitive" } },
|
||||||
UPPER(COALESCE(u.email, '')) LIKE UPPER($${paramIndex})
|
{ email: { contains: searchTerm, mode: "insensitive" } },
|
||||||
)`;
|
];
|
||||||
queryParams.push(`%${searchTerm}%`);
|
|
||||||
paramIndex++;
|
|
||||||
|
|
||||||
logger.info("통합 검색 실행", { searchTerm });
|
logger.info("통합 검색 실행", { searchTerm });
|
||||||
} else if (searchField && searchValue) {
|
} else if (searchField && searchValue) {
|
||||||
// 단일 필드 검색
|
// 단일 필드 검색
|
||||||
searchType = "single";
|
searchType = "single";
|
||||||
const fieldMap: { [key: string]: string } = {
|
const fieldMap: { [key: string]: string } = {
|
||||||
sabun: "u.sabun",
|
sabun: "sabun",
|
||||||
companyName: "u.user_type_name",
|
companyName: "user_type_name",
|
||||||
deptName: "u.dept_name",
|
deptName: "dept_name",
|
||||||
positionName: "u.position_name",
|
positionName: "position_name",
|
||||||
userId: "u.user_id",
|
userId: "user_id",
|
||||||
userName: "u.user_name",
|
userName: "user_name",
|
||||||
tel: "u.tel",
|
tel: "tel",
|
||||||
cellPhone: "u.cell_phone",
|
cellPhone: "cell_phone",
|
||||||
email: "u.email",
|
email: "email",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fieldMap[searchField as string]) {
|
if (fieldMap[searchField as string]) {
|
||||||
if (searchField === "tel") {
|
if (searchField === "tel") {
|
||||||
// 전화번호는 TEL과 CELL_PHONE 모두 검색
|
whereConditions.OR = [
|
||||||
query += ` AND (UPPER(u.tel) LIKE UPPER($${paramIndex}) OR UPPER(u.cell_phone) LIKE UPPER($${paramIndex}))`;
|
{ tel: { contains: searchValue as string, mode: "insensitive" } },
|
||||||
|
{
|
||||||
|
cell_phone: {
|
||||||
|
contains: searchValue as string,
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
} else {
|
} else {
|
||||||
query += ` AND UPPER(${fieldMap[searchField as string]}) LIKE UPPER($${paramIndex})`;
|
whereConditions[fieldMap[searchField as string]] = {
|
||||||
|
contains: searchValue as string,
|
||||||
|
mode: "insensitive",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
queryParams.push(`%${searchValue}%`);
|
|
||||||
paramIndex++;
|
|
||||||
|
|
||||||
logger.info("단일 필드 검색 실행", { searchField, searchValue });
|
logger.info("단일 필드 검색 실행", { searchField, searchValue });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 고급 검색 (개별 필드별 AND 조건)
|
// 고급 검색 (개별 필드별 AND 조건)
|
||||||
const advancedSearchFields = [
|
const advancedSearchFields = [
|
||||||
{ param: search_sabun, field: "u.sabun" },
|
{ param: search_sabun, field: "sabun" },
|
||||||
{ param: search_companyName, field: "u.user_type_name" },
|
{ param: search_companyName, field: "user_type_name" },
|
||||||
{ param: search_deptName, field: "u.dept_name" },
|
{ param: search_deptName, field: "dept_name" },
|
||||||
{ param: search_positionName, field: "u.position_name" },
|
{ param: search_positionName, field: "position_name" },
|
||||||
{ param: search_userId, field: "u.user_id" },
|
{ param: search_userId, field: "user_id" },
|
||||||
{ param: search_userName, field: "u.user_name" },
|
{ param: search_userName, field: "user_name" },
|
||||||
{ param: search_email, field: "u.email" },
|
{ param: search_email, field: "email" },
|
||||||
];
|
];
|
||||||
|
|
||||||
let hasAdvancedSearch = false;
|
let hasAdvancedSearch = false;
|
||||||
|
|
||||||
for (const { param, field } of advancedSearchFields) {
|
for (const { param, field } of advancedSearchFields) {
|
||||||
if (param && typeof param === "string" && param.trim()) {
|
if (param && typeof param === "string" && param.trim()) {
|
||||||
query += ` AND UPPER(${field}) LIKE UPPER($${paramIndex})`;
|
whereConditions[field] = {
|
||||||
queryParams.push(`%${param.trim()}%`);
|
contains: param.trim(),
|
||||||
paramIndex++;
|
mode: "insensitive",
|
||||||
|
};
|
||||||
hasAdvancedSearch = true;
|
hasAdvancedSearch = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 전화번호 검색 (TEL 또는 CELL_PHONE)
|
// 전화번호 검색
|
||||||
if (search_tel && typeof search_tel === "string" && search_tel.trim()) {
|
if (search_tel && typeof search_tel === "string" && search_tel.trim()) {
|
||||||
query += ` AND (UPPER(u.tel) LIKE UPPER($${paramIndex}) OR UPPER(u.cell_phone) LIKE UPPER($${paramIndex}))`;
|
whereConditions.OR = [
|
||||||
queryParams.push(`%${search_tel.trim()}%`);
|
{ tel: { contains: search_tel.trim(), mode: "insensitive" } },
|
||||||
paramIndex++;
|
{ cell_phone: { contains: search_tel.trim(), mode: "insensitive" } },
|
||||||
|
];
|
||||||
hasAdvancedSearch = true;
|
hasAdvancedSearch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,74 +302,53 @@ export const getUserList = async (req: AuthenticatedRequest, res: Response) => {
|
||||||
|
|
||||||
// 기존 필터들
|
// 기존 필터들
|
||||||
if (deptCode) {
|
if (deptCode) {
|
||||||
query += ` AND u.dept_code = $${paramIndex}`;
|
whereConditions.dept_code = deptCode as string;
|
||||||
queryParams.push(deptCode);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
query += ` AND u.status = $${paramIndex}`;
|
whereConditions.status = status as string;
|
||||||
queryParams.push(status);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 정렬
|
// 총 개수 조회
|
||||||
query += ` ORDER BY u.regdate DESC, u.user_name`;
|
const totalCount = await prisma.user_info.count({
|
||||||
|
where: whereConditions,
|
||||||
// 페이징 파라미터 제외한 카운트용 파라미터
|
});
|
||||||
const countParams = [...queryParams];
|
|
||||||
|
|
||||||
// 총 개수 조회를 위해 기존 쿼리를 COUNT로 변환
|
|
||||||
const countQuery = query
|
|
||||||
.replace(/SELECT[\s\S]*?FROM/i, "SELECT COUNT(*) as total FROM")
|
|
||||||
.replace(/ORDER BY.*$/i, "");
|
|
||||||
|
|
||||||
const countResult = await client.query(countQuery, countParams);
|
|
||||||
const totalCount = parseInt(countResult.rows[0].total);
|
|
||||||
|
|
||||||
// 페이징 적용
|
|
||||||
const offset = (Number(page) - 1) * Number(countPerPage);
|
|
||||||
query += ` LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
|
|
||||||
queryParams.push(Number(countPerPage), offset);
|
|
||||||
|
|
||||||
// 사용자 목록 조회
|
// 사용자 목록 조회
|
||||||
const result = await client.query(query, queryParams);
|
const users = await prisma.user_info.findMany({
|
||||||
const users = result.rows;
|
where: whereConditions,
|
||||||
|
orderBy: [{ regdate: "desc" }, { user_name: "asc" }],
|
||||||
// 디버깅: 원본 데이터베이스 조회 결과 로깅
|
skip: (Number(page) - 1) * Number(countPerPage),
|
||||||
logger.info("=== 원본 데이터베이스 조회 결과 ===");
|
take: Number(countPerPage),
|
||||||
logger.info("총 조회된 사용자 수:", users.length);
|
select: {
|
||||||
if (users.length > 0) {
|
sabun: true,
|
||||||
logger.info("첫 번째 사용자 원본 데이터:", {
|
user_id: true,
|
||||||
user_id: users[0].user_id,
|
user_name: true,
|
||||||
user_name: users[0].user_name,
|
user_name_eng: true,
|
||||||
user_name_eng: users[0].user_name_eng,
|
dept_code: true,
|
||||||
dept_code: users[0].dept_code,
|
dept_name: true,
|
||||||
dept_name: users[0].dept_name,
|
position_code: true,
|
||||||
position_code: users[0].position_code,
|
position_name: true,
|
||||||
position_name: users[0].position_name,
|
email: true,
|
||||||
email: users[0].email,
|
tel: true,
|
||||||
tel: users[0].tel,
|
cell_phone: true,
|
||||||
cell_phone: users[0].cell_phone,
|
user_type: true,
|
||||||
user_type: users[0].user_type,
|
user_type_name: true,
|
||||||
user_type_name: users[0].user_type_name,
|
regdate: true,
|
||||||
status: users[0].status,
|
status: true,
|
||||||
company_code: users[0].company_code,
|
company_code: true,
|
||||||
locale: users[0].locale,
|
locale: true,
|
||||||
regdate: users[0].regdate,
|
},
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// 응답 데이터 가공
|
// 응답 데이터 가공
|
||||||
const processedUsers = users.map((user) => {
|
const processedUsers = users.map((user) => ({
|
||||||
// 디버깅: 각 필드별 값 확인
|
|
||||||
const processedUser = {
|
|
||||||
userId: user.user_id,
|
userId: user.user_id,
|
||||||
userName: user.user_name,
|
userName: user.user_name,
|
||||||
userNameEng: user.user_name_eng || null,
|
userNameEng: user.user_name_eng || null,
|
||||||
sabun: user.sabun || null,
|
sabun: user.sabun || null,
|
||||||
deptCode: user.dept_code || null,
|
deptCode: user.dept_code || null,
|
||||||
deptName: user.dept_name || user.dept_name_full || null,
|
deptName: user.dept_name || null,
|
||||||
positionCode: user.position_code || null,
|
positionCode: user.position_code || null,
|
||||||
positionName: user.position_name || null,
|
positionName: user.position_name || null,
|
||||||
email: user.email || null,
|
email: user.email || null,
|
||||||
|
|
@ -410,49 +359,14 @@ export const getUserList = async (req: AuthenticatedRequest, res: Response) => {
|
||||||
status: user.status || "active",
|
status: user.status || "active",
|
||||||
companyCode: user.company_code || null,
|
companyCode: user.company_code || null,
|
||||||
locale: user.locale || null,
|
locale: user.locale || null,
|
||||||
regDate: user.regdate
|
regDate: user.regdate ? user.regdate.toISOString().split("T")[0] : null,
|
||||||
? user.regdate.toISOString().split("T")[0]
|
}));
|
||||||
: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 빈 문자열을 null로 변환
|
|
||||||
Object.keys(processedUser).forEach((key) => {
|
|
||||||
if (processedUser[key as keyof typeof processedUser] === "") {
|
|
||||||
(processedUser as any)[key] = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 디버깅: 가공된 데이터 로깅
|
|
||||||
logger.info(`사용자 ${user.user_id} 가공 결과:`, {
|
|
||||||
원본: {
|
|
||||||
user_id: user.user_id,
|
|
||||||
user_name: user.user_name,
|
|
||||||
user_name_eng: user.user_name_eng,
|
|
||||||
dept_code: user.dept_code,
|
|
||||||
dept_name: user.dept_name,
|
|
||||||
position_code: user.position_code,
|
|
||||||
position_name: user.position_name,
|
|
||||||
email: user.email,
|
|
||||||
tel: user.tel,
|
|
||||||
cell_phone: user.cell_phone,
|
|
||||||
user_type: user.user_type,
|
|
||||||
user_type_name: user.user_type_name,
|
|
||||||
status: user.status,
|
|
||||||
company_code: user.company_code,
|
|
||||||
locale: user.locale,
|
|
||||||
regdate: user.regdate,
|
|
||||||
},
|
|
||||||
가공후: processedUser,
|
|
||||||
});
|
|
||||||
|
|
||||||
return processedUser;
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
success: true,
|
success: true,
|
||||||
data: processedUsers,
|
data: processedUsers,
|
||||||
total: totalCount,
|
total: totalCount,
|
||||||
searchType, // 검색 타입 정보 (unified, single, advanced, none)
|
searchType,
|
||||||
pagination: {
|
pagination: {
|
||||||
page: Number(page),
|
page: Number(page),
|
||||||
limit: Number(countPerPage),
|
limit: Number(countPerPage),
|
||||||
|
|
@ -470,9 +384,6 @@ export const getUserList = async (req: AuthenticatedRequest, res: Response) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("사용자 목록 조회 실패", { error });
|
logger.error("사용자 목록 조회 실패", { error });
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -506,8 +417,6 @@ export const getUserLocale = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
// 데이터베이스에서 사용자 로케일 조회
|
// 데이터베이스에서 사용자 로케일 조회
|
||||||
const prisma = (await import("../config/database")).default;
|
|
||||||
|
|
||||||
const userInfo = await prisma.user_info.findFirst({
|
const userInfo = await prisma.user_info.findFirst({
|
||||||
where: {
|
where: {
|
||||||
user_id: req.user.userId,
|
user_id: req.user.userId,
|
||||||
|
|
@ -587,8 +496,6 @@ export const setUserLocale = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
// 데이터베이스에 사용자 로케일 저장
|
// 데이터베이스에 사용자 로케일 저장
|
||||||
const prisma = (await import("../config/database")).default;
|
|
||||||
|
|
||||||
await prisma.user_info.update({
|
await prisma.user_info.update({
|
||||||
where: {
|
where: {
|
||||||
user_id: req.user.userId,
|
user_id: req.user.userId,
|
||||||
|
|
@ -1473,35 +1380,23 @@ export async function getCompanyListFromDB(
|
||||||
res: Response
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
logger.info("회사 목록 조회 요청 (DB)", { user: req.user });
|
logger.info("회사 목록 조회 요청 (Prisma)", { user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
// Prisma ORM으로 회사 목록 조회
|
||||||
const client = new Client({
|
const companies = await prisma.company_mng.findMany({
|
||||||
connectionString:
|
select: {
|
||||||
process.env.DATABASE_URL ||
|
company_code: true,
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
company_name: true,
|
||||||
|
writer: true,
|
||||||
|
regdate: true,
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
regdate: "desc",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.connect();
|
logger.info("회사 목록 조회 성공 (Prisma)", { count: companies.length });
|
||||||
|
|
||||||
// company_mng 테이블에서 회사 목록 조회
|
|
||||||
const query = `
|
|
||||||
SELECT
|
|
||||||
company_code,
|
|
||||||
company_name,
|
|
||||||
writer,
|
|
||||||
regdate,
|
|
||||||
status
|
|
||||||
FROM company_mng
|
|
||||||
ORDER BY regdate DESC
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await client.query(query);
|
|
||||||
const companies = result.rows;
|
|
||||||
|
|
||||||
await client.end();
|
|
||||||
|
|
||||||
logger.info("회사 목록 조회 성공 (DB)", { count: companies.length });
|
|
||||||
|
|
||||||
const response: ApiResponse<any> = {
|
const response: ApiResponse<any> = {
|
||||||
success: true,
|
success: true,
|
||||||
|
|
@ -1512,7 +1407,7 @@ export async function getCompanyListFromDB(
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("회사 목록 조회 실패 (DB):", error);
|
logger.error("회사 목록 조회 실패 (Prisma):", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "회사 목록 조회 중 오류가 발생했습니다.",
|
message: "회사 목록 조회 중 오류가 발생했습니다.",
|
||||||
|
|
@ -1846,7 +1741,7 @@ export const getUserInfo = async (req: AuthenticatedRequest, res: Response) => {
|
||||||
export const checkDuplicateUserId = async (
|
export const checkDuplicateUserId = async (
|
||||||
req: AuthenticatedRequest,
|
req: AuthenticatedRequest,
|
||||||
res: Response
|
res: Response
|
||||||
) => {
|
): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const { userId } = req.body;
|
const { userId } = req.body;
|
||||||
logger.info(`사용자 ID 중복 체크 요청 - userId: ${userId}`, {
|
logger.info(`사용자 ID 중복 체크 요청 - userId: ${userId}`, {
|
||||||
|
|
@ -1865,27 +1760,18 @@ export const checkDuplicateUserId = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
// Prisma ORM으로 사용자 ID 중복 체크
|
||||||
const client = new Client({
|
const existingUser = await prisma.user_info.findUnique({
|
||||||
connectionString:
|
where: {
|
||||||
process.env.DATABASE_URL ||
|
user_id: userId,
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
},
|
||||||
|
select: {
|
||||||
|
user_id: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.connect();
|
const isDuplicate = !!existingUser;
|
||||||
|
const count = isDuplicate ? 1 : 0;
|
||||||
try {
|
|
||||||
// 사용자 ID 중복 체크 쿼리
|
|
||||||
const query = `
|
|
||||||
SELECT COUNT(*) as count
|
|
||||||
FROM user_info
|
|
||||||
WHERE user_id = $1
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await client.query(query, [userId]);
|
|
||||||
const count = parseInt(result.rows[0].count);
|
|
||||||
|
|
||||||
const isDuplicate = count > 0;
|
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
success: true,
|
success: true,
|
||||||
|
|
@ -1906,9 +1792,6 @@ export const checkDuplicateUserId = async (
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("사용자 ID 중복 체크 실패", {
|
logger.error("사용자 ID 중복 체크 실패", {
|
||||||
error,
|
error,
|
||||||
|
|
@ -2112,20 +1995,25 @@ export const changeUserStatus = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 복잡한 상태 변경은 직접 쿼리 사용
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
connectionString: config.databaseUrl,
|
connectionString: config.databaseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.connect();
|
// 1. Prisma ORM으로 사용자 존재 여부 확인
|
||||||
|
const currentUser = await prisma.user_info.findUnique({
|
||||||
|
where: {
|
||||||
|
user_id: userId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
user_id: true,
|
||||||
|
user_name: true,
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// 1. 사용자 존재 여부 확인
|
if (!currentUser) {
|
||||||
const userCheckResult = await client.query(
|
|
||||||
"SELECT user_id, user_name, status FROM user_info WHERE user_id = $1",
|
|
||||||
[userId]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (userCheckResult.rows.length === 0) {
|
|
||||||
res.status(404).json({
|
res.status(404).json({
|
||||||
result: false,
|
result: false,
|
||||||
msg: "사용자를 찾을 수 없습니다.",
|
msg: "사용자를 찾을 수 없습니다.",
|
||||||
|
|
@ -2133,7 +2021,7 @@ export const changeUserStatus = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentUser = userCheckResult.rows[0];
|
await client.connect();
|
||||||
|
|
||||||
// 2. 상태 변경 쿼리 실행
|
// 2. 상태 변경 쿼리 실행
|
||||||
let updateQuery = `
|
let updateQuery = `
|
||||||
|
|
@ -2387,7 +2275,23 @@ export const createCompany = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
// Prisma ORM으로 회사명 중복 체크
|
||||||
|
const existingCompany = await prisma.company_mng.findFirst({
|
||||||
|
where: {
|
||||||
|
company_name: company_name.trim(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingCompany) {
|
||||||
|
res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: "이미 등록된 회사명입니다.",
|
||||||
|
errorCode: "COMPANY_NAME_DUPLICATE",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostgreSQL 클라이언트 생성 (복잡한 코드 생성 쿼리용)
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
connectionString:
|
connectionString:
|
||||||
process.env.DATABASE_URL ||
|
process.env.DATABASE_URL ||
|
||||||
|
|
@ -2397,26 +2301,6 @@ export const createCompany = async (
|
||||||
await client.connect();
|
await client.connect();
|
||||||
|
|
||||||
try {
|
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, ...)
|
// 회사 코드 생성 (COMPANY_1, COMPANY_2, ...)
|
||||||
const codeQuery = `
|
const codeQuery = `
|
||||||
SELECT COALESCE(MAX(CAST(SUBSTRING(company_code FROM 9) AS INTEGER)), 0) + 1 as next_number
|
SELECT COALESCE(MAX(CAST(SUBSTRING(company_code FROM 9) AS INTEGER)), 0) + 1 as next_number
|
||||||
|
|
@ -2622,26 +2506,18 @@ export const deleteCompany = async (
|
||||||
user: req.user,
|
user: req.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
// Prisma ORM으로 회사 존재 여부 확인
|
||||||
const client = new Client({
|
const existingCompany = await prisma.company_mng.findUnique({
|
||||||
connectionString:
|
where: {
|
||||||
process.env.DATABASE_URL ||
|
company_code: companyCode,
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
},
|
||||||
|
select: {
|
||||||
|
company_code: true,
|
||||||
|
company_name: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.connect();
|
if (!existingCompany) {
|
||||||
|
|
||||||
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({
|
res.status(404).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "해당 회사를 찾을 수 없습니다.",
|
message: "해당 회사를 찾을 수 없습니다.",
|
||||||
|
|
@ -2650,17 +2526,16 @@ export const deleteCompany = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 회사 삭제
|
// Prisma ORM으로 회사 삭제
|
||||||
const deleteQuery = `
|
await prisma.company_mng.delete({
|
||||||
DELETE FROM company_mng
|
where: {
|
||||||
WHERE company_code = $1
|
company_code: companyCode,
|
||||||
`;
|
},
|
||||||
|
});
|
||||||
await client.query(deleteQuery, [companyCode]);
|
|
||||||
|
|
||||||
logger.info("회사 삭제 성공", {
|
logger.info("회사 삭제 성공", {
|
||||||
companyCode,
|
companyCode,
|
||||||
companyName: checkResult.rows[0].company_name,
|
companyName: existingCompany.company_name,
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
|
|
@ -2668,14 +2543,11 @@ export const deleteCompany = async (
|
||||||
message: "회사가 삭제되었습니다.",
|
message: "회사가 삭제되었습니다.",
|
||||||
data: {
|
data: {
|
||||||
company_code: companyCode,
|
company_code: companyCode,
|
||||||
company_name: checkResult.rows[0].company_name,
|
company_name: existingCompany.company_name,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("회사 삭제 실패", { error });
|
logger.error("회사 삭제 실패", { error });
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -2816,8 +2688,7 @@ export const updateProfile = async (
|
||||||
export const resetUserPassword = async (
|
export const resetUserPassword = async (
|
||||||
req: AuthenticatedRequest,
|
req: AuthenticatedRequest,
|
||||||
res: Response
|
res: Response
|
||||||
) => {
|
): Promise<void> => {
|
||||||
try {
|
|
||||||
const { userId, newPassword } = req.body;
|
const { userId, newPassword } = req.body;
|
||||||
|
|
||||||
logger.info("비밀번호 초기화 요청", { userId, user: req.user });
|
logger.info("비밀번호 초기화 요청", { userId, user: req.user });
|
||||||
|
|
@ -2852,17 +2723,22 @@ export const resetUserPassword = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 복잡한 암호화 로직은 직접 쿼리 사용
|
||||||
const client = new Client({ connectionString: config.databaseUrl });
|
const client = new Client({ connectionString: config.databaseUrl });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.connect();
|
// 1. Prisma ORM으로 사용자 존재 여부 확인
|
||||||
|
const currentUser = await prisma.user_info.findUnique({
|
||||||
|
where: {
|
||||||
|
user_id: userId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
user_id: true,
|
||||||
|
user_name: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// 1. 사용자 존재 여부 확인
|
if (!currentUser) {
|
||||||
const userCheckResult = await client.query(
|
|
||||||
"SELECT user_id, user_name FROM user_info WHERE user_id = $1",
|
|
||||||
[userId]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (userCheckResult.rows.length === 0) {
|
|
||||||
res.status(404).json({
|
res.status(404).json({
|
||||||
success: false,
|
success: false,
|
||||||
result: false,
|
result: false,
|
||||||
|
|
@ -2872,7 +2748,7 @@ export const resetUserPassword = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentUser = userCheckResult.rows[0];
|
await client.connect();
|
||||||
|
|
||||||
// 2. 비밀번호 암호화 (기존 Java 로직과 동일)
|
// 2. 비밀번호 암호화 (기존 Java 로직과 동일)
|
||||||
let encryptedPassword: string;
|
let encryptedPassword: string;
|
||||||
|
|
@ -2946,13 +2822,10 @@ export const resetUserPassword = async (
|
||||||
msg: "사용자 정보를 찾을 수 없거나 비밀번호 변경에 실패했습니다.",
|
msg: "사용자 정보를 찾을 수 없거나 비밀번호 변경에 실패했습니다.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("비밀번호 초기화 중 오류 발생", {
|
logger.error("비밀번호 초기화 중 오류 발생", {
|
||||||
error,
|
error,
|
||||||
userId: req.body.userId,
|
userId,
|
||||||
});
|
});
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
|
|
@ -2960,5 +2833,7 @@ export const resetUserPassword = async (
|
||||||
message: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
|
message: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
|
||||||
msg: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
|
msg: "비밀번호 초기화 중 시스템 오류가 발생했습니다.",
|
||||||
});
|
});
|
||||||
|
} finally {
|
||||||
|
await client.end();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { Request, Response } from "express";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { AuthenticatedRequest } from "../types/auth";
|
import { AuthenticatedRequest } from "../types/auth";
|
||||||
import { MultiLangService } from "../services/multilangService";
|
import { MultiLangService } from "../services/multilangService";
|
||||||
import { Client } from "pg";
|
|
||||||
import {
|
import {
|
||||||
CreateLanguageRequest,
|
CreateLanguageRequest,
|
||||||
UpdateLanguageRequest,
|
UpdateLanguageRequest,
|
||||||
|
|
@ -25,17 +24,7 @@ export const getLanguages = async (
|
||||||
try {
|
try {
|
||||||
logger.info("언어 목록 조회 요청", { user: req.user });
|
logger.info("언어 목록 조회 요청", { user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const languages = await multiLangService.getLanguages();
|
const languages = await multiLangService.getLanguages();
|
||||||
|
|
||||||
const response: ApiResponse<any[]> = {
|
const response: ApiResponse<any[]> = {
|
||||||
|
|
@ -45,9 +34,6 @@ export const getLanguages = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("언어 목록 조회 실패:", error);
|
logger.error("언어 목록 조회 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -90,17 +76,7 @@ export const createLanguage = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const createdLanguage = await multiLangService.createLanguage({
|
const createdLanguage = await multiLangService.createLanguage({
|
||||||
...languageData,
|
...languageData,
|
||||||
createdBy: req.user?.userId || "system",
|
createdBy: req.user?.userId || "system",
|
||||||
|
|
@ -114,9 +90,6 @@ export const createLanguage = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(201).json(response);
|
res.status(201).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("언어 생성 실패:", error);
|
logger.error("언어 생성 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -144,17 +117,7 @@ export const updateLanguage = async (
|
||||||
|
|
||||||
logger.info("언어 수정 요청", { langCode, languageData, user: req.user });
|
logger.info("언어 수정 요청", { langCode, languageData, user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const updatedLanguage = await multiLangService.updateLanguage(langCode, {
|
const updatedLanguage = await multiLangService.updateLanguage(langCode, {
|
||||||
...languageData,
|
...languageData,
|
||||||
updatedBy: req.user?.userId || "system",
|
updatedBy: req.user?.userId || "system",
|
||||||
|
|
@ -167,9 +130,6 @@ export const updateLanguage = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("언어 수정 실패:", error);
|
logger.error("언어 수정 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -195,17 +155,7 @@ export const toggleLanguage = async (
|
||||||
const { langCode } = req.params;
|
const { langCode } = req.params;
|
||||||
logger.info("언어 상태 토글 요청", { langCode, user: req.user });
|
logger.info("언어 상태 토글 요청", { langCode, user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const result = await multiLangService.toggleLanguage(langCode);
|
const result = await multiLangService.toggleLanguage(langCode);
|
||||||
|
|
||||||
const response: ApiResponse<string> = {
|
const response: ApiResponse<string> = {
|
||||||
|
|
@ -215,9 +165,6 @@ export const toggleLanguage = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("언어 상태 토글 실패:", error);
|
logger.error("언어 상태 토글 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -246,17 +193,7 @@ export const getLangKeys = async (
|
||||||
user: req.user,
|
user: req.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const langKeys = await multiLangService.getLangKeys({
|
const langKeys = await multiLangService.getLangKeys({
|
||||||
companyCode: companyCode as string,
|
companyCode: companyCode as string,
|
||||||
menuCode: menuCode as string,
|
menuCode: menuCode as string,
|
||||||
|
|
@ -271,9 +208,6 @@ export const getLangKeys = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 키 목록 조회 실패:", error);
|
logger.error("다국어 키 목록 조회 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -299,17 +233,7 @@ export const getLangTexts = async (
|
||||||
const { keyId } = req.params;
|
const { keyId } = req.params;
|
||||||
logger.info("다국어 텍스트 조회 요청", { keyId, user: req.user });
|
logger.info("다국어 텍스트 조회 요청", { keyId, user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const langTexts = await multiLangService.getLangTexts(parseInt(keyId));
|
const langTexts = await multiLangService.getLangTexts(parseInt(keyId));
|
||||||
|
|
||||||
const response: ApiResponse<any[]> = {
|
const response: ApiResponse<any[]> = {
|
||||||
|
|
@ -319,9 +243,6 @@ export const getLangTexts = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 텍스트 조회 실패:", error);
|
logger.error("다국어 텍스트 조회 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -360,17 +281,7 @@ export const createLangKey = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const keyId = await multiLangService.createLangKey({
|
const keyId = await multiLangService.createLangKey({
|
||||||
...keyData,
|
...keyData,
|
||||||
createdBy: req.user?.userId || "system",
|
createdBy: req.user?.userId || "system",
|
||||||
|
|
@ -384,9 +295,6 @@ export const createLangKey = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(201).json(response);
|
res.status(201).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 키 생성 실패:", error);
|
logger.error("다국어 키 생성 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -414,17 +322,7 @@ export const updateLangKey = async (
|
||||||
|
|
||||||
logger.info("다국어 키 수정 요청", { keyId, keyData, user: req.user });
|
logger.info("다국어 키 수정 요청", { keyId, keyData, user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
await multiLangService.updateLangKey(parseInt(keyId), {
|
await multiLangService.updateLangKey(parseInt(keyId), {
|
||||||
...keyData,
|
...keyData,
|
||||||
updatedBy: req.user?.userId || "system",
|
updatedBy: req.user?.userId || "system",
|
||||||
|
|
@ -437,9 +335,6 @@ export const updateLangKey = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 키 수정 실패:", error);
|
logger.error("다국어 키 수정 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -465,17 +360,7 @@ export const deleteLangKey = async (
|
||||||
const { keyId } = req.params;
|
const { keyId } = req.params;
|
||||||
logger.info("다국어 키 삭제 요청", { keyId, user: req.user });
|
logger.info("다국어 키 삭제 요청", { keyId, user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
await multiLangService.deleteLangKey(parseInt(keyId));
|
await multiLangService.deleteLangKey(parseInt(keyId));
|
||||||
|
|
||||||
const response: ApiResponse<string> = {
|
const response: ApiResponse<string> = {
|
||||||
|
|
@ -485,9 +370,6 @@ export const deleteLangKey = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 키 삭제 실패:", error);
|
logger.error("다국어 키 삭제 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -513,17 +395,7 @@ export const toggleLangKey = async (
|
||||||
const { keyId } = req.params;
|
const { keyId } = req.params;
|
||||||
logger.info("다국어 키 상태 토글 요청", { keyId, user: req.user });
|
logger.info("다국어 키 상태 토글 요청", { keyId, user: req.user });
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const result = await multiLangService.toggleLangKey(parseInt(keyId));
|
const result = await multiLangService.toggleLangKey(parseInt(keyId));
|
||||||
|
|
||||||
const response: ApiResponse<string> = {
|
const response: ApiResponse<string> = {
|
||||||
|
|
@ -533,9 +405,6 @@ export const toggleLangKey = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 키 상태 토글 실패:", error);
|
logger.error("다국어 키 상태 토글 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -580,17 +449,7 @@ export const saveLangTexts = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
await multiLangService.saveLangTexts(parseInt(keyId), {
|
await multiLangService.saveLangTexts(parseInt(keyId), {
|
||||||
texts: textData.texts.map((text) => ({
|
texts: textData.texts.map((text) => ({
|
||||||
...text,
|
...text,
|
||||||
|
|
@ -606,9 +465,6 @@ export const saveLangTexts = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 텍스트 저장 실패:", error);
|
logger.error("다국어 텍스트 저장 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -654,17 +510,7 @@ export const getUserText = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const langText = await multiLangService.getUserText({
|
const langText = await multiLangService.getUserText({
|
||||||
companyCode,
|
companyCode,
|
||||||
menuCode,
|
menuCode,
|
||||||
|
|
@ -679,9 +525,6 @@ export const getUserText = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("사용자별 다국어 텍스트 조회 실패:", error);
|
logger.error("사용자별 다국어 텍스트 조회 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -713,17 +556,7 @@ export const getLangText = async (
|
||||||
user: req.user,
|
user: req.user,
|
||||||
});
|
});
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const langText = await multiLangService.getLangText(
|
const langText = await multiLangService.getLangText(
|
||||||
companyCode,
|
companyCode,
|
||||||
langKey,
|
langKey,
|
||||||
|
|
@ -737,9 +570,6 @@ export const getLangText = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("특정 키의 다국어 텍스트 조회 실패:", error);
|
logger.error("특정 키의 다국어 텍스트 조회 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -777,17 +607,7 @@ export const deleteLanguage = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
await multiLangService.deleteLanguage(langCode);
|
await multiLangService.deleteLanguage(langCode);
|
||||||
|
|
||||||
const response: ApiResponse<string> = {
|
const response: ApiResponse<string> = {
|
||||||
|
|
@ -797,9 +617,6 @@ export const deleteLanguage = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("언어 삭제 실패:", error);
|
logger.error("언어 삭제 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
@ -866,17 +683,7 @@ export const getBatchTranslations = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const multiLangService = new MultiLangService();
|
||||||
const client = new Client({
|
|
||||||
connectionString:
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
"postgresql://postgres:postgres@localhost:5432/ilshin",
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const multiLangService = new MultiLangService(client);
|
|
||||||
const translations = await multiLangService.getBatchTranslations({
|
const translations = await multiLangService.getBatchTranslations({
|
||||||
companyCode: finalCompanyCode as string,
|
companyCode: finalCompanyCode as string,
|
||||||
menuCode: finalMenuCode as string,
|
menuCode: finalMenuCode as string,
|
||||||
|
|
@ -891,9 +698,6 @@ export const getBatchTranslations = async (
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("다국어 텍스트 배치 조회 실패:", error);
|
logger.error("다국어 텍스트 배치 조회 실패:", error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { Request, Response } from "express";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import { AuthenticatedRequest } from "../types/auth";
|
import { AuthenticatedRequest } from "../types/auth";
|
||||||
import { ApiResponse } from "../types/common";
|
import { ApiResponse } from "../types/common";
|
||||||
import { Client } from "pg";
|
|
||||||
import { TableManagementService } from "../services/tableManagementService";
|
import { TableManagementService } from "../services/tableManagementService";
|
||||||
import {
|
import {
|
||||||
TableInfo,
|
TableInfo,
|
||||||
|
|
@ -23,15 +22,7 @@ export async function getTableList(
|
||||||
try {
|
try {
|
||||||
logger.info("=== 테이블 목록 조회 시작 ===");
|
logger.info("=== 테이블 목록 조회 시작 ===");
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const tableManagementService = new TableManagementService();
|
||||||
const client = new Client({
|
|
||||||
connectionString: process.env.DATABASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tableManagementService = new TableManagementService(client);
|
|
||||||
const tableList = await tableManagementService.getTableList();
|
const tableList = await tableManagementService.getTableList();
|
||||||
|
|
||||||
logger.info(`테이블 목록 조회 결과: ${tableList.length}개`);
|
logger.info(`테이블 목록 조회 결과: ${tableList.length}개`);
|
||||||
|
|
@ -43,9 +34,6 @@ export async function getTableList(
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("테이블 목록 조회 중 오류 발생:", error);
|
logger.error("테이블 목록 조회 중 오류 발생:", error);
|
||||||
|
|
||||||
|
|
@ -86,15 +74,7 @@ export async function getColumnList(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const tableManagementService = new TableManagementService();
|
||||||
const client = new Client({
|
|
||||||
connectionString: process.env.DATABASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tableManagementService = new TableManagementService(client);
|
|
||||||
const columnList = await tableManagementService.getColumnList(tableName);
|
const columnList = await tableManagementService.getColumnList(tableName);
|
||||||
|
|
||||||
logger.info(`컬럼 정보 조회 결과: ${tableName}, ${columnList.length}개`);
|
logger.info(`컬럼 정보 조회 결과: ${tableName}, ${columnList.length}개`);
|
||||||
|
|
@ -106,9 +86,6 @@ export async function getColumnList(
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("컬럼 정보 조회 중 오류 발생:", error);
|
logger.error("컬럼 정보 조회 중 오류 발생:", error);
|
||||||
|
|
||||||
|
|
@ -164,15 +141,7 @@ export async function updateColumnSettings(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const tableManagementService = new TableManagementService();
|
||||||
const client = new Client({
|
|
||||||
connectionString: process.env.DATABASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tableManagementService = new TableManagementService(client);
|
|
||||||
await tableManagementService.updateColumnSettings(
|
await tableManagementService.updateColumnSettings(
|
||||||
tableName,
|
tableName,
|
||||||
columnName,
|
columnName,
|
||||||
|
|
@ -187,9 +156,6 @@ export async function updateColumnSettings(
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("컬럼 설정 업데이트 중 오류 발생:", error);
|
logger.error("컬럼 설정 업데이트 중 오류 발생:", error);
|
||||||
|
|
||||||
|
|
@ -245,15 +211,7 @@ export async function updateAllColumnSettings(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const tableManagementService = new TableManagementService();
|
||||||
const client = new Client({
|
|
||||||
connectionString: process.env.DATABASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tableManagementService = new TableManagementService(client);
|
|
||||||
await tableManagementService.updateAllColumnSettings(
|
await tableManagementService.updateAllColumnSettings(
|
||||||
tableName,
|
tableName,
|
||||||
columnSettings
|
columnSettings
|
||||||
|
|
@ -269,9 +227,6 @@ export async function updateAllColumnSettings(
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("전체 컬럼 설정 일괄 업데이트 중 오류 발생:", error);
|
logger.error("전체 컬럼 설정 일괄 업데이트 중 오류 발생:", error);
|
||||||
|
|
||||||
|
|
@ -312,17 +267,8 @@ export async function getTableLabels(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const tableManagementService = new TableManagementService();
|
||||||
const client = new Client({
|
const tableLabels = await tableManagementService.getTableLabels(tableName);
|
||||||
connectionString: process.env.DATABASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tableManagementService = new TableManagementService(client);
|
|
||||||
const tableLabels =
|
|
||||||
await tableManagementService.getTableLabels(tableName);
|
|
||||||
|
|
||||||
if (!tableLabels) {
|
if (!tableLabels) {
|
||||||
const response: ApiResponse<null> = {
|
const response: ApiResponse<null> = {
|
||||||
|
|
@ -346,9 +292,6 @@ export async function getTableLabels(
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("테이블 라벨 정보 조회 중 오류 발생:", error);
|
logger.error("테이블 라벨 정보 조회 중 오류 발생:", error);
|
||||||
|
|
||||||
|
|
@ -389,15 +332,7 @@ export async function getColumnLabels(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgreSQL 클라이언트 생성
|
const tableManagementService = new TableManagementService();
|
||||||
const client = new Client({
|
|
||||||
connectionString: process.env.DATABASE_URL,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.connect();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tableManagementService = new TableManagementService(client);
|
|
||||||
const columnLabels = await tableManagementService.getColumnLabels(
|
const columnLabels = await tableManagementService.getColumnLabels(
|
||||||
tableName,
|
tableName,
|
||||||
columnName
|
columnName
|
||||||
|
|
@ -425,9 +360,6 @@ export async function getColumnLabels(
|
||||||
};
|
};
|
||||||
|
|
||||||
res.status(200).json(response);
|
res.status(200).json(response);
|
||||||
} finally {
|
|
||||||
await client.end();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("컬럼 라벨 정보 조회 중 오류 발생:", error);
|
logger.error("컬럼 라벨 정보 조회 중 오류 발생:", error);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,4 @@
|
||||||
import { Client } from "pg";
|
import { PrismaClient } from "@prisma/client";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger";
|
||||||
import {
|
import {
|
||||||
TableInfo,
|
TableInfo,
|
||||||
|
|
@ -8,21 +8,21 @@ import {
|
||||||
ColumnLabels,
|
ColumnLabels,
|
||||||
} from "../types/tableManagement";
|
} from "../types/tableManagement";
|
||||||
|
|
||||||
export class TableManagementService {
|
const prisma = new PrismaClient();
|
||||||
private client: Client;
|
|
||||||
|
|
||||||
constructor(client: Client) {
|
export class TableManagementService {
|
||||||
this.client = client;
|
constructor() {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 테이블 목록 조회 (PostgreSQL information_schema 활용)
|
* 테이블 목록 조회 (PostgreSQL information_schema 활용)
|
||||||
|
* 메타데이터 조회는 Prisma로 변경 불가
|
||||||
*/
|
*/
|
||||||
async getTableList(): Promise<TableInfo[]> {
|
async getTableList(): Promise<TableInfo[]> {
|
||||||
try {
|
try {
|
||||||
logger.info("테이블 목록 조회 시작");
|
logger.info("테이블 목록 조회 시작");
|
||||||
|
|
||||||
const query = `
|
// information_schema는 여전히 $queryRaw 사용
|
||||||
|
const tables = await prisma.$queryRaw<TableInfo[]>`
|
||||||
SELECT
|
SELECT
|
||||||
t.table_name as "tableName",
|
t.table_name as "tableName",
|
||||||
COALESCE(tl.table_label, t.table_name) as "displayName",
|
COALESCE(tl.table_label, t.table_name) as "displayName",
|
||||||
|
|
@ -38,10 +38,8 @@ export class TableManagementService {
|
||||||
ORDER BY t.table_name
|
ORDER BY t.table_name
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.client.query(query);
|
logger.info(`테이블 목록 조회 완료: ${tables.length}개`);
|
||||||
logger.info(`테이블 목록 조회 완료: ${result.rows.length}개`);
|
return tables;
|
||||||
|
|
||||||
return result.rows;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error("테이블 목록 조회 중 오류 발생:", error);
|
logger.error("테이블 목록 조회 중 오류 발생:", error);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|
@ -52,12 +50,14 @@ export class TableManagementService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 테이블 컬럼 정보 조회
|
* 테이블 컬럼 정보 조회
|
||||||
|
* 메타데이터 조회는 Prisma로 변경 불가
|
||||||
*/
|
*/
|
||||||
async getColumnList(tableName: string): Promise<ColumnTypeInfo[]> {
|
async getColumnList(tableName: string): Promise<ColumnTypeInfo[]> {
|
||||||
try {
|
try {
|
||||||
logger.info(`컬럼 정보 조회 시작: ${tableName}`);
|
logger.info(`컬럼 정보 조회 시작: ${tableName}`);
|
||||||
|
|
||||||
const query = `
|
// information_schema는 여전히 $queryRaw 사용
|
||||||
|
const columns = await prisma.$queryRaw<ColumnTypeInfo[]>`
|
||||||
SELECT
|
SELECT
|
||||||
c.column_name as "columnName",
|
c.column_name as "columnName",
|
||||||
COALESCE(cl.column_label, c.column_name) as "displayName",
|
COALESCE(cl.column_label, c.column_name) as "displayName",
|
||||||
|
|
@ -78,14 +78,12 @@ export class TableManagementService {
|
||||||
cl.is_visible as "isVisible"
|
cl.is_visible as "isVisible"
|
||||||
FROM information_schema.columns c
|
FROM information_schema.columns c
|
||||||
LEFT JOIN column_labels cl ON c.table_name = cl.table_name AND c.column_name = cl.column_name
|
LEFT JOIN column_labels cl ON c.table_name = cl.table_name AND c.column_name = cl.column_name
|
||||||
WHERE c.table_name = $1
|
WHERE c.table_name = ${tableName}
|
||||||
ORDER BY c.ordinal_position
|
ORDER BY c.ordinal_position
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await this.client.query(query, [tableName]);
|
logger.info(`컬럼 정보 조회 완료: ${tableName}, ${columns.length}개`);
|
||||||
logger.info(`컬럼 정보 조회 완료: ${tableName}, ${result.rows.length}개`);
|
return columns;
|
||||||
|
|
||||||
return result.rows;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`컬럼 정보 조회 중 오류 발생: ${tableName}`, error);
|
logger.error(`컬럼 정보 조회 중 오류 발생: ${tableName}`, error);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|
@ -96,18 +94,22 @@ export class TableManagementService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 테이블이 table_labels에 없으면 자동 추가
|
* 테이블이 table_labels에 없으면 자동 추가
|
||||||
|
* Prisma ORM으로 변경
|
||||||
*/
|
*/
|
||||||
async insertTableIfNotExists(tableName: string): Promise<void> {
|
async insertTableIfNotExists(tableName: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
logger.info(`테이블 라벨 자동 추가 시작: ${tableName}`);
|
logger.info(`테이블 라벨 자동 추가 시작: ${tableName}`);
|
||||||
|
|
||||||
const query = `
|
await prisma.table_labels.upsert({
|
||||||
INSERT INTO table_labels (table_name, table_label, description)
|
where: { table_name: tableName },
|
||||||
VALUES ($1, $1, '')
|
update: {}, // 이미 존재하면 변경하지 않음
|
||||||
ON CONFLICT (table_name) DO NOTHING
|
create: {
|
||||||
`;
|
table_name: tableName,
|
||||||
|
table_label: tableName,
|
||||||
|
description: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
await this.client.query(query, [tableName]);
|
|
||||||
logger.info(`테이블 라벨 자동 추가 완료: ${tableName}`);
|
logger.info(`테이블 라벨 자동 추가 완료: ${tableName}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`테이블 라벨 자동 추가 중 오류 발생: ${tableName}`, error);
|
logger.error(`테이블 라벨 자동 추가 중 오류 발생: ${tableName}`, error);
|
||||||
|
|
@ -119,6 +121,7 @@ export class TableManagementService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 컬럼 설정 업데이트 (UPSERT 방식)
|
* 컬럼 설정 업데이트 (UPSERT 방식)
|
||||||
|
* Prisma ORM으로 변경
|
||||||
*/
|
*/
|
||||||
async updateColumnSettings(
|
async updateColumnSettings(
|
||||||
tableName: string,
|
tableName: string,
|
||||||
|
|
@ -131,38 +134,42 @@ export class TableManagementService {
|
||||||
// 테이블이 table_labels에 없으면 자동 추가
|
// 테이블이 table_labels에 없으면 자동 추가
|
||||||
await this.insertTableIfNotExists(tableName);
|
await this.insertTableIfNotExists(tableName);
|
||||||
|
|
||||||
const query = `
|
// column_labels 업데이트 또는 생성
|
||||||
INSERT INTO column_labels (
|
await prisma.column_labels.upsert({
|
||||||
table_name, column_name, column_label, web_type,
|
where: {
|
||||||
detail_settings, code_category, code_value,
|
table_name_column_name: {
|
||||||
reference_table, reference_column, display_order, is_visible
|
table_name: tableName,
|
||||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
column_name: columnName,
|
||||||
ON CONFLICT (table_name, column_name) DO UPDATE SET
|
},
|
||||||
column_label = EXCLUDED.column_label,
|
},
|
||||||
web_type = EXCLUDED.web_type,
|
update: {
|
||||||
detail_settings = EXCLUDED.detail_settings,
|
column_label: settings.columnLabel,
|
||||||
code_category = EXCLUDED.code_category,
|
web_type: settings.webType,
|
||||||
code_value = EXCLUDED.code_value,
|
detail_settings: settings.detailSettings,
|
||||||
reference_table = EXCLUDED.reference_table,
|
code_category: settings.codeCategory,
|
||||||
reference_column = EXCLUDED.reference_column,
|
code_value: settings.codeValue,
|
||||||
display_order = EXCLUDED.display_order,
|
reference_table: settings.referenceTable,
|
||||||
is_visible = EXCLUDED.is_visible,
|
reference_column: settings.referenceColumn,
|
||||||
updated_date = now()
|
display_order: settings.displayOrder || 0,
|
||||||
`;
|
is_visible:
|
||||||
|
|
||||||
await this.client.query(query, [
|
|
||||||
tableName,
|
|
||||||
columnName,
|
|
||||||
settings.columnLabel,
|
|
||||||
settings.webType,
|
|
||||||
settings.detailSettings,
|
|
||||||
settings.codeCategory,
|
|
||||||
settings.codeValue,
|
|
||||||
settings.referenceTable,
|
|
||||||
settings.referenceColumn,
|
|
||||||
settings.displayOrder || 0,
|
|
||||||
settings.isVisible !== undefined ? settings.isVisible : true,
|
settings.isVisible !== undefined ? settings.isVisible : true,
|
||||||
]);
|
updated_date: new Date(),
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
table_name: tableName,
|
||||||
|
column_name: columnName,
|
||||||
|
column_label: settings.columnLabel,
|
||||||
|
web_type: settings.webType,
|
||||||
|
detail_settings: settings.detailSettings,
|
||||||
|
code_category: settings.codeCategory,
|
||||||
|
code_value: settings.codeValue,
|
||||||
|
reference_table: settings.referenceTable,
|
||||||
|
reference_column: settings.referenceColumn,
|
||||||
|
display_order: settings.displayOrder || 0,
|
||||||
|
is_visible:
|
||||||
|
settings.isVisible !== undefined ? settings.isVisible : true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
logger.info(`컬럼 설정 업데이트 완료: ${tableName}.${columnName}`);
|
logger.info(`컬럼 설정 업데이트 완료: ${tableName}.${columnName}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -178,6 +185,7 @@ export class TableManagementService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 전체 컬럼 설정 일괄 업데이트
|
* 전체 컬럼 설정 일괄 업데이트
|
||||||
|
* Prisma 트랜잭션으로 변경
|
||||||
*/
|
*/
|
||||||
async updateAllColumnSettings(
|
async updateAllColumnSettings(
|
||||||
tableName: string,
|
tableName: string,
|
||||||
|
|
@ -188,10 +196,8 @@ export class TableManagementService {
|
||||||
`전체 컬럼 설정 일괄 업데이트 시작: ${tableName}, ${columnSettings.length}개`
|
`전체 컬럼 설정 일괄 업데이트 시작: ${tableName}, ${columnSettings.length}개`
|
||||||
);
|
);
|
||||||
|
|
||||||
// 트랜잭션 시작
|
// Prisma 트랜잭션 사용
|
||||||
await this.client.query("BEGIN");
|
await prisma.$transaction(async (tx) => {
|
||||||
|
|
||||||
try {
|
|
||||||
// 테이블이 table_labels에 없으면 자동 추가
|
// 테이블이 table_labels에 없으면 자동 추가
|
||||||
await this.insertTableIfNotExists(tableName);
|
await this.insertTableIfNotExists(tableName);
|
||||||
|
|
||||||
|
|
@ -207,15 +213,9 @@ export class TableManagementService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 트랜잭션 커밋
|
|
||||||
await this.client.query("COMMIT");
|
|
||||||
logger.info(`전체 컬럼 설정 일괄 업데이트 완료: ${tableName}`);
|
logger.info(`전체 컬럼 설정 일괄 업데이트 완료: ${tableName}`);
|
||||||
} catch (error) {
|
|
||||||
// 트랜잭션 롤백
|
|
||||||
await this.client.query("ROLLBACK");
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`전체 컬럼 설정 일괄 업데이트 중 오류 발생: ${tableName}`,
|
`전체 컬럼 설정 일괄 업데이트 중 오류 발생: ${tableName}`,
|
||||||
|
|
@ -229,30 +229,37 @@ export class TableManagementService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 테이블 라벨 정보 조회
|
* 테이블 라벨 정보 조회
|
||||||
|
* Prisma ORM으로 변경
|
||||||
*/
|
*/
|
||||||
async getTableLabels(tableName: string): Promise<TableLabels | null> {
|
async getTableLabels(tableName: string): Promise<TableLabels | null> {
|
||||||
try {
|
try {
|
||||||
logger.info(`테이블 라벨 정보 조회 시작: ${tableName}`);
|
logger.info(`테이블 라벨 정보 조회 시작: ${tableName}`);
|
||||||
|
|
||||||
const query = `
|
const tableLabel = await prisma.table_labels.findUnique({
|
||||||
SELECT
|
where: { table_name: tableName },
|
||||||
table_name as "tableName",
|
select: {
|
||||||
table_label as "tableLabel",
|
table_name: true,
|
||||||
description,
|
table_label: true,
|
||||||
created_date as "createdDate",
|
description: true,
|
||||||
updated_date as "updatedDate"
|
created_date: true,
|
||||||
FROM table_labels
|
updated_date: true,
|
||||||
WHERE table_name = $1
|
},
|
||||||
`;
|
});
|
||||||
|
|
||||||
const result = await this.client.query(query, [tableName]);
|
if (!tableLabel) {
|
||||||
|
|
||||||
if (result.rows.length === 0) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result: TableLabels = {
|
||||||
|
tableName: tableLabel.table_name,
|
||||||
|
tableLabel: tableLabel.table_label || undefined,
|
||||||
|
description: tableLabel.description || undefined,
|
||||||
|
createdDate: tableLabel.created_date || undefined,
|
||||||
|
updatedDate: tableLabel.updated_date || undefined,
|
||||||
|
};
|
||||||
|
|
||||||
logger.info(`테이블 라벨 정보 조회 완료: ${tableName}`);
|
logger.info(`테이블 라벨 정보 조회 완료: ${tableName}`);
|
||||||
return result.rows[0];
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`테이블 라벨 정보 조회 중 오류 발생: ${tableName}`, error);
|
logger.error(`테이블 라벨 정보 조회 중 오류 발생: ${tableName}`, error);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|
@ -263,6 +270,7 @@ export class TableManagementService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 컬럼 라벨 정보 조회
|
* 컬럼 라벨 정보 조회
|
||||||
|
* Prisma ORM으로 변경
|
||||||
*/
|
*/
|
||||||
async getColumnLabels(
|
async getColumnLabels(
|
||||||
tableName: string,
|
tableName: string,
|
||||||
|
|
@ -271,35 +279,56 @@ export class TableManagementService {
|
||||||
try {
|
try {
|
||||||
logger.info(`컬럼 라벨 정보 조회 시작: ${tableName}.${columnName}`);
|
logger.info(`컬럼 라벨 정보 조회 시작: ${tableName}.${columnName}`);
|
||||||
|
|
||||||
const query = `
|
const columnLabel = await prisma.column_labels.findUnique({
|
||||||
SELECT
|
where: {
|
||||||
id,
|
table_name_column_name: {
|
||||||
table_name as "tableName",
|
table_name: tableName,
|
||||||
column_name as "columnName",
|
column_name: columnName,
|
||||||
column_label as "columnLabel",
|
},
|
||||||
web_type as "webType",
|
},
|
||||||
detail_settings as "detailSettings",
|
select: {
|
||||||
description,
|
id: true,
|
||||||
display_order as "displayOrder",
|
table_name: true,
|
||||||
is_visible as "isVisible",
|
column_name: true,
|
||||||
code_category as "codeCategory",
|
column_label: true,
|
||||||
code_value as "codeValue",
|
web_type: true,
|
||||||
reference_table as "referenceTable",
|
detail_settings: true,
|
||||||
reference_column as "referenceColumn",
|
description: true,
|
||||||
created_date as "createdDate",
|
display_order: true,
|
||||||
updated_date as "updatedDate"
|
is_visible: true,
|
||||||
FROM column_labels
|
code_category: true,
|
||||||
WHERE table_name = $1 AND column_name = $2
|
code_value: true,
|
||||||
`;
|
reference_table: true,
|
||||||
|
reference_column: true,
|
||||||
|
created_date: true,
|
||||||
|
updated_date: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const result = await this.client.query(query, [tableName, columnName]);
|
if (!columnLabel) {
|
||||||
|
|
||||||
if (result.rows.length === 0) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result: ColumnLabels = {
|
||||||
|
id: columnLabel.id,
|
||||||
|
tableName: columnLabel.table_name || "",
|
||||||
|
columnName: columnLabel.column_name || "",
|
||||||
|
columnLabel: columnLabel.column_label || undefined,
|
||||||
|
webType: columnLabel.web_type || undefined,
|
||||||
|
detailSettings: columnLabel.detail_settings || undefined,
|
||||||
|
description: columnLabel.description || undefined,
|
||||||
|
displayOrder: columnLabel.display_order || undefined,
|
||||||
|
isVisible: columnLabel.is_visible || undefined,
|
||||||
|
codeCategory: columnLabel.code_category || undefined,
|
||||||
|
codeValue: columnLabel.code_value || undefined,
|
||||||
|
referenceTable: columnLabel.reference_table || undefined,
|
||||||
|
referenceColumn: columnLabel.reference_column || undefined,
|
||||||
|
createdDate: columnLabel.created_date || undefined,
|
||||||
|
updatedDate: columnLabel.updated_date || undefined,
|
||||||
|
};
|
||||||
|
|
||||||
logger.info(`컬럼 라벨 정보 조회 완료: ${tableName}.${columnName}`);
|
logger.info(`컬럼 라벨 정보 조회 완료: ${tableName}.${columnName}`);
|
||||||
return result.rows[0];
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`컬럼 라벨 정보 조회 중 오류 발생: ${tableName}.${columnName}`,
|
`컬럼 라벨 정보 조회 중 오류 발생: ${tableName}.${columnName}`,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue