portfolio

πŸ“… Appointment Booking System

React Node.js MongoDB Express Stripe

Multi-tenant scheduling platform with smart slot management, payment integration, and automated notifications

πŸ“‹ Problem Statement

Service-based businesses face scheduling challenges:

πŸ’‘ Solution: Smart Appointment Booking System

A comprehensive multi-tenant platform that automates scheduling, payments, and notifications for service businesses like doctors, salons, and consultants.

Key Features

πŸ—οΈ Architecture

```mermaid graph TB A[React Frontend] –>|API Calls| B[Express Backend] B –>|CRUD| C[MongoDB] B –>|Send SMS| D[AWS SNS] B –>|Process Payment| E[Stripe API] F[Slot Manager] –>|Check Availability| C B –>|Use| F G[Cron Jobs] –>|Trigger| H[Reminder Service] H –>|Send| D

style A fill:#61DAFB
style B fill:#000000
style C fill:#47A248
style E fill:#008CDD \`\`\`

Booking Flow

  1. Customer selects service and preferred date/time
  2. Slot Manager checks availability in real-time
  3. Customer provides details and makes payment via Stripe
  4. Booking confirmed and stored in MongoDB
  5. SMS confirmation sent immediately via AWS SNS
  6. Reminder sent 24 hours before appointment
  7. Post-appointment feedback request sent

πŸ“ Project Structure

``` appointment-booking-system/ β”œβ”€β”€ backend/ β”‚ β”œβ”€β”€ controllers/ β”‚ β”‚ β”œβ”€β”€ appointmentController.js # Booking logic β”‚ β”‚ β”œβ”€β”€ userController.js # User management β”‚ β”‚ └── paymentController.js # Stripe integration β”‚ β”œβ”€β”€ models/ β”‚ β”‚ β”œβ”€β”€ Appointment.js # Appointment schema β”‚ β”‚ β”œβ”€β”€ User.js # User schema β”‚ β”‚ └── Business.js # Business schema β”‚ β”œβ”€β”€ services/ β”‚ β”‚ β”œβ”€β”€ slot_manager.js # Smart slot algorithm β”‚ β”‚ β”œβ”€β”€ sms_service.js # AWS SNS integration β”‚ β”‚ └── payment_service.js # Stripe wrapper β”‚ β”œβ”€β”€ routes/ β”‚ β”‚ └── api.js # API routes β”‚ └── server.js # Express server β”œβ”€β”€ frontend/ β”‚ β”œβ”€β”€ src/ β”‚ β”‚ β”œβ”€β”€ components/ β”‚ β”‚ β”‚ β”œβ”€β”€ Calendar.jsx # Booking calendar β”‚ β”‚ β”‚ β”œβ”€β”€ ServiceList.jsx # Available services β”‚ β”‚ β”‚ β”œβ”€β”€ BookingForm.jsx # Appointment form β”‚ β”‚ β”‚ └── Dashboard.jsx # Admin dashboard β”‚ β”‚ β”œβ”€β”€ pages/ β”‚ β”‚ β”‚ β”œβ”€β”€ Home.jsx β”‚ β”‚ β”‚ β”œβ”€β”€ Booking.jsx β”‚ β”‚ β”‚ └── Admin.jsx β”‚ β”‚ └── App.jsx β”‚ └── package.json └── README.md ```

πŸš€ Setup & Deployment

Prerequisites

Backend Setup

  1. Clone and install ```bash git clone https://github.com/Abhinandansinha01/portfolio.git cd appointment-booking-system/backend npm install ```

  2. Configure environment variables ```bash

    Create .env file

    cat > .env « EOF PORT=5000 MONGODB_URI=mongodb://localhost:27017/appointments STRIPE_SECRET_KEY=sk_test_your_stripe_key AWS_ACCESS_KEY_ID=your_aws_key AWS_SECRET_ACCESS_KEY=your_aws_secret AWS_REGION=us-east-1 SNS_TOPIC_ARN=arn:aws:sns:us-east-1:123456789:appointments JWT_SECRET=your_jwt_secret EOF ```

  3. Start MongoDB ```bash

    If using local MongoDB

    mongod –dbpath /data/db ```

  4. Run backend ```bash npm run dev

    Server runs on http://localhost:5000

    ```

Frontend Setup

  1. Navigate and install ```bash cd ../frontend npm install ```

  2. Configure API endpoint ```bash

    Create .env

    echo β€œREACT_APP_API_URL=http://localhost:5000/api” > .env echo β€œREACT_APP_STRIPE_PUBLIC_KEY=pk_test_your_public_key” » .env ```

  3. Run frontend ```bash npm start

    App runs on http://localhost:3000

    ```

