Back to Projects
2023ProjectStartup • Web

Appoim

Appoim is a flexible professional booking and scheduling platform that enables professionals to create detailed profiles, define custom availability, offer free or paid sessions, manage bookings and payments, and host events or webinars. The platform is built around a reusable scheduling engine designed to handle dynamic availability, slot generation, booking concurrency, payment workflows, and event registration.

Appoim

Appoim: Building a Flexible Professional Booking, Scheduling & Event Platform

Modern professionals increasingly need a simple way to make their expertise directly accessible to others.

A doctor may want to offer a 30-minute consultation. A lawyer may want to provide an advisory session. A software engineer may want to conduct a technical mentoring session. A startup founder may want to offer one-on-one calls or host a webinar.

The common requirement is simple:

Define availability → define a service → define pricing → accept bookings → manage payments → deliver the session.

Appoim is designed around this workflow.

Appoim is a professional discovery and booking platform where professionals can create detailed profiles, publish flexible availability schedules, create free or paid appointments, host events and webinars, and allow users to discover and book those services.

The interesting engineering challenge is not simply building another appointment-booking application.

The challenge is building a generic scheduling and booking system that can support many different professional use cases without hard-coding the workflow around a single industry.


1. What Is Appoim?

Appoim connects two primary types of users:

Professionals

Professionals can:

  • Create a detailed professional profile
  • Add education and qualifications
  • Add experience
  • Add skills
  • Add descriptions
  • Add social media profiles
  • Define professional categories
  • Create appointment schedules
  • Configure availability
  • Set pricing
  • Create free or paid sessions
  • Configure payment timing
  • Create events and webinars
  • Manage bookings

Users

Users can:

  • Discover professionals
  • Search by category
  • View professional profiles
  • Explore available schedules
  • Select a suitable time
  • Book an appointment
  • Make payments when required
  • Register for events
  • Attend free or paid events

The platform therefore has two major workflows:

Professional
     │
     ├── Profile
     ├── Availability
     ├── Services
     ├── Pricing
     └── Events
              │
              ▼
           Appoim
              │
              ▼
            User
              │
     ├── Discover
     ├── Select
     ├── Book
     ├── Pay
     └── Attend

2. The Core Engineering Problem

At first glance, Appoim looks like a simple CRUD application.

It is not.

The complexity starts when professionals need complete control over their availability.

For example, a professional could create:

Technical Consultation
Duration: 30 minutes
Price: ₹999
Payment: Before booking
Availability:
Monday    10:00 - 13:00
Wednesday 14:00 - 18:00
Friday    10:00 - 12:00

Another professional could configure:

Career Mentoring
Duration: 60 minutes
Price: Free
Payment: Not required
Availability:
Saturday 10:00 - 17:00

Another could create:

Startup Advisory
Duration: 45 minutes
Price: ₹2,500
Payment: After session

Therefore, the scheduling system cannot assume:

  • One fixed duration
  • One availability pattern
  • One payment model
  • One professional category
  • One type of session

The platform needs a flexible scheduling model.


3. Authentication Architecture

Appoim uses a low-friction authentication experience.

Instead of forcing users to remember passwords, authentication can be based on OTP verification.

The basic flow is:

Enter Mobile Number
        │
        ▼
Generate OTP
        │
        ▼
Send OTP
        │
        ▼
Verify OTP
        │
        ▼
Create / Retrieve User
        │
        ▼
Generate Session

The important architectural distinction is between:

Authentication

and

Application Profile

A user can authenticate successfully without necessarily becoming a professional.

For example:

User
 │
 ├── Authentication
 │      └── Mobile + OTP
 │
 └── Application Role
        ├── User
        └── Professional

This keeps authentication independent from professional profile data.


4. Professional Profile System

The professional profile is one of the core entities of Appoim.

A professional profile can contain:

