ERP-node/backend-node/src/controllers/multilangController.ts

849 lines
22 KiB
TypeScript
Raw Normal View History

2025-08-25 15:12:31 +09:00
import { Request, Response } from "express";
import { logger } from "../utils/logger";
2025-08-25 15:12:31 +09:00
import { AuthenticatedRequest } from "../types/auth";
import { MultiLangService } from "../services/multilangService";
import { Client } from "pg";
import {
CreateLanguageRequest,
UpdateLanguageRequest,
CreateLangKeyRequest,
UpdateLangKeyRequest,
SaveLangTextsRequest,
GetUserTextParams,
BatchTranslationRequest,
ApiResponse,
} from "../types/multilang";
/**
2025-08-25 15:12:31 +09:00
* GET /api/multilang/languages
* API
*/
2025-08-25 15:12:31 +09:00
export const getLanguages = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
2025-08-25 15:12:31 +09:00
logger.info("언어 목록 조회 요청", { user: req.user });
2025-08-25 15:12:31 +09:00
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
2025-08-25 15:12:31 +09:00
await client.connect();
try {
const multiLangService = new MultiLangService(client);
const languages = await multiLangService.getLanguages();
const response: ApiResponse<any[]> = {
success: true,
message: "언어 목록 조회 성공",
data: languages,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("언어 목록 조회 실패:", error);
res.status(500).json({
success: false,
message: "언어 목록 조회 중 오류가 발생했습니다.",
error: {
code: "LANGUAGE_LIST_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* POST /api/multilang/languages
* API
*/
export const createLanguage = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const languageData: CreateLanguageRequest = req.body;
logger.info("언어 생성 요청", { languageData, user: req.user });
// 필수 입력값 검증
if (
!languageData.langCode ||
!languageData.langName ||
!languageData.langNative
) {
res.status(400).json({
success: false,
2025-08-25 15:12:31 +09:00
message: "언어 코드, 언어명, 원어명은 필수입니다.",
error: {
code: "MISSING_REQUIRED_FIELDS",
details: "langCode, langName, langNative are required",
},
});
return;
}
2025-08-25 15:12:31 +09:00
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
await client.connect();
2025-08-25 15:12:31 +09:00
try {
const multiLangService = new MultiLangService(client);
const createdLanguage = await multiLangService.createLanguage({
...languageData,
createdBy: req.user?.userId || "system",
updatedBy: req.user?.userId || "system",
});
2025-08-25 15:12:31 +09:00
const response: ApiResponse<any> = {
success: true,
2025-08-25 15:12:31 +09:00
message: "언어가 성공적으로 생성되었습니다.",
data: createdLanguage,
};
res.status(201).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("언어 생성 실패:", error);
res.status(500).json({
success: false,
message: "언어 생성 중 오류가 발생했습니다.",
error: {
code: "LANGUAGE_CREATE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* PUT /api/multilang/languages/:langCode
* API
*/
export const updateLanguage = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { langCode } = req.params;
const languageData: UpdateLanguageRequest = req.body;
logger.info("언어 수정 요청", { langCode, languageData, user: req.user });
// PostgreSQL 클라이언트 생성
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, {
...languageData,
updatedBy: req.user?.userId || "system",
});
2025-08-25 15:12:31 +09:00
const response: ApiResponse<any> = {
success: true,
message: "언어가 성공적으로 수정되었습니다.",
data: updatedLanguage,
};
res.status(200).json(response);
} finally {
await client.end();
}
2025-08-25 15:12:31 +09:00
} catch (error) {
logger.error("언어 수정 실패:", error);
res.status(500).json({
success: false,
message: "언어 수정 중 오류가 발생했습니다.",
error: {
code: "LANGUAGE_UPDATE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
2025-08-25 15:12:31 +09:00
/**
* PUT /api/multilang/languages/:langCode/toggle
* API
*/
export const toggleLanguage = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { langCode } = req.params;
logger.info("언어 상태 토글 요청", { langCode, user: req.user });
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
2025-08-25 15:12:31 +09:00
await client.connect();
try {
const multiLangService = new MultiLangService(client);
const result = await multiLangService.toggleLanguage(langCode);
2025-08-25 15:12:31 +09:00
const response: ApiResponse<string> = {
success: true,
message: `언어가 ${result}되었습니다.`,
data: result,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("언어 상태 토글 실패:", error);
res.status(500).json({
success: false,
message: "언어 상태 변경 중 오류가 발생했습니다.",
error: {
code: "LANGUAGE_TOGGLE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
2025-08-25 15:12:31 +09:00
}
};
2025-08-25 15:12:31 +09:00
/**
* GET /api/multilang/keys
* API
*/
export const getLangKeys = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { companyCode, menuCode, keyType, searchText } = req.query;
logger.info("다국어 키 목록 조회 요청", {
query: req.query,
user: req.user,
});
2025-08-25 15:12:31 +09:00
// PostgreSQL 클라이언트 생성
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({
companyCode: companyCode as string,
menuCode: menuCode as string,
keyType: keyType as string,
searchText: searchText as string,
});
2025-08-25 15:12:31 +09:00
const response: ApiResponse<any[]> = {
success: true,
message: "다국어 키 목록 조회 성공",
data: langKeys,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("다국어 키 목록 조회 실패:", error);
res.status(500).json({
success: false,
message: "다국어 키 목록 조회 중 오류가 발생했습니다.",
error: {
code: "LANG_KEYS_LIST_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* GET /api/multilang/keys/:keyId/texts
* API
*/
export const getLangTexts = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { keyId } = req.params;
logger.info("다국어 텍스트 조회 요청", { keyId, user: req.user });
// PostgreSQL 클라이언트 생성
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 response: ApiResponse<any[]> = {
success: true,
2025-08-25 15:12:31 +09:00
message: "다국어 텍스트 조회 성공",
data: langTexts,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("다국어 텍스트 조회 실패:", error);
res.status(500).json({
success: false,
message: "다국어 텍스트 조회 중 오류가 발생했습니다.",
error: {
code: "LANG_TEXTS_LIST_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* POST /api/multilang/keys
* API
*/
export const createLangKey = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const keyData: CreateLangKeyRequest = req.body;
logger.info("다국어 키 생성 요청", { keyData, user: req.user });
// 필수 입력값 검증
if (!keyData.companyCode || !keyData.langKey) {
res.status(400).json({
success: false,
message: "회사 코드와 언어 키는 필수입니다.",
error: {
code: "MISSING_REQUIRED_FIELDS",
details: "companyCode and langKey are required",
},
});
return;
}
2025-08-25 15:12:31 +09:00
// PostgreSQL 클라이언트 생성
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({
...keyData,
createdBy: req.user?.userId || "system",
updatedBy: req.user?.userId || "system",
});
const response: ApiResponse<number> = {
success: true,
message: "다국어 키가 성공적으로 생성되었습니다.",
data: keyId,
};
res.status(201).json(response);
} finally {
await client.end();
}
2025-08-25 15:12:31 +09:00
} catch (error) {
logger.error("다국어 키 생성 실패:", error);
res.status(500).json({
success: false,
message: "다국어 키 생성 중 오류가 발생했습니다.",
error: {
code: "LANG_KEY_CREATE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
2025-08-25 15:12:31 +09:00
/**
* PUT /api/multilang/keys/:keyId
* API
*/
export const updateLangKey = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { keyId } = req.params;
const keyData: UpdateLangKeyRequest = req.body;
logger.info("다국어 키 수정 요청", { keyId, keyData, user: req.user });
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
2025-08-25 15:12:31 +09:00
await client.connect();
try {
const multiLangService = new MultiLangService(client);
await multiLangService.updateLangKey(parseInt(keyId), {
...keyData,
updatedBy: req.user?.userId || "system",
});
const response: ApiResponse<string> = {
success: true,
message: "다국어 키가 성공적으로 수정되었습니다.",
data: "수정 완료",
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("다국어 키 수정 실패:", error);
res.status(500).json({
success: false,
message: "다국어 키 수정 중 오류가 발생했습니다.",
error: {
code: "LANG_KEY_UPDATE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
2025-08-25 15:12:31 +09:00
}
};
2025-08-25 15:12:31 +09:00
/**
* DELETE /api/multilang/keys/:keyId
* API
*/
export const deleteLangKey = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { keyId } = req.params;
logger.info("다국어 키 삭제 요청", { keyId, user: req.user });
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
2025-08-25 15:12:31 +09:00
await client.connect();
try {
const multiLangService = new MultiLangService(client);
await multiLangService.deleteLangKey(parseInt(keyId));
const response: ApiResponse<string> = {
success: true,
message: "다국어 키가 성공적으로 삭제되었습니다.",
data: "삭제 완료",
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
2025-08-25 15:12:31 +09:00
logger.error("다국어 키 삭제 실패:", error);
res.status(500).json({
success: false,
2025-08-25 15:12:31 +09:00
message: "다국어 키 삭제 중 오류가 발생했습니다.",
error: {
code: "LANG_KEY_DELETE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* PUT /api/multilang/keys/:keyId/toggle
* API
*/
export const toggleLangKey = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { keyId } = req.params;
logger.info("다국어 키 상태 토글 요청", { keyId, user: req.user });
// PostgreSQL 클라이언트 생성
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 response: ApiResponse<string> = {
success: true,
message: `다국어 키가 ${result}되었습니다.`,
data: result,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("다국어 키 상태 토글 실패:", error);
res.status(500).json({
success: false,
message: "다국어 키 상태 변경 중 오류가 발생했습니다.",
error: {
code: "LANG_KEY_TOGGLE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* POST /api/multilang/keys/:keyId/texts
* / API
*/
export const saveLangTexts = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { keyId } = req.params;
const textData: SaveLangTextsRequest = req.body;
logger.info("다국어 텍스트 저장 요청", { keyId, textData, user: req.user });
// 필수 입력값 검증
if (
!textData.texts ||
!Array.isArray(textData.texts) ||
textData.texts.length === 0
) {
res.status(400).json({
success: false,
message: "텍스트 데이터는 필수입니다.",
error: {
code: "MISSING_REQUIRED_FIELDS",
details: "texts array is required",
},
});
return;
}
// PostgreSQL 클라이언트 생성
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), {
texts: textData.texts.map((text) => ({
...text,
createdBy: req.user?.userId || "system",
updatedBy: req.user?.userId || "system",
})),
});
const response: ApiResponse<string> = {
success: true,
message: "다국어 텍스트가 성공적으로 저장되었습니다.",
data: "저장 완료",
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("다국어 텍스트 저장 실패:", error);
res.status(500).json({
success: false,
message: "다국어 텍스트 저장 중 오류가 발생했습니다.",
error: {
code: "LANG_TEXTS_SAVE_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
* GET /api/multilang/user-text/:companyCode/:menuCode/:langKey
2025-08-25 15:12:31 +09:00
* API
*/
2025-08-25 15:12:31 +09:00
export const getUserText = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { companyCode, menuCode, langKey } = req.params;
const { userLang } = req.query;
2025-08-25 15:12:31 +09:00
logger.info("사용자별 다국어 텍스트 조회 요청", {
companyCode,
menuCode,
langKey,
userLang,
user: req.user,
});
2025-08-25 15:12:31 +09:00
if (!userLang) {
res.status(400).json({
success: false,
message: "사용자 언어는 필수입니다.",
error: {
code: "MISSING_USER_LANG",
details: "userLang query parameter is required",
},
});
return;
}
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
2025-08-25 15:12:31 +09:00
await client.connect();
try {
const multiLangService = new MultiLangService(client);
const langText = await multiLangService.getUserText({
companyCode,
menuCode,
langKey,
userLang: userLang as string,
});
const response: ApiResponse<string> = {
success: true,
message: "사용자별 다국어 텍스트 조회 성공",
data: langText,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
2025-08-25 15:12:31 +09:00
logger.error("사용자별 다국어 텍스트 조회 실패:", error);
res.status(500).json({
success: false,
2025-08-25 15:12:31 +09:00
message: "사용자별 다국어 텍스트 조회 중 오류가 발생했습니다.",
error: {
code: "USER_TEXT_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
2025-08-25 15:12:31 +09:00
* GET /api/multilang/text/:companyCode/:langKey/:langCode
* API
*/
2025-08-25 15:12:31 +09:00
export const getLangText = async (
req: AuthenticatedRequest,
res: Response
): Promise<void> => {
try {
const { companyCode, langKey, langCode } = req.params;
2025-08-25 15:12:31 +09:00
logger.info("특정 키의 다국어 텍스트 조회 요청", {
companyCode,
langKey,
langCode,
user: req.user,
});
2025-08-25 15:12:31 +09:00
// PostgreSQL 클라이언트 생성
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(
companyCode,
langKey,
langCode
);
const response: ApiResponse<string> = {
success: true,
message: "특정 키의 다국어 텍스트 조회 성공",
data: langText,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
logger.error("특정 키의 다국어 텍스트 조회 실패:", error);
res.status(500).json({
success: false,
message: "특정 키의 다국어 텍스트 조회 중 오류가 발생했습니다.",
error: {
code: "LANG_TEXT_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};
/**
2025-08-25 15:12:31 +09:00
* POST /api/multilang/batch
* API
*/
2025-08-25 15:12:31 +09:00
export const getBatchTranslations = async (
2025-08-29 10:09:34 +09:00
req: Request,
2025-08-25 15:12:31 +09:00
res: Response
): Promise<void> => {
try {
2025-08-25 15:12:31 +09:00
const { companyCode, menuCode, userLang } = req.query;
2025-08-25 17:22:20 +09:00
const {
langKeys,
companyCode: bodyCompanyCode,
menuCode: bodyMenuCode,
userLang: bodyUserLang,
} = req.body;
// query params에서 읽지 못한 경우 body에서 읽기
const finalCompanyCode = companyCode || bodyCompanyCode;
const finalMenuCode = menuCode || bodyMenuCode;
const finalUserLang = userLang || bodyUserLang;
2025-08-25 15:12:31 +09:00
logger.info("다국어 텍스트 배치 조회 요청", {
2025-08-25 17:22:20 +09:00
companyCode: finalCompanyCode,
menuCode: finalMenuCode,
userLang: finalUserLang,
2025-08-25 15:12:31 +09:00
keyCount: langKeys?.length || 0,
});
2025-08-25 15:12:31 +09:00
if (!langKeys || !Array.isArray(langKeys) || langKeys.length === 0) {
res.status(400).json({
success: false,
message: "langKeys 배열이 필요합니다.",
error: {
code: "MISSING_LANG_KEYS",
details: "langKeys array is required",
},
});
return;
}
2025-08-25 17:22:20 +09:00
if (!finalCompanyCode || !finalUserLang) {
2025-08-25 15:12:31 +09:00
res.status(400).json({
success: false,
message: "companyCode와 userLang은 필수입니다.",
error: {
code: "MISSING_REQUIRED_PARAMS",
details: "companyCode and userLang are required",
},
});
return;
}
// PostgreSQL 클라이언트 생성
const client = new Client({
connectionString:
process.env.DATABASE_URL ||
"postgresql://postgres:postgres@localhost:5432/ilshin",
});
2025-08-25 15:12:31 +09:00
await client.connect();
try {
const multiLangService = new MultiLangService(client);
const translations = await multiLangService.getBatchTranslations({
2025-08-25 17:22:20 +09:00
companyCode: finalCompanyCode as string,
menuCode: finalMenuCode as string,
userLang: finalUserLang as string,
2025-08-25 15:12:31 +09:00
langKeys,
});
const response: ApiResponse<Record<string, string>> = {
success: true,
message: "다국어 텍스트 배치 조회 성공",
data: translations,
};
res.status(200).json(response);
} finally {
await client.end();
}
} catch (error) {
2025-08-25 15:12:31 +09:00
logger.error("다국어 텍스트 배치 조회 실패:", error);
res.status(500).json({
success: false,
2025-08-25 15:12:31 +09:00
message: "다국어 텍스트 배치 조회 중 오류가 발생했습니다.",
error: {
code: "BATCH_TRANSLATION_ERROR",
details: error instanceof Error ? error.message : "Unknown error",
},
});
}
};