🧠 Smart Slot Manager Algorithm

The core innovation of this system is the intelligent slot management:

```javascript // slot_manager.js class SlotManager { constructor(business) { this.business = business; this.bufferTime = business.bufferTime || 15; // minutes }

async getAvailableSlots(date, serviceId) { const service = await Service.findById(serviceId); const duration = service.duration; const businessHours = this.business.hours[date.getDay()];

// Generate all possible slots
const allSlots = this.generateTimeSlots(
  businessHours.start,
  businessHours.end,
  duration + this.bufferTime
);

// Get existing bookings for the date
const bookings = await Appointment.find({
  businessId: this.business._id,
  date: date,
  status: { $ne: 'cancelled' }
});

// Filter out booked slots
const availableSlots = allSlots.filter(slot => {
  return !this.hasConflict(slot, duration, bookings);
});

return availableSlots;   }

hasConflict(slot, duration, bookings) { const slotStart = new Date(slot); const slotEnd = new Date(slotStart.getTime() + duration * 60000);

return bookings.some(booking => {
  const bookingStart = new Date(booking.startTime);
  const bookingEnd = new Date(booking.endTime);
  
  // Check for overlap
  return (slotStart < bookingEnd && slotEnd > bookingStart);
});   }

generateTimeSlots(start, end, interval) { const slots = []; let current = new Date(`2000-01-01T${start}`); const endTime = new Date(`2000-01-01T${end}`);

while (current < endTime) {
  slots.push(current.toTimeString().slice(0, 5));
  current = new Date(current.getTime() + interval * 60000);
}

return slots;   } } \`\`\`

Key Algorithm Features

πŸ’³ Payment Integration

Stripe Checkout Flow

```javascript // payment_service.js const createPaymentIntent = async (amount, customerId) => { const paymentIntent = await stripe.paymentIntents.create({ amount: amount * 100, // Convert to cents currency: β€˜usd’, customer: customerId, payment_method_types: [β€˜card’], metadata: { type: β€˜appointment_deposit’ } });

return paymentIntent.client_secret; }; ```

Payment Features

πŸ“² SMS Notification System

AWS SNS Integration

```javascript // sms_service.js const sendSMS = async (phoneNumber, message) => { const params = { Message: message, PhoneNumber: phoneNumber, MessageAttributes: { β€˜AWS.SNS.SMS.SMSType’: { DataType: β€˜String’, StringValue: β€˜Transactional’ } } };

await sns.publish(params).promise(); };

// Notification templates const templates = { confirmation: (name, date, time) => `Hi ${name}! Your appointment is confirmed for ${date} at ${time}. Reply CANCEL to cancel.`,

reminder: (name, hours) => `Hi ${name}! Reminder: Your appointment is in ${hours} hours. See you soon!`,

cancellation: (name) => `Hi ${name}, your appointment has been cancelled. Your refund will be processed in 5-7 days.` }; ```

Notification Types

πŸ“Š Database Schema

Appointment Model

```javascript const appointmentSchema = new Schema({ businessId: { type: ObjectId, ref: β€˜Business’, required: true }, customerId: { type: ObjectId, ref: β€˜User’, required: true }, serviceId: { type: ObjectId, ref: β€˜Service’, required: true }, date: { type: Date, required: true }, startTime: { type: Date, required: true }, endTime: { type: Date, required: true }, status: { type: String, enum: [β€˜pending’, β€˜confirmed’, β€˜completed’, β€˜cancelled’], default: β€˜pending’ }, payment: { amount: Number, status: String, stripePaymentId: String }, notes: String, createdAt: { type: Date, default: Date.now } }); ```

πŸ“ˆ Analytics Dashboard

Key Metrics

Reports

πŸ” Security Features

🎯 Multi-Tenant Support

Business Isolation

Tenant Management

```javascript // Business schema const businessSchema = new Schema({ name: String, slug: { type: String, unique: true }, logo: String, hours: { monday: { start: String, end: String }, tuesday: { start: String, end: String }, // … other days }, services: [{ type: ObjectId, ref: β€˜Service’ }], stripeAccountId: String, settings: { bufferTime: Number, cancellationPolicy: String, depositPercentage: Number } }); ```

πŸ”„ Future Enhancements

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

This project is open source and available under the MIT License.

πŸ‘€ Author

Abhinandan Sinha


Scheduling made simple, one appointment at a time πŸ“