Merge remote-tracking branch 'upstream/main'

This commit is contained in:
kjs
2026-03-11 19:11:35 +09:00
652 changed files with 33132 additions and 14759 deletions

View File

@@ -5,6 +5,7 @@ import {
ApprovalRequestController,
ApprovalLineController,
} from "../controllers/approvalController";
import { ApprovalProxyController } from "../controllers/approvalProxyController";
import { authenticateToken } from "../middleware/authMiddleware";
const router = express.Router();
@@ -30,9 +31,17 @@ router.get("/requests", ApprovalRequestController.getRequests);
router.get("/requests/:id", ApprovalRequestController.getRequest);
router.post("/requests", ApprovalRequestController.createRequest);
router.post("/requests/:id/cancel", ApprovalRequestController.cancelRequest);
router.post("/requests/:id/post-approve", ApprovalRequestController.postApprove);
// ==================== 결재 라인 처리 (Lines) ====================
router.get("/my-pending", ApprovalLineController.getMyPendingLines);
router.post("/lines/:lineId/process", ApprovalLineController.processApproval);
// ==================== 대결 위임 설정 (Proxy Settings) ====================
router.get("/proxy-settings", ApprovalProxyController.getProxySettings);
router.post("/proxy-settings", ApprovalProxyController.createProxySetting);
router.put("/proxy-settings/:id", ApprovalProxyController.updateProxySetting);
router.delete("/proxy-settings/:id", ApprovalProxyController.deleteProxySetting);
router.get("/proxy-settings/check/:userId", ApprovalProxyController.checkActiveProxy);
export default router;

View File

@@ -6,6 +6,8 @@ import { authenticateToken } from "../middleware/authMiddleware";
import { AuthenticatedRequest } from "../types/auth";
import { getPool } from "../database/db";
import { auditLogService } from "../services/auditLogService";
import { TableManagementService } from "../services/tableManagementService";
import { formatPgError } from "../utils/pgErrorUtil";
const router = express.Router();
@@ -1047,6 +1049,20 @@ router.post(
console.log(`🏢 company_name 자동 추가: ${req.user.companyName}`);
}
// UNIQUE 제약조건 검증
const tms = new TableManagementService();
const uniqueViolations = await tms.validateUniqueConstraints(
tableName,
enrichedData,
req.user?.companyCode || "*"
);
if (uniqueViolations.length > 0) {
return res.status(400).json({
success: false,
message: `중복된 값이 존재합니다: ${uniqueViolations.join(", ")}`,
});
}
// 레코드 생성
const result = await dataService.createRecord(tableName, enrichedData);
@@ -1116,6 +1132,21 @@ router.put(
console.log(`✏️ 레코드 수정: ${tableName}/${id}`, data);
// UNIQUE 제약조건 검증 (자기 자신 제외)
const tmsUpdate = new TableManagementService();
const uniqueViolations = await tmsUpdate.validateUniqueConstraints(
tableName,
data,
req.user?.companyCode || "*",
String(id)
);
if (uniqueViolations.length > 0) {
return res.status(400).json({
success: false,
message: `중복된 값이 존재합니다: ${uniqueViolations.join(", ")}`,
});
}
// 레코드 수정
const result = await dataService.updateRecord(tableName, id, data);

View File

@@ -0,0 +1,10 @@
import { Router } from "express";
import { authenticateToken } from "../middleware/authMiddleware";
const router = Router();
router.use(authenticateToken);
// TODO: 포장/적재정보 관리 API 구현 예정
export default router;

View File

@@ -0,0 +1,27 @@
import { Router } from "express";
import {
getSystemNotices,
createSystemNotice,
updateSystemNotice,
deleteSystemNotice,
} from "../controllers/systemNoticeController";
import { authenticateToken } from "../middleware/authMiddleware";
const router = Router();
// 모든 공지사항 라우트에 인증 미들웨어 적용
router.use(authenticateToken);
// 공지사항 목록 조회 (is_active 필터 쿼리 파라미터 지원)
router.get("/", getSystemNotices);
// 공지사항 등록
router.post("/", createSystemNotice);
// 공지사항 수정
router.put("/:id", updateSystemNotice);
// 공지사항 삭제
router.delete("/:id", deleteSystemNotice);
export default router;

View File

@@ -27,6 +27,7 @@ import {
getCategoryColumnsByCompany, // 🆕 회사별 카테고리 컬럼 조회
getNumberingColumnsByCompany, // 채번 타입 컬럼 조회
multiTableSave, // 🆕 범용 다중 테이블 저장
validateExcelData, // 엑셀 업로드 전 데이터 검증
getTableEntityRelations, // 🆕 두 테이블 간 엔티티 관계 조회
getReferencedByTables, // 🆕 현재 테이블을 참조하는 테이블 조회
getTableConstraints, // 🆕 PK/인덱스 상태 조회
@@ -280,4 +281,9 @@ router.get("/menu/:menuObjid/category-columns", getCategoryColumnsByMenu);
*/
router.post("/multi-table-save", multiTableSave);
/**
* 엑셀 업로드 전 데이터 검증
*/
router.post("/validate-excel", validateExcelData);
export default router;