우측 패널 항목 삭제 기능 구현
This commit is contained in:
@@ -459,6 +459,58 @@ router.put(
|
||||
* 레코드 삭제 API
|
||||
* DELETE /api/data/{tableName}/{id}
|
||||
*/
|
||||
/**
|
||||
* 복합키 레코드 삭제 API (POST)
|
||||
* POST /api/data/:tableName/delete
|
||||
* Body: { user_id: 'xxx', dept_code: 'yyy' }
|
||||
*/
|
||||
router.post(
|
||||
"/:tableName/delete",
|
||||
authenticateToken,
|
||||
async (req: AuthenticatedRequest, res) => {
|
||||
try {
|
||||
const { tableName } = req.params;
|
||||
const compositeKey = req.body;
|
||||
|
||||
// 입력값 검증
|
||||
if (!tableName || typeof tableName !== "string") {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "테이블명이 필요합니다.",
|
||||
error: "INVALID_TABLE_NAME",
|
||||
});
|
||||
}
|
||||
|
||||
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName)) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "유효하지 않은 테이블명입니다.",
|
||||
error: "INVALID_TABLE_NAME",
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`🗑️ 복합키 레코드 삭제: ${tableName}`, compositeKey);
|
||||
|
||||
// 레코드 삭제 (복합키 객체 전달)
|
||||
const result = await dataService.deleteRecord(tableName, compositeKey);
|
||||
|
||||
if (!result.success) {
|
||||
return res.status(400).json(result);
|
||||
}
|
||||
|
||||
console.log(`✅ 레코드 삭제 성공: ${tableName}`);
|
||||
return res.json(result);
|
||||
} catch (error: any) {
|
||||
console.error(`레코드 삭제 오류 (${req.params.tableName}):`, error);
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: "레코드 삭제 중 오류가 발생했습니다.",
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:tableName/:id",
|
||||
authenticateToken,
|
||||
|
||||
@@ -652,7 +652,7 @@ class DataService {
|
||||
*/
|
||||
async deleteRecord(
|
||||
tableName: string,
|
||||
id: string | number
|
||||
id: string | number | Record<string, any>
|
||||
): Promise<ServiceResponse<void>> {
|
||||
try {
|
||||
// 테이블 접근 검증
|
||||
@@ -661,28 +661,53 @@ class DataService {
|
||||
return validation.error!;
|
||||
}
|
||||
|
||||
// Primary Key 컬럼 찾기
|
||||
// Primary Key 컬럼 찾기 (복합키 지원)
|
||||
const pkResult = await query<{ attname: string }>(
|
||||
`SELECT a.attname
|
||||
FROM pg_index i
|
||||
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
|
||||
WHERE i.indrelid = $1::regclass AND i.indisprimary`,
|
||||
WHERE i.indrelid = $1::regclass AND i.indisprimary
|
||||
ORDER BY a.attnum`,
|
||||
[tableName]
|
||||
);
|
||||
|
||||
let pkColumn = "id";
|
||||
if (pkResult.length > 0) {
|
||||
pkColumn = pkResult[0].attname;
|
||||
let whereClauses: string[] = [];
|
||||
let params: any[] = [];
|
||||
|
||||
if (pkResult.length > 1) {
|
||||
// 복합키인 경우: id가 객체여야 함
|
||||
console.log(`🔑 복합키 테이블: ${tableName}, PK: [${pkResult.map(r => r.attname).join(', ')}]`);
|
||||
|
||||
if (typeof id === 'object' && !Array.isArray(id)) {
|
||||
// id가 객체인 경우: { user_id: 'xxx', dept_code: 'yyy' }
|
||||
pkResult.forEach((pk, index) => {
|
||||
whereClauses.push(`"${pk.attname}" = $${index + 1}`);
|
||||
params.push(id[pk.attname]);
|
||||
});
|
||||
} else {
|
||||
// id가 문자열/숫자인 경우: 첫 번째 PK만 사용 (하위 호환성)
|
||||
whereClauses.push(`"${pkResult[0].attname}" = $1`);
|
||||
params.push(id);
|
||||
}
|
||||
} else {
|
||||
// 단일키인 경우
|
||||
const pkColumn = pkResult.length > 0 ? pkResult[0].attname : "id";
|
||||
whereClauses.push(`"${pkColumn}" = $1`);
|
||||
params.push(typeof id === 'object' ? id[pkColumn] : id);
|
||||
}
|
||||
|
||||
const queryText = `DELETE FROM "${tableName}" WHERE "${pkColumn}" = $1`;
|
||||
await query<any>(queryText, [id]);
|
||||
const queryText = `DELETE FROM "${tableName}" WHERE ${whereClauses.join(' AND ')}`;
|
||||
console.log(`🗑️ 삭제 쿼리:`, queryText, params);
|
||||
|
||||
const result = await query<any>(queryText, params);
|
||||
|
||||
console.log(`✅ 레코드 삭제 완료: ${tableName}, 영향받은 행: ${result.length}`);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`레코드 삭제 오류 (${tableName}/${id}):`, error);
|
||||
console.error(`레코드 삭제 오류 (${tableName}):`, error);
|
||||
return {
|
||||
success: false,
|
||||
message: "레코드 삭제 중 오류가 발생했습니다.",
|
||||
|
||||
Reference in New Issue
Block a user