Initial commit - EENE Dashboard

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
EENE Dashboard
2026-05-29 18:07:10 +09:00
commit 22366dde72
64 changed files with 10483 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
import { Router } from 'express';
import path from 'path';
import fs from 'fs';
import { prisma } from '../lib/prisma';
import { upload } from '../middleware/upload';
import { AppError } from '../middleware/errorHandler';
const router = Router();
// POST /api/files/upload/:taskId — 파일 업로드
router.post('/upload/:taskId', upload.single('file'), async (req, res, next) => {
try {
if (!req.file) throw new AppError(400, '파일이 없습니다.');
const taskId = String(req.params.taskId);
const task = await prisma.task.findUnique({ where: { id: taskId } });
if (!task) throw new AppError(404, '업무를 찾을 수 없습니다.');
const fileRecord = await prisma.file.create({
data: {
taskId,
filename: req.file.filename,
originalName: req.file.originalname,
mimetype: req.file.mimetype,
size: req.file.size,
path: req.file.path,
uploadedBy: (req.body as Record<string, string>).uploadedBy ?? 'system',
},
});
res.status(201).json(fileRecord);
} catch (err) {
next(err);
}
});
// GET /api/files/:id/view — 파일 미리보기 (브라우저에서 바로 열기)
router.get('/:id/view', async (req, res, next) => {
try {
const file = await prisma.file.findUnique({ where: { id: req.params.id } });
if (!file) throw new AppError(404, '파일을 찾을 수 없습니다.');
if (!fs.existsSync(file.path)) throw new AppError(404, '파일이 서버에 없습니다.');
res.setHeader('Content-Type', file.mimetype);
res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(file.originalName)}"`);
fs.createReadStream(file.path).pipe(res);
} catch (err) {
next(err);
}
});
// GET /api/files/:id/download — 파일 다운로드
router.get('/:id/download', async (req, res, next) => {
try {
const file = await prisma.file.findUnique({ where: { id: req.params.id } });
if (!file) throw new AppError(404, '파일을 찾을 수 없습니다.');
if (!fs.existsSync(file.path)) throw new AppError(404, '파일이 서버에 없습니다.');
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(file.originalName)}"`);
res.download(file.path, file.originalName);
} catch (err) {
next(err);
}
});
// DELETE /api/files/:id — 파일 삭제
router.delete('/:id', async (req, res, next) => {
try {
const file = await prisma.file.findUnique({ where: { id: req.params.id } });
if (!file) throw new AppError(404, '파일을 찾을 수 없습니다.');
// 실제 파일 삭제
if (fs.existsSync(file.path)) {
fs.unlinkSync(file.path);
}
await prisma.file.delete({ where: { id: req.params.id } });
res.status(204).send();
} catch (err) {
next(err);
}
});
export default router;