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:
EENE Dashboard
2026-06-05 22:08:56 +09:00
parent 9abb58e5c8
commit 6066b5682d
12 changed files with 488 additions and 188 deletions

View File

@@ -1,6 +1,6 @@
import { useState, useEffect, useMemo } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../lib/apiClient';
import { apiClient, getApiErrorMessage } from '../lib/apiClient';
import { onDualMonitorEvent } from '../lib/dualMonitor';
import { ContextMenu } from '../components/common/ContextMenu';
import { FeedbackModal, type FeedbackFormData } from '../components/detail/FeedbackModal';
@@ -272,9 +272,7 @@ function DetailView({ task }: { task: TaskWithRelations }) {
if (item.displayName.trim()) {
form.append('displayName', item.displayName.trim());
}
await apiClient.post(`/files/upload/${task.id}`, form, {
headers: { 'Content-Type': 'multipart/form-data' },
});
await apiClient.post(`/files/upload/${task.id}`, form);
}
};
@@ -313,9 +311,7 @@ function DetailView({ task }: { task: TaskWithRelations }) {
for (const rep of filePayload.replacements) {
const form = new FormData();
form.append('file', rep.file);
await apiClient.post(`/files/${rep.id}/replace`, form, {
headers: { 'Content-Type': 'multipart/form-data' },
});
await apiClient.post(`/files/${rep.id}/replace`, form);
}
for (const edit of filePayload.existingEdits) {
const original = files.find((f) => f.id === edit.id);
@@ -334,17 +330,13 @@ function DetailView({ task }: { task: TaskWithRelations }) {
await uploadFiles(milestoneId, filePayload.uploads);
}
} catch (err: unknown) {
const ax = err as { response?: { data?: { message?: string } }; message?: string };
const msg = ax.response?.data?.message || ax.message || '파일 처리에 실패했습니다.';
alert(`단계는 저장됐지만 ${msg}`);
alert(`단계는 저장됐지만 ${getApiErrorMessage(err, '파일 처리에 실패했습니다.')}`);
}
await qc.invalidateQueries({ queryKey: ['task', task.id] });
setStageModal(null);
} catch (err: unknown) {
const ax = err as { response?: { data?: { message?: string } }; message?: string };
const msg = ax.response?.data?.message || ax.message || '단계 저장에 실패했습니다.';
alert(msg);
alert(getApiErrorMessage(err, '단계 저장에 실패했습니다.'));
} finally {
setStageSaving(false);
}
@@ -372,9 +364,7 @@ function DetailView({ task }: { task: TaskWithRelations }) {
await qc.invalidateQueries({ queryKey: ['task', task.id] });
setFeedbackModal(null);
} catch (err: unknown) {
const ax = err as { response?: { data?: { message?: string } }; message?: string };
const msg = ax.response?.data?.message || ax.message || '피드백 저장에 실패했습니다.';
alert(msg);
alert(getApiErrorMessage(err, '피드백 저장에 실패했습니다.'));
} finally {
setFeedbackSaving(false);
}