import { setHeader } from 'h3' import { format } from 'date-fns' import { prisma } from '../../utils/db' import { requireUser } from '../../utils/auth' export default defineEventHandler(async (event) => { const user = await requireUser(event) const rows = await prisma.transaction.findMany({ where: { userId: user.id }, include: { asset: true, category: { include: { parent: true } } }, orderBy: { occurredAt: 'desc' } }) const escape = (value: unknown) => `"${String(value ?? '').replaceAll('"', '""')}"` const categoryName = (row: typeof rows[number]) => row.category.name const parentCategoryName = (row: typeof rows[number]) => row.category.parent?.name || '' const lines = [ ['날짜', '유형', '자산', '상위분류', '분류', '금액', '내용', '메모', '위도', '경도', '거래ID'].map(escape).join(','), ...rows.map(row => [ format(row.occurredAt, 'yyyy-MM-dd'), row.type === 'income' ? '수입' : '지출', row.asset.name, parentCategoryName(row), categoryName(row), row.amount, row.title, row.memo, row.latitude, row.longitude, row.id ].map(escape).join(',')) ] setHeader(event, 'content-type', 'text/csv; charset=utf-8') setHeader(event, 'content-disposition', 'attachment; filename="money-transactions.csv"') return `\uFEFF${lines.join('\n')}` })