Professional
│
├── Basic Information
│   ├── Name
│   ├── Profile Image
│   └── Description
│
├── Professional Information
│   ├── Category
│   ├── Skills
│   ├── Experience
│   └── Qualifications
│
├── Education
│
├── Social Links
│   ├── LinkedIn
│   ├── X
│   ├── Instagram
│   └── Website
│
├── Services
│
├── Availability
│
└── Events

The profile system is intentionally generic.

The platform should not assume that every professional is a doctor, lawyer, consultant, or mentor.

Instead, the system models a professional using flexible attributes.

For example:

Category
    └── Software Engineering

Skills
    ├── Go
    ├── Node.js
    ├── Distributed Systems
    └── System Design

Experience
    └── 8+ years

Education
    └── Computer Science

Another professional can have an entirely different skill and qualification structure.


5. Professional Discovery

Once professionals are registered, they become discoverable through the platform.

The discovery layer can organize professionals by:

  • Category
  • Skills
  • Experience
  • Professional type
  • Availability
  • Profile information

A simplified search flow is:

User Search
     │
     ▼
Search Query
     │
     ▼
Category / Skill Filters
     │
     ▼
Professional Index
     │
     ▼
Ranked Results
     │
     ▼
Professional Profile

The important design principle is separating the professional profile model from the search representation.

The database can remain optimized for transactional operations while a search/index layer can later optimize:

  • Text search
  • Filtering
  • Ranking
  • Autocomplete
  • Category discovery

6. Flexible Schedule Architecture

Scheduling is the most important technical component of Appoim.

A schedule is not simply a calendar entry.

A schedule represents a bookable service definition.

For example:

Schedule
────────────────────────
Title: Technical Consultation
Duration: 30 minutes
Price: ₹999
Payment: Before booking
Type: Paid
Status: Active

The schedule then has availability rules.

Availability
────────────────────────
Monday
10:00 → 13:00

Wednesday
14:00 → 18:00

Friday
10:00 → 12:00

This separation is important.

Instead of storing every future appointment as an individual availability record, Appoim can represent availability as rules and generate bookable slots from those rules.


7. Availability Rule vs Booking

A critical distinction in the architecture is:

Availability

versus:

Booking

Availability answers:

When is the professional willing to accept bookings?

Booking answers:

Which specific time has already been reserved?

For example:

Availability:
Monday 10:00 - 13:00

A 30-minute schedule can generate:

10:00 - 10:30
10:30 - 11:00
11:00 - 11:30
11:30 - 12:00
12:00 - 12:30
12:30 - 13:00

If:

10:30 - 11:00

is booked, the remaining slots remain available.

This means availability should not be treated as a static list of slots.


8. Slot Generation

A simplified slot-generation algorithm looks like:

Input:
    Availability Window
    Schedule Duration
    Buffer
    Existing Bookings

Example:

Availability:
10:00 - 13:00

Duration:
30 minutes

Generated Slots:
10:00 - 10:30
10:30 - 11:00
11:00 - 11:30
11:30 - 12:00
12:00 - 12:30
12:30 - 13:00

Then existing bookings are applied:

Existing Booking:
11:00 - 11:30

Result:

10:00 - 10:30   AVAILABLE
10:30 - 11:00   AVAILABLE
11:00 - 11:30   BOOKED
11:30 - 12:00   AVAILABLE
12:00 - 12:30   AVAILABLE
12:30 - 13:00   AVAILABLE

This approach allows Appoim to support arbitrary schedule durations.


9. Preventing Double Booking

One of the most important backend problems is concurrency.

Imagine two users select the same slot:

User A ───────┐
              ├── 11:00 - 11:30
User B ───────┘

Both requests could reach the server almost simultaneously.

A naive implementation might do:

Check availability
      ↓
Slot available
      ↓
Create booking

for both users.

This can result in:

Booking A → SUCCESS
Booking B → SUCCESS

which is incorrect.

The booking system therefore needs an atomic reservation mechanism.

A safer conceptual workflow is:

Request Booking
      │
      ▼
Validate Slot
      │
      ▼
