Merge remote-tracking branch 'upstream/main'

This commit is contained in:
kjs
2026-01-06 10:29:09 +09:00
22 changed files with 454 additions and 146 deletions

View File

@@ -55,3 +55,4 @@ export default router;

View File

@@ -51,3 +51,4 @@ export default router;

View File

@@ -67,3 +67,4 @@ export default router;

View File

@@ -55,3 +55,4 @@ export default router;

View File

@@ -65,6 +65,13 @@ export class AdminService {
}
);
// [임시 비활성화] 메뉴 권한 그룹 체크 - 모든 사용자에게 전체 메뉴 표시
// TODO: 권한 체크 다시 활성화 필요
logger.info(
`⚠️ [임시 비활성화] 권한 그룹 체크 스킵 - 사용자 ${userId}(${userType})에게 전체 메뉴 표시`
);
/* [원본 코드 - 권한 그룹 체크]
if (userType === "COMPANY_ADMIN") {
// 회사 관리자: 권한 그룹 기반 필터링 적용
if (userRoleGroups.length > 0) {
@@ -141,6 +148,7 @@ export class AdminService {
return [];
}
}
*/
} else if (
menuType !== undefined &&
userType === "SUPER_ADMIN" &&
@@ -412,6 +420,15 @@ export class AdminService {
let queryParams: any[] = [userLang];
let paramIndex = 2;
// [임시 비활성화] 메뉴 권한 그룹 체크 - 모든 사용자에게 전체 메뉴 표시
// TODO: 권한 체크 다시 활성화 필요
logger.info(
`⚠️ [임시 비활성화] getUserMenuList 권한 그룹 체크 스킵 - 사용자 ${userId}(${userType})에게 전체 메뉴 표시`
);
authFilter = "";
unionFilter = "";
/* [원본 코드 - getUserMenuList 권한 그룹 체크]
if (userType === "SUPER_ADMIN") {
// SUPER_ADMIN: 권한 그룹 체크 없이 해당 회사의 모든 메뉴 표시
logger.info(`✅ 좌측 사이드바 (SUPER_ADMIN): 회사 ${userCompanyCode}의 모든 메뉴 표시`);
@@ -471,6 +488,7 @@ export class AdminService {
return [];
}
}
*/
// 2. 회사별 필터링 조건 생성
let companyFilter = "";

View File

@@ -2409,11 +2409,19 @@ export class TableManagementService {
}
// SET 절 생성 (수정할 데이터) - 먼저 생성
// 🔧 테이블에 존재하는 컬럼만 UPDATE (가상 컬럼 제외)
const setConditions: string[] = [];
const setValues: any[] = [];
let paramIndex = 1;
const skippedColumns: string[] = [];
Object.keys(updatedData).forEach((column) => {
// 테이블에 존재하지 않는 컬럼은 스킵
if (!columnTypeMap.has(column)) {
skippedColumns.push(column);
return;
}
const dataType = columnTypeMap.get(column) || "text";
setConditions.push(
`"${column}" = $${paramIndex}::${this.getPostgreSQLType(dataType)}`
@@ -2424,6 +2432,10 @@ export class TableManagementService {
paramIndex++;
});
if (skippedColumns.length > 0) {
logger.info(`⚠️ 테이블에 존재하지 않는 컬럼 스킵: ${skippedColumns.join(", ")}`);
}
// WHERE 조건 생성 (PRIMARY KEY 우선, 없으면 모든 원본 데이터 사용)
let whereConditions: string[] = [];
let whereValues: any[] = [];
@@ -3930,9 +3942,10 @@ export class TableManagementService {
`컬럼 입력타입 정보 조회: ${tableName}, company: ${companyCode}`
);
// table_type_columns에서 입력타입 정보 조회 (company_code 필터링)
// table_type_columns에서 입력타입 정보 조회
// 회사별 설정 우선, 없으면 기본 설정(*) fallback
const rawInputTypes = await query<any>(
`SELECT
`SELECT DISTINCT ON (ttc.column_name)
ttc.column_name as "columnName",
COALESCE(cl.column_label, ttc.column_name) as "displayName",
ttc.input_type as "inputType",
@@ -3946,8 +3959,10 @@ export class TableManagementService {
LEFT JOIN information_schema.columns ic
ON ttc.table_name = ic.table_name AND ttc.column_name = ic.column_name
WHERE ttc.table_name = $1
AND ttc.company_code = $2
ORDER BY ttc.display_order, ttc.column_name`,
AND ttc.company_code IN ($2, '*')
ORDER BY ttc.column_name,
CASE WHEN ttc.company_code = $2 THEN 0 ELSE 1 END,
ttc.display_order`,
[tableName, companyCode]
);
@@ -3961,17 +3976,20 @@ export class TableManagementService {
const mappingTableExists = tableExistsResult[0]?.table_exists === true;
// 카테고리 컬럼의 경우, 매핑된 메뉴 목록 조회
// 회사별 설정 우선, 없으면 기본 설정(*) fallback
let categoryMappings: Map<string, number[]> = new Map();
if (mappingTableExists) {
logger.info("카테고리 매핑 조회 시작", { tableName, companyCode });
const mappings = await query<any>(
`SELECT
`SELECT DISTINCT ON (logical_column_name, menu_objid)
logical_column_name as "columnName",
menu_objid as "menuObjid"
FROM category_column_mapping
WHERE table_name = $1
AND company_code = $2`,
AND company_code IN ($2, '*')
ORDER BY logical_column_name, menu_objid,
CASE WHEN company_code = $2 THEN 0 ELSE 1 END`,
[tableName, companyCode]
);