Build Modular Contact / Feedback Feature Module (FastKit Style)
#12 opened on Jun 27, 2025
Repository metrics
- Stars
- (1 star)
- PR merge metrics
- (PR metrics pending)
Description
🧩 Description
Create a reusable, pluggable Contact or Feedback module that allows users to submit messages or inquiries through a contact form. This module should store messages in the database and expose methods to:
-
Submit a new message
-
Retrieve all messages (for admin)
-
Delete a message
-
Email the message to an admin/support inbox
This module should:
-
Be class-based (controller, service, etc.)
-
Be easy to plug into any Express app
-
Support validations
-
Be future-proof (pagination, filters, mail support)
🧱 Why This Is Important
-
✅ Almost every app or website includes a "Contact Us" or "Feedback" form.
-
🧩 This module allows developers to plug in the functionality without reinventing the wheel.
-
🛠️ Supports easy extensions like emailing, reply status, priority, or categories.
🟢 Difficulty Level: Beginner → Intermediate
Familiarity with:
-
Express
-
TypeScript
-
Validation libraries (Zod or Joi)
✅ Tasks
📁 Folder Structure
src/
└── features/
└── Contact/
└── v1/
├── Contact.controller.ts
├── Contact.service.ts
├── Contact.validators.ts
├── Contact.constant.ts
├── Contact.model.ts
├── Contact.middleware.ts (optional)
├── Contact.demo.ts
└── README.md
📘 Model (Contact.model.ts)
- Create a schema-like interface:
export interface IContactMessage {
id: string;
name: string;
email: string;
subject: string;
message: string;
createdAt: Date;
// Other
}
- Design the model to be compatible with Mongoose, Prisma, or in-memory store.
📜 Validators (Contact.validators.ts)
Use Joi or Zod:
const createMessageSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
subject: z.string().min(2),
message: z.string().min(10),
// Other
});
Export as express middleware:
export const validateCreateMessage = validateZod(createMessageSchema);
⚙️ Service (Contact.service.ts)
class ContactService {
async createMessage(data: IContactMessage): Promise<IContactMessage> {}
async getAllMessages(): Promise<IContactMessage[]> {}
async deleteMessage(id: string): Promise<boolean> {}
}
📦 Controller (Contact.controller.ts)
- Expose class methods for:
class ContactController {
createMessage(req, res): Promise<void> {}
getMessages(req, res): Promise<void> {}
deleteMessage(req, res): Promise<void> {}
}
Use helpers like:
-
SendResponse.success()
-
SendResponse.error()
-
TryCatch.wrap()
🧾 Constants (Contact.constant.ts)
export const CONTACT_MESSAGES = {
CREATED: "Your message has been received!",
FETCHED: "Messages retrieved successfully",
DELETED: "Message deleted",
NOT_FOUND: "Message not found",
};
📄 Middleware (optional)
Add optional middleware like:
-
Spam detection
-
Rate limiting (1 message per 10 min)
-
CAPTCHA (placeholder for real validation)
📘 README.md
Include:
-
What this module does
-
How to use it
-
Example with controller methods in routes
-
How to customize schema or add emailing
🧪 Demo Code (Contact.demo.ts)
const contactController = new ContactController();
router.post(
'/contact',
validateCreateMessage,
contactController.createMessage
);
router.get(
'/contact',
verifyToken, // optional: for admin only
contactController.getMessages
);
router.delete(
'/contact/:id',
verifyToken,
allowRoles('admin'),
contactController.deleteMessage
);
📈 Optional Enhancements
[ ] Add support for email notification using nodemailer/sendgrid
[ ] Add reply status or admin response support
[ ] Add filters like subject, date range, email
[ ] Add pagination for large feedback datasets
🎯 Expected Outcome
[x] Pluggable contact/feedback module
[x] Reusable validation and controller
[x] Class-based architecture for clean API design
[x] Easy to test and extend
[x] Ideal for use in websites, dashboards, SaaS products
🙋🏻♂️ Looking For
Contributors who can:
-
Add email notification support
-
Add Mongoose
-
Add frontend usage example
-
Add admin reply or read status
-
Help test edge cases (spam, invalid format)