Acquire Reservation / Lock
      │
      ▼
Re-check Availability
      │
      ▼
Create Booking
      │
      ▼
Release Lock

Depending on the persistence layer, this can be implemented using:

  • Database transactions
  • Unique constraints
  • Atomic updates
  • Distributed locks
  • Temporary slot reservations

The important rule is:

Availability validation and booking creation must be concurrency-safe.

10. Temporary Slot Reservation

Paid bookings introduce another challenge.

A user may select a slot and then take time to complete payment.

For example:

10:00
 │
 ├── User selects slot
 │
 ├── Payment initiated
 │
 ├── Payment processing
 │
 └── Payment completed

If the system does not temporarily reserve the slot, another user could book it during the payment process.

A better workflow is:

AVAILABLE
    │
    ▼
HELD
    │
    ├── Payment Success ──► CONFIRMED
    │
    └── Timeout / Failure ─► AVAILABLE

For example:

Hold Duration: 10 minutes

After the hold expires, the slot becomes available again.

This is especially important for high-demand schedules.


11. Payment Architecture

Appoim supports different payment configurations.

A professional can define whether payment is:

Free

or:

Paid

and potentially whether payment is required:

Before Booking
After Booking / Session

This means payment should not be tightly coupled to the appointment entity.

A conceptual model is:

Schedule
   │
   ├── Pricing
   │
   ├── Payment Requirement
   │
   └── Payment Timing

Then:

Booking
   │
   └── Payment
         ├── Pending
         ├── Processing
         ├── Successful
         └── Failed

This makes the payment layer extensible.


12. Payment State Machine

Payments should be modeled as a state machine rather than a simple boolean.

For example:

PENDING
   │
   ▼
PROCESSING
   │
   ├── SUCCESS
   │
   └── FAILED

The booking itself can have an independent state:

Booking
├── Pending
├── Held
├── Confirmed
├── Cancelled
├── Completed
└── Expired

Keeping payment state and booking state separate is important.

For example:

Payment = SUCCESS
Booking = CONFIRMED

is normal.

But:

Payment = FAILED
Booking = PENDING

may occur temporarily during a payment attempt.


13. Payment Webhooks

The backend should not rely solely on the frontend to determine whether payment succeeded.

Instead:

User
 │
 ▼
Payment Gateway
 │
 ▼
Payment Processing
 │
 ▼
Webhook
 │
 ▼
Appoim Backend
 │
 ▼
Verify Payment
 │
 ▼
Update Payment
 │
 ▼
Confirm Booking

The webhook becomes the authoritative mechanism for payment confirmation.

This protects the system from scenarios such as:

  • Browser closed after payment
  • Network interruption
  • Frontend timeout
  • Duplicate requests
  • Client-side manipulation

Webhook processing should also be idempotent.

If the same webhook is delivered multiple times:

Webhook #1 → Process
Webhook #2 → Ignore duplicate
Webhook #3 → Ignore duplicate

The booking should still only be confirmed once.


14. Free vs Paid Schedules

Appoim supports both free and paid schedules.

Free schedule

User
 │
 ▼
Select Schedule
 │
 ▼
Select Time
 │
 ▼
Create Booking
 │
 ▼
Confirmed

Paid schedule

User
 │
 ▼
Select Schedule
 │
 ▼
Select Time
 │
 ▼
Create Temporary Hold
 │
 ▼
Payment
 │
 ▼
Payment Confirmation
 │
 ▼
Booking Confirmed

This allows the same scheduling engine to support both use cases.


15. Payment After Session

Another interesting requirement is delayed payment.

For example:

Schedule:
Technical Consultation

Price:
₹1,000

Payment:
After Session

The booking can therefore be confirmed without an initial payment transaction.

The system can represent:

Booking
    │
    ├── Appointment
    └── Payment
          └── PENDING

After the session:

Session Completed
       │
       ▼
Payment Request
       │
       ▼
Payment Completed

This demonstrates why payment should be modeled independently from scheduling.


