-
-
Notifications
You must be signed in to change notification settings - Fork 0
Description
📅 Calendar & Reminder Feature (FastKit-Style)
🧩 Description
-
Create a modular calendar/reminder feature that lets users:
-
Add, update, and delete events/tasks
-
Set reminder times
-
Automatically receive email reminders via NodeMailer
-
Easily plug this feature into any Express project without writing boilerplate
This module should be:
-
Class-based
-
Pluggable
-
Email-ready with customizable mail templates
-
Ready for production-scale use with date-based job scheduling
🧱 Why This Is Important
-
🧘 Most apps need event scheduling (personal dashboards, health, team tools)
-
⏰ Reminder emails improve engagement and reduce forgetfulness
-
🔌 Clean, modular design makes it easy to reuse or extend
🟢 Difficulty Level: Intermediate → Advanced
Familiarity with:
-
NodeMailer
-
Express + TypeScript
-
Async services & scheduling (e.g., node-cron or setTimeout)
-
Zod/Joi validation
-
Date/time manipulation (date-fns, dayjs)
✅ Tasks
📁 Folder Structure
src/
└── features/
└── Calendar/
└── v1/
├── Calendar.controller.ts
├── Calendar.service.ts
├── Calendar.validators.ts
├── Calendar.constant.ts
├── Calendar.model.ts
├── Calendar.reminder.ts # Email scheduler logic
├── Calendar.demo.ts
└── README.md📘 Model (Calendar.model.ts)
export interface ICalendarEvent {
id: string;
title: string;
description?: string;
startTime: Date;
endTime: Date;
remindBeforeInMinutes?: number; // e.g. 10 min before
email: string; // whom to send reminder
status?: 'pending' | 'completed';
// Other
}📜 Validators (Calendar.validators.ts)
Use Zod or Joi:
const createEventSchema = z.object({
title: z.string().min(2),
startTime: z.string().datetime(),
endTime: z.string().datetime(),
remindBeforeInMinutes: z.number().optional(),
email: z.string().email(),
});✅ Export validation middleware.
⚙️ Service (Calendar.service.ts)
class CalendarService {
async createEvent(data: ICalendarEvent): Promise<ICalendarEvent> {}
async getAllEvents(): Promise<ICalendarEvent[]> {}
async updateEvent(id: string, updates: Partial<ICalendarEvent>): Promise<ICalendarEvent> {}
async deleteEvent(id: string): Promise<boolean> {}
}📦 Controller (Calendar.controller.ts)
Bind-safe controller:
class CalendarController {
createEvent(req, res): Promise<void>;
getEvents(req, res): Promise<void>;
updateEvent(req, res): Promise<void>;
deleteEvent(req, res): Promise<void>;
}✅ Uses:
-
TryCatch.wrap()
-
SendResponse.success() / .error()
🔔 Reminder Handler (Calendar.reminder.ts)
This file:
-
Schedules email reminders based on startTime - remindBeforeInMinutes
-
Uses NodeMailer or SendGrid for sending
-
Optionally logs to Logger.ts
class ReminderScheduler {
static schedule(event: ICalendarEvent): void {
const delay = event.startTime.getTime() - Date.now() - (event.remindBeforeInMinutes || 10) * 60000;
if (delay <= 0) return;
setTimeout(() => {
EmailSender.sendReminder(event.email, event.title, event.startTime);
}, delay);
}
}📧 Email Sender (in utils/Email.ts or local helper)
import nodemailer from 'nodemailer';
export class EmailSender {
static async sendReminder(to: string, title: string, startTime: Date) {
const transport = nodemailer.createTransport({ /* SMTP config */ });
await transport.sendMail({
to,
subject: `Reminder: ${title}`,
html: `<p>This is a reminder for your event: <strong>${title}</strong> scheduled at ${startTime}.</p>`,
});
}
}🧾 Constants (Calendar.constant.ts)
export const CALENDAR_MESSAGES = {
CREATED: "Event created and reminder scheduled.",
UPDATED: "Event updated.",
DELETED: "Event deleted.",
NOT_FOUND: "Event not found.",
};📘 README.md
Include:
-
How to create events
-
Example of reminder config
-
How reminder emails work
-
Customizing NodeMailer transport
-
How to use controller directly in routes
🧪 Demo Code (Calendar.demo.ts)
router.post('/calendar/eventCreate', validateCreateEvent, calendarController.createEvent);
router.get('/calendar', calendarController.getEvents);
router.put('/calendar/:id', validateUpdateEvent, calendarController.updateEvent);
router.delete('/calendar/:id', calendarController.deleteEvent);🎯 Expected Outcome
[x] Plug-n-play calendar/reminder module
[x] Clean separation of controller, service, validators, scheduler
[x] Auto-schedule emails on event creation
[x] Built-in NodeMailer support
[x] Easy to customize timing, templates, provider
🙋🏻♂️ Looking For
Contributors for:
-
Adding recurring events support (daily, weekly)
-
Adding cron-based implementation (node-cron)
-
Supporting SMS (Twilio)
-
Frontend sample
-
Email templates (tsx)
📦 Bonus Ideas
-
Add “mark as completed” status
-
Add calendar ICS export
-
Add Google Calendar sync in future
-
Export reminders in CSV