eletrotupi / tcc/ api/src/reports/report.router.tsd28d4c0c63d8f95f839b180d4753a0160e22f6bc
1.7 KB | 60 lines Raw
1
import { Router, Response, NextFunction } from 'express'
2
import React from 'react'
3
import { renderToBuffer } from '@react-pdf/renderer'
4
import { z } from 'zod'
5
import { requireAuth, AuthenticatedRequest } from '@app/middleware/auth'
6
import { buildReportData } from './report.data'
7
import ReportDocument from './ReportDocument'
8

9
const router = Router()
10

11
const ReportSchema = z
12
  .object({
13
    periodStart: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
14
    periodEnd: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
15
  })
16
  .refine(
17
    (d) => {
18
      const start = new Date(d.periodStart)
19
      const end = new Date(d.periodEnd)
20
      const diff = (end.getTime() - start.getTime()) / 86_400_000
21
      return diff > 0 && diff <= 90
22
    },
23
    { message: 'periodEnd must be after periodStart and range ≤ 90 days' },
24
  )
25

26
router.post(
27
  '/',
28
  requireAuth,
29
  async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
30
    try {
31
      const parsed = ReportSchema.safeParse(req.body)
32
      if (!parsed.success) {
33
        return res.status(400).json({ error: parsed.error.issues[0]?.message ?? 'Invalid request' })
34
      }
35

36
      const { periodStart, periodEnd } = parsed.data
37
      const data = await buildReportData(
38
        req.userId!,
39
        new Date(periodStart),
40
        new Date(periodEnd),
41
      )
42

43
      const element = React.createElement(ReportDocument, { data })
44
      const buffer = await renderToBuffer(
45
        element as React.ReactElement<any>,
46
      )
47

48
      res.setHeader('Content-Type', 'application/pdf')
49
      res.setHeader(
50
        'Content-Disposition',
51
        `attachment; filename="Nexo-report-${periodStart.slice(0, 7)}.pdf"`,
52
      )
53
      return res.send(buffer)
54
    } catch (err) {
55
      return next(err)
56
    }
57
  },
58
)
59

60
export default router