16. Event System

Appoim is not limited to one-to-one appointments.

Professionals can also create events.

Examples:

  • Webinars
  • Workshops
  • Technical sessions
  • Public talks
  • Group mentoring
  • Community events

An event can contain:

Event
│
├── Title
├── Description
├── Host
├── Category
├── Start Time
├── End Time
├── Capacity
├── Price
├── Registration
└── Status

Events support both:

Free Event

and:

Paid Event

17. Appointment vs Event

Although both involve time, appointments and events should be different domain entities.

Appointment

Professional
      │
      └── One User
             │
             └── Specific Time Slot

Event

Professional
      │
      └── Event
           │
           ├── User A
           ├── User B
           ├── User C
           └── User D

The capacity model is therefore different.

For appointments:

Capacity = 1

For events:

Capacity = N

This distinction prevents the scheduling model from becoming unnecessarily complicated.


18. Event Capacity Management

Suppose an event has:

Capacity = 100

and 99 people have registered.

The next registration should consume the final available capacity atomically.

Conceptually:

remaining_capacity = capacity - confirmed_registrations

But under concurrency, simply calculating this value is not enough.

Two users could simultaneously see:

Remaining = 1

and both register.

Therefore event registration also requires atomic capacity enforcement.

The backend needs to guarantee:

Confirmed Registrations <= Event Capacity

even under concurrent requests.


19. Booking Lifecycle

A unified booking lifecycle can look like:

┌───────────────┐
                │   AVAILABLE   │
                └───────┬───────┘
                        │
                        ▼
                ┌───────────────┐
                │     HELD      │
                └───────┬───────┘
                        │
              ┌─────────┴─────────┐
              │                   │
         Payment Success      Timeout
              │                   │
              ▼                   ▼
       ┌─────────────┐       AVAILABLE
       │  CONFIRMED  │
       └──────┬──────┘
              │
              ▼
       ┌─────────────┐
       │  COMPLETED  │
       └─────────────┘

Additional transitions can support:

CONFIRMED → CANCELLED
CONFIRMED → NO_SHOW
CONFIRMED → COMPLETED

Explicit states make the system easier to reason about and audit.


20. Data Model

A simplified domain model could contain:

User
ProfessionalProfile
Category
Skill
Education
Experience
SocialLink

Schedule
AvailabilityRule
Booking

Event
EventRegistration

Payment
PaymentTransaction

The relationships can be represented conceptually as:

User
 │
 └── ProfessionalProfile
        │
        ├── Schedule
        │      │
        │      ├── AvailabilityRule
        │      └── Booking
        │
        └── Event
               │
               └── EventRegistration

Booking
   │
   └── Payment

21. Time Handling

Since Appoim is designed for users and professionals in India, the platform uses a consistent Indian Standard Time (IST) setup.

Availability and appointments are managed using IST:

Availability:
Monday
10:00 AM - 12:00 PM

Timezone:
IST

The backend stores and processes appointment times consistently in IST, while the frontend displays the same time to users.

Conceptually:

IST-Based Availability
        │
        ▼
Availability Rules
        │
        ▼
Bookable Slots
        │
        ▼
Confirmed Appointment

Using one standard time setup keeps scheduling simple and avoids unnecessary timezone conversion issues for Indian users and professionals.


22. Recurring Availability

Instead of creating availability manually for every date, professionals can define recurring rules.

For example:

Every Monday
10:00 - 13:00

Every Wednesday
14:00 - 18:00

Every Friday
10:00 - 12:00

The scheduling engine evaluates these rules against a requested date.

This makes the system scalable because the application does not need to store millions of pre-generated future slots.

Instead:

Rule
 +
Existing Bookings
 +
Requested Date
        │
        ▼
Available Slots

are calculated when necessary.


23. Exceptions and Overrides

Real-world calendars require exceptions.

For example:

Normal:
Monday 10:00 - 13:00

But a professional may be unavailable on:

September 14

The system therefore needs a concept of:

