fix: production save errors and import HR dashboard data
Resolve invalid task creator IDs, fix API routing and file uploads on Vercel, and replace dummy seed data with HR_Dashboard import.
This commit is contained in:
@@ -12,14 +12,20 @@ app.use(helmet());
|
||||
const allowedOrigins = [
|
||||
'http://localhost:3000',
|
||||
'http://172.16.8.248:3000',
|
||||
'https://eene-dashboard.vercel.app',
|
||||
process.env.FRONTEND_URL,
|
||||
].filter(Boolean) as string[];
|
||||
|
||||
function isAllowedOrigin(origin: string): boolean {
|
||||
if (allowedOrigins.includes(origin)) return true;
|
||||
if (/^https:\/\/[\w-]+\.vercel\.app$/.test(origin)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
app.use(
|
||||
cors({
|
||||
origin: (origin, callback) => {
|
||||
// 같은 서버에서 직접 호출하거나 허용된 origin이면 통과
|
||||
if (!origin || allowedOrigins.includes(origin)) {
|
||||
if (!origin || isAllowedOrigin(origin)) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
callback(new Error(`CORS 차단: ${origin}`));
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
import { prisma } from './prisma';
|
||||
import { AppError } from '../middleware/errorHandler';
|
||||
|
||||
/** 업무 생성 시 사용할 creatorId (클라이언트의 잘못된 값 무시) */
|
||||
export async function resolveCreatorId(requested?: string): Promise<string> {
|
||||
if (requested?.trim() && requested !== 'system') {
|
||||
const user = await prisma.user.findUnique({ where: { id: requested.trim() } });
|
||||
if (user) return user.id;
|
||||
}
|
||||
|
||||
const admin = await prisma.user.findFirst({ where: { role: 'ADMIN' }, select: { id: true } });
|
||||
if (admin) return admin.id;
|
||||
|
||||
const anyUser = await prisma.user.findFirst({ select: { id: true } });
|
||||
if (anyUser) return anyUser.id;
|
||||
|
||||
throw new AppError(500, '사용자를 찾을 수 없습니다. 관리자 계정을 먼저 생성해 주세요.');
|
||||
}
|
||||
|
||||
/** task 작성자 또는 관리자 등 유효한 user id 반환 (FK 오류 방지) */
|
||||
export async function resolveTaskActorId(taskId: string): Promise<string> {
|
||||
const task = await prisma.task.findUnique({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Router } from 'express';
|
||||
import { prisma } from '../lib/prisma';
|
||||
import { resolveCreatorId } from '../lib/resolveUser';
|
||||
import { AppError } from '../middleware/errorHandler';
|
||||
|
||||
const router = Router();
|
||||
@@ -67,6 +68,8 @@ router.post('/', async (req, res, next) => {
|
||||
throw new AppError(400, '제목과 분기는 필수입니다.');
|
||||
}
|
||||
|
||||
const creatorId = await resolveCreatorId((req.body as Record<string, string>).creatorId);
|
||||
|
||||
const task = await prisma.task.create({
|
||||
data: {
|
||||
title,
|
||||
@@ -89,7 +92,7 @@ router.post('/', async (req, res, next) => {
|
||||
showProgress: showProgress !== undefined ? showProgress === 'true' || showProgress === true : true,
|
||||
keywords: keywords || null,
|
||||
assigneeId: assigneeId || null,
|
||||
creatorId: (req.body as Record<string, string>).creatorId ?? 'system',
|
||||
creatorId,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user