Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
The Heyme application is a web-based service that allows users to record and send video messages to their future selves or others. The architecture is built on a modern Jamstack foundation, leveraging a Next.js frontend, a serverless API for backend logic, a relational database for storage, and a third-party service for transactional email delivery. This design prioritizes scalability, maintainability, and a seamless user experience.
The core functionality revolves around scheduling and dispatching messages. A user records a video, provides recipient details and a future delivery date. This information is stored in a MySQL database. A scheduled task runs daily to check for messages due for delivery, and upon finding them, uses the Zeptomail service to send an email to the recipient with a link to watch the video.
Core Technologies and Services
The application integrates several key technologies and external services to function. The primary framework is Next.js, which handles both the client-side rendering and the serverless API endpoints.
Sources: README.md:39-45, package.json:11-80
| Technology/Service | Role | Key Packages |
|---|---|---|
| Framework | Next.js | next, react, react-dom |
| Database | MySQL | mysql, knex |
| Email Service | Zeptomail | zeptomail |
| Styling | Tailwind CSS | tailwindcss, tailwindcss-animate, clsx |
| UI Components | Radix UI | @radix-ui/* |
| Deployment | Vercel | @vercel/analytics |
| Monitoring | Highlight.run | @highlight-run/next |
| Date/Time | Day.js | dayjs |
High-Level Architecture Diagram
This diagram illustrates the main components of the Heyme application and their interactions.
This diagram shows the flow from the user interacting with the Next.js frontend, data being stored in MySQL, the serverless function dispatching emails via Zeptomail, and the user ultimately viewing the video.
Sources: README.md:39-48, pages/api/dispatch.ts
Frontend
The frontend is built with Next.js and React. It uses a page-based routing system and a component-driven architecture.
Sources: pages/index.tsx, pages/_app.tsx, pages/_document.tsx, components/site-header.tsx
Application Shell
The main application shell is defined in _app.tsx and _document.tsx.
pages/_document.tsx: Customizes the server-rendered<html>and<body>tags. It sets the language to English, applies default dark mode classes, and links favicons.pages/_app.tsx: This is the top-level component that wraps all pages. It initializes theThemeProviderfor light/dark mode, integrates Vercel Analytics and Highlight.run for monitoring, and applies global styles and fonts.
Sources: pages/_document.tsx:4-16, pages/_app.tsx:5-29
UI and Styling
The user interface is built using a combination of custom React components and a pre-built UI library.
- Styling: Tailwind CSS is used for utility-first styling, configured in
tailwind.config.js. - Components: The application uses Radix UI primitives for accessible and unstyled components like
Tabs,ScrollArea, andNavigationMenu, which are then styled with Tailwind. These are found in thecomponents/ui/directory. - Structure: Reusable components like
SiteHeader,Testimonials, andFootercreate a consistent layout across the application.
Sources: tailwind.config.js, components/ui/tabs.tsx, components/ui/scroll-area.tsx, components/testimonials.tsx
Backend API
The backend logic is implemented as serverless functions within the Next.js pages/api directory. The most critical endpoint is /api/dispatch.
Email Dispatch System (/api/dispatch)
This endpoint is responsible for sending out the scheduled video messages. It is designed to be triggered by a scheduled task (e.g., a cron job).
Sources: pages/api/dispatch.ts
Process Flow
The following sequence diagram details the steps taken by the dispatch handler.
Sources: pages/api/dispatch.ts:35-95
Key Functions
| Function | Description | Source File |
|---|---|---|
handleDispatchEmails | Main handler for the API route. Orchestrates the entire process. | pages/api/dispatch.ts:35-95 |
fetchAllVideosForToday | Queries the Videos table for all records where send_at is the current date. | pages/api/dispatch.ts:20-23 |
updateVideoToSent | Updates a video's sent status to 1 in the database after the email is sent. | pages/api/dispatch.ts:25-29 |
getEmailContent | Reads an HTML template from public/mails/email.html and populates it with dynamic data. | pages/api/dispatch.ts:9-18 |
Database Schema
The application uses a MySQL database. While the full schema is not present, the Videos table structure can be inferred from the API and test files.
Sources: pages/api/dispatch.ts:20-29, 50-70, tests/api/watch.spec.tsx:19-24
Videos Table ER Diagram
Field Descriptions
| Field | Type | Description |
|---|---|---|
id | int | Primary key for the video record. |
video_url | varchar | URL of the recorded video, likely hosted on a service like Cloudinary. |
created_at | date | The date the message was created. |
send_at | date | The scheduled date for the message to be sent. Used for querying. |
email | varchar | The recipient's email address. |
send_to | varchar | Indicates if the message is to "yourself" or someone else. |
sent | tinyint | A boolean flag (0 or 1) to indicate if the email has been dispatched. |
Sources: pages/api/dispatch.ts:22, 26, 50, 58, 61, tests/api/watch.spec.tsx:20-23
Email Templating
Emails are generated from a static HTML file with placeholders. The getEmailContent function replaces these placeholders with dynamic content before sending.
Sources: public/mails/email.html, pages/api/dispatch.ts:9-18
| Placeholder | Replaced With |
|---|---|
{{REPLACE_WATCH_LINK_HERE}} | The unique URL to watch the video (e.g., https://heyme.io/watch/VIDEO_ID). |
{{REPLACE_GREETING_HERE}} | A dynamic greeting based on who sent the message. |
{{REPLACE_BODY_HERE}} | A static body text explaining the service. |
{{REPLACE_OUTRO_HERE}} | A static closing message. |