Availability Rule

and:

Availability Exception

For example:

Recurring Rule
Monday 10:00 - 13:00

Exception
2026-09-14 → CLOSED

Similarly, a professional could create a temporary override:

2026-09-21
15:00 - 18:00

This provides much greater scheduling flexibility.


24. API-Oriented Architecture

The backend can expose APIs around domain boundaries.

For example:

/auth
    /request-otp
    /verify-otp

/professionals
    /profile
    /profile/:id

/schedules
    /create
    /update
    /delete
    /:id

/availability
    /rules
    /slots

/bookings
    /create
    /cancel
    /:id

/payments
    /create
    /verify
    /webhook

/events
    /create
    /update
    /:id

/event-registrations
    /register
    /cancel

This creates clear boundaries between the major modules.


25. Backend Service Boundaries

A modular backend could be structured as:

Application
│
├── Authentication Module
│
├── User Module
│
├── Professional Module
│
├── Search Module
│
├── Scheduling Module
│
├── Booking Module
│
├── Payment Module
│
├── Event Module
│
├── Notification Module
│
└── Admin Module

Initially these modules can exist inside a modular monolith.

There is no requirement to immediately deploy them as independent microservices.

A modular monolith provides:

  • Simpler deployment
  • Easier transactions
  • Lower operational complexity
  • Clear domain boundaries
  • Easier initial development

Individual services can later be extracted if scale requires it.


26. Caching Strategy

Availability queries can be expensive when the system needs to repeatedly calculate:

Professional
+
Schedule
+
Availability Rules
+
Bookings
+
Exceptions

Caching can reduce repeated computation.

For example:

GET /schedules/:id/slots?date=2026-09-10

could use a short-lived cache.

However, booking creation should always validate the authoritative data again.

The important rule is:

Cache availability for reads, but never trust stale availability for final booking confirmation.

27. Notifications

Booking and event systems naturally require notifications.

Possible notification events include:

OTP Generated
Booking Created
Booking Confirmed
Payment Successful
Booking Cancelled
Event Registration
Event Reminder
Session Reminder
Payment Pending

The notification architecture can be event-driven:

Booking Confirmed
       │
       ▼
Application Event
       │
       ├── Email
       ├── SMS
       ├── Push Notification
       └── Other Channels

This avoids tightly coupling booking logic with notification providers.


28. Idempotency

Booking and payment APIs are vulnerable to duplicate requests.

For example:

POST /booking

may be submitted twice because of:

  • Double-click
  • Network retry
  • Mobile connection problems
  • Client retry logic

The backend should support idempotency.

For example:

Idempotency-Key:
abc123

If the same request arrives again:

abc123

the system returns the existing result instead of creating another booking.

This is particularly important for payment and booking operations.


29. Security Considerations

Appoim handles user identity, appointments and potentially financial transactions, so security must be considered at every layer.

Important controls include:

Authentication

OTP verification with:

  • Rate limiting
  • OTP expiration
  • Attempt limits
  • Abuse prevention

Authorization

A professional should only be able to modify their own:

Profile
Schedules
Availability
Events
Bookings

API Security

Use:

  • Authentication middleware
  • Authorization checks
  • Request validation
  • Rate limiting
  • Input sanitization
  • Secure session/token management

Payment Security

Never trust payment status from the client.

Always verify payment through the payment provider's server-side mechanism.


30. The Most Interesting Part: Generic Scheduling

The most technically interesting characteristic of Appoim is its generic scheduling model.

The system does not need separate scheduling implementations for:

Doctor
Lawyer
Engineer
Mentor
Founder
Consultant
Coach
Teacher
Developer

Instead, all professionals use the same scheduling abstraction:

Professional
      │
      ▼
Schedule
      │
      ├── Duration
      ├── Pricing
      ├── Payment Configuration
      ├── Availability Rules
      ├── Exceptions
      └── Booking Rules

This makes the scheduling engine reusable across different professional categories.


