PDF Reports
Renders full audit reports, accessibility summaries, and single-page snapshots as PDFs using React-PDF, then stores them in AWS S3.
Email Delivery
Sends 30+ templated emails — OTPs, invites, trial lifecycle, billing alerts, uptime alerts — via Resend.
Job Queue
BullMQ + Redis for async PDF generation. Report requests return immediately; the worker picks them up in the background.
Agency & Promotions
Generates one-time Stripe coupon codes and dispatches agency lead notifications via Slack.
Service at a Glance
Architecture
The service has two parts that build and deploy together:Backend — Express + BullMQ Worker (server/)
Backend — Express + BullMQ Worker (server/)
The HTTP server exposes 5 endpoints. The most important one (
POST /api/v1/report) immediately enqueues a BullMQ job and returns a job ID. A co-located worker in the same process picks up the job asynchronously, generates the PDF, uploads it to S3, and sends the email.Frontend — React PDF Viewer (src/)
Frontend — React PDF Viewer (src/)
A Vite + React app that renders PDF reports in the browser using
@react-pdf/renderer’s <PDFViewer> component. Used for previewing report layouts during development. In production this serves as a standalone PDF preview tool.The React components in src/reports/ are shared between the frontend viewer and the backend PDF renderer — the same <Audit />, <Accessibility />, and <SinglePage /> components are used server-side via ReactPDF.renderToStream().Email Templates (server/emails/)
Email Templates (server/emails/)
35+ React Email components using
@react-email/components. Templates are rendered to HTML strings server-side and sent via Resend’s API. All templates share the Webyes brand colours (#0B66E4 primary, #2E3240 body text).Data Flow: Report Generation
1
API call from auditor-backend
The Python backend calls
POST /api/v1/report after a scan completes, passing the full audit data payload and the user’s email address.2
Job queued in Redis
The Express handler immediately adds a BullMQ job to the
auditReport-{env} queue in Redis and returns { success: true, jobId } to the caller.3
Worker generates PDF
The BullMQ worker picks up the job, calls
createTemplate(reportData, type), which renders the appropriate React-PDF component (Audit, Accessibility, or SinglePage) to a binary buffer.4
Upload to S3
The PDF buffer is uploaded to the
webyes-report S3 bucket with the audit_id as the object key.5
Email sent via Resend
A templated email with a download link (
/api/v1/scan/report/download/{id}) is sent to the user. The link generates a presigned S3 URL (valid for 1 hour) and redirects.6
Agency lead (optional)
If an
agencyEmail was provided in the request, a separate lead email is sent to the agency and a Slack notification is posted to the configured channel.