31. A Typical End-to-End Booking Flow

Consider a user booking a 30-minute technical consultation.

Step 1 — Discovery

User
 ↓
Search Professionals
 ↓
Select Professional

Step 2 — Profile

Professional Profile
 ↓
View Skills
 ↓
View Experience
 ↓
View Services

Step 3 — Schedule

Technical Consultation
30 Minutes
₹999

Step 4 — Availability

Select Date
 ↓
Generate Available Slots
 ↓
Select 10:30 AM

Step 5 — Reservation

Create Temporary Hold

Step 6 — Payment

Payment Gateway
 ↓
Payment Success

Step 7 — Confirmation

Booking
    ↓
CONFIRMED

Step 8 — Notification

Professional ← Booking Confirmation → User

The same architecture can support free appointments by removing the payment stage.


32. Event Booking Flow

For an event:

User
 ↓
Discover Event
 ↓
View Event Details
 ↓
Register

For a free event:

Register
 ↓
Confirmation

For a paid event:

Register
 ↓
Payment
 ↓
Payment Confirmation
 ↓
Registration Confirmed

The same payment infrastructure can therefore serve:

Paid Appointments
        +
Paid Events

33. Designing for Extensibility

A major architectural objective of Appoim is avoiding a system where every new feature requires rewriting the booking engine.

The core abstractions should remain stable.

For example:

Professional
Schedule
Availability
Booking
Payment
Event
Registration

Future features can then build on top of these abstractions.

Potential extensions include:

Group Sessions
Subscription Packages
Bundles
Recurring Appointments
Team Booking
Multiple Professionals
Coupons
Refunds
Calendar Synchronization
Video Meeting Integration
Waiting Lists
Reviews
Analytics

The architecture becomes more valuable when these capabilities can be added without redesigning the entire platform.


34. Architectural Philosophy

The fundamental architecture of Appoim can be summarized as:

Identity
   │
   ▼
Professional
   │
   ├──────────────┐
   ▼              ▼
Schedule         Event
   │              │
   ▼              ▼
Availability   Registration
   │              │
   └──────┬───────┘
          ▼
       Payment
          │
          ▼
     Notifications

Each domain has a clear responsibility.

The scheduling engine determines when something can happen.

The booking system determines who reserved it.

The payment system determines whether money was successfully collected.

The event system determines how multiple users register for a shared session.

The notification system communicates the resulting state changes.


35. Key Technical Challenges

The major engineering challenges in Appoim are not the profile CRUD operations.

They are:

1. Flexible availability

Supporting arbitrary schedules and recurring availability.

2. Slot generation

Converting availability rules into real-time bookable slots.

3. Double-booking prevention

Handling concurrent booking requests safely.

4. Temporary reservations

Holding slots while payments are being processed.

5. Payment consistency

Synchronizing payment state with booking state.

6. Idempotency

Preventing duplicate bookings and payment operations.

7. Timezones

Correctly handling professionals and users across India.

8. Event capacity

Guaranteeing that concurrent registrations cannot exceed capacity.

9. Extensibility

Supporting different professional types without creating industry-specific implementations.

10. Search

Making thousands or millions of professional profiles efficiently discoverable.


36. Conclusion

Appoim is fundamentally a professional scheduling and transaction platform.

Its architecture revolves around a few important abstractions:

Professional
Schedule
Availability
Booking
Payment
Event
Registration

The complexity comes from making those abstractions flexible enough to support different professional workflows.

A doctor, lawyer, engineer, founder, mentor or consultant can all use the same underlying scheduling infrastructure while configuring completely different services, durations, pricing models and availability.

The most important engineering principle is therefore not simply:

"Build an appointment booking system."

It is:

Build a reusable scheduling and booking engine that can model different professional services without coupling the system to a specific industry.

That approach allows Appoim to evolve from a basic appointment application into a more general platform for professional discovery, one-to-one sessions, paid consultations, free sessions, webinars and events while maintaining a consistent technical foundation.