Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: v2 bookings #16200

Merged
merged 109 commits into from
Sep 23, 2024
Merged

refactor: v2 bookings #16200

merged 109 commits into from
Sep 23, 2024

Conversation

supalarry
Copy link
Contributor

@supalarry supalarry commented Aug 14, 2024

To use this version add cal-api-version: 2024-08-13 request header.

This PR versions existing bookings endpoints under 2024-04-15/controllers/bookings.controller.ts and introduces new endpoints under bookings/2024-08-13/controllers/bookings.controller.ts. There are following endpoints:

  1. Create booking, recurring booking and instant booking
  2. Get booking, recurring booking, or individual recurrence of recurring booking by uid
  3. Get all bookings using filters
  4. Reschedule booking
  5. Cancel booking
  6. Mark host or attendee as absent

2024-08-13/controllers/bookings.controller.e2e-spec.ts tests all of these features and also team event type bookings.

Fixes #16512

1. Create booking, recurring booking and instant booking

POST /v2/bookings is used to create regular bookings, recurring bookings and instant bookings. The request bodies for all 3 are almost the same except:

  1. If eventTypeId in the request body is id of a regular event, then regular booking is created. If it is an id of a recurring event type, then recurring booking is created. Meaning that the request bodies are equal but the outcome depends on what kind of event type it is with the goal of making it as seamless for developers as possible.
  2. For team event types it is possible to create instant meeting. To do that just pass "instant": true to the request body.
  3. the start needs to be in UTC aka if the timezone is GMT+2 in Rome and meeting should start at 11, then UTC time should have hours 09:00 aka without time zone.

Booking

Request body:

{
  "start": "2025-02-21T09:00:00",
  "eventTypeId": 3652,
  "attendee": {
    "timeZone": "Europe/Rome",
    "email": "[email protected]",
    "name": "lauris",
    "language": "lv"
  },
  "meetingUrl": "https://daily.co/abc-xyz"
}

Response:

{
  "status": "success",
  "data": {
    "id": 1189,
    "uid": "r66HAHqdmsfUAKxr6yXfjh",
    "hosts": [
      {
        "id": 2457,
        "name": "John Jones",
        "timeZone": "Europe/Madrid"
      }
    ],
    "status": "accepted",
    "start": "2025-02-21T09:00:00.000Z",
    "end": "2025-02-21T10:00:00.000Z",
    "duration": 60,
    "eventTypeId": 3652,
    "attendees": [
      {
        "name": "lauris",
        "timeZone": "Europe/Rome",
        "language": "lv",
        "absent": false
      }
    ],
    "meetingUrl": "https://daily.co/abc-xyz",
    "absentHost": false
  }
}

Recurring booking

The eventTypeId equals to recurring event type.

Request body:

{
  "start": "2025-02-21T10:00:00",
  "eventTypeId": 3687,
  "attendee": {
    "timeZone": "Europe/Rome",
    "email": "[email protected]",
    "name": "lauris",
    "language": "lv"
  }
}

Response:

{
  "status": "success",
  "data": [
    {
      "id": 1190,
      "uid": "1pvo6RVzqbgr1hhP6AV4qB",
      "hosts": [
        {
          "id": 2465,
          "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
          "timeZone": "Europe/Rome"
        }
      ],
      "status": "accepted",
      "start": "2025-02-21T10:00:00.000Z",
      "end": "2025-02-21T11:00:00.000Z",
      "duration": 60,
      "eventTypeId": 3687,
      "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
      "attendees": [
        {
          "name": "lauris",
          "timeZone": "Europe/Rome",
          "language": "lv",
          "absent": false
        }
      ],
      "meetingUrl": "integrations:daily",
      "absentHost": false
    },
    {
      "id": 1191,
      "uid": "xwiP3mQhdbzNHd1tgyroer",
      "hosts": [
        {
          "id": 2465,
          "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
          "timeZone": "Europe/Rome"
        }
      ],
      "status": "accepted",
      "start": "2025-02-28T10:00:00.000Z",
      "end": "2025-02-28T11:00:00.000Z",
      "duration": 60,
      "eventTypeId": 3687,
      "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
      "attendees": [
        {
          "name": "lauris",
          "timeZone": "Europe/Rome",
          "language": "lv",
          "absent": false
        }
      ],
      "meetingUrl": "integrations:daily",
      "absentHost": false
    },
    {
      "id": 1192,
      "uid": "cRveyJUq8169yFL4kBQee7",
      "hosts": [
        {
          "id": 2465,
          "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
          "timeZone": "Europe/Rome"
        }
      ],
      "status": "accepted",
      "start": "2025-03-07T10:00:00.000Z",
      "end": "2025-03-07T11:00:00.000Z",
      "duration": 60,
      "eventTypeId": 3687,
      "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
      "attendees": [
        {
          "name": "lauris",
          "timeZone": "Europe/Rome",
          "language": "lv",
          "absent": false
        }
      ],
      "meetingUrl": "integrations:daily",
      "absentHost": false
    }
  ]
}

Instant Booking

The "eventTypeId" must be a team event type and simply add "instant" : true to the request body.

Request:

{
  "instant": true,
  "start": "2026-02-21T09:00:00",
  "eventTypeId": 3680,
  "attendee": {
    "timeZone": "Europe/Rome",
    "email": "[email protected]",
    "name": "lauris",
    "language": "lv"
  }
}

2. Get booking, recurring booking, or individual recurrence of recurring booking by uid

Similarly, getting bookings has been simplified. Fetch booking using GET /v2/bookings/:bookingUid . The :bookingUid can be:

  1. uid of a regular booking above e.g. "r66HAHqdmsfUAKxr6yXfjh" above.

  2. uid of one of the recurrences within recurring bookings e.g. "1pvo6RVzqbgr1hhP6AV4qB" above (if its recurring booking with 3 recurrences, then return will be 1 object containing 1 of the 3 occurences)

  3. uid of the recurring booking e.g. "89e7ef26-ec0b-4898-9733-6488264ac438” above stored in the recurringBookingUid key (will return an array of all 3 recurrences)

  4. GET normal booking api/v2/bookings/r66HAHqdmsfUAKxr6yXfjh response:

{
  "status": "success",
  "data": {
    "id": 1189,
    "uid": "r66HAHqdmsfUAKxr6yXfjh",
    "hosts": [
      {
        "id": 2457,
        "name": "John Jones",
        "timeZone": "Europe/Madrid"
      }
    ],
    "status": "accepted",
    "start": "2025-02-21T09:00:00.000Z",
    "end": "2025-02-21T10:00:00.000Z",
    "duration": 60,
    "eventTypeId": 3652,
    "attendees": [
      {
        "name": "lauris",
        "timeZone": "Europe/Rome",
        "language": "lv",
        "absent": false
      }
    ],
    "meetingUrl": "https://daily.co/abc-xyz",
    "absentHost": false
  }
}
  1. GET individual recurrence api/v2/bookings/1pvo6RVzqbgr1hhP6AV4qB response:
    As you see it has recurringBookingUid key.
{
  "status": "success",
  "data": {
    "id": 1190,
    "uid": "1pvo6RVzqbgr1hhP6AV4qB",
    "hosts": [
      {
        "id": 2465,
        "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
        "timeZone": "Europe/Rome"
      }
    ],
    "status": "accepted",
    "start": "2025-02-21T10:00:00.000Z",
    "end": "2025-02-21T11:00:00.000Z",
    "duration": 60,
    "eventTypeId": 3687,
    "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
    "attendees": [
      {
        "name": "lauris",
        "timeZone": "Europe/Rome",
        "language": "lv",
        "absent": false
      }
    ],
    "meetingUrl": "integrations:daily",
    "absentHost": false
  }
}
  1. GET recurring booking api/v2/bookings/89e7ef26-ec0b-4898-9733-6488264ac438 response:
{
  "status": "success",
  "data": [
    {
      "id": 1190,
      "uid": "1pvo6RVzqbgr1hhP6AV4qB",
      "hosts": [
        {
          "id": 2465,
          "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
          "timeZone": "Europe/Rome"
        }
      ],
      "status": "accepted",
      "start": "2025-02-21T10:00:00.000Z",
      "end": "2025-02-21T11:00:00.000Z",
      "duration": 60,
      "eventTypeId": 3687,
      "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
      "attendees": [
        {
          "name": "lauris",
          "timeZone": "Europe/Rome",
          "language": "lv",
          "absent": false
        }
      ],
      "meetingUrl": "integrations:daily",
      "absentHost": false
    },
    {
      "id": 1191,
      "uid": "xwiP3mQhdbzNHd1tgyroer",
      "hosts": [
        {
          "id": 2465,
          "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
          "timeZone": "Europe/Rome"
        }
      ],
      "status": "accepted",
      "start": "2025-02-28T10:00:00.000Z",
      "end": "2025-02-28T11:00:00.000Z",
      "duration": 60,
      "eventTypeId": 3687,
      "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
      "attendees": [
        {
          "name": "lauris",
          "timeZone": "Europe/Rome",
          "language": "lv",
          "absent": false
        }
      ],
      "meetingUrl": "integrations:daily",
      "absentHost": false
    },
    {
      "id": 1192,
      "uid": "cRveyJUq8169yFL4kBQee7",
      "hosts": [
        {
          "id": 2465,
          "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
          "timeZone": "Europe/Rome"
        }
      ],
      "status": "accepted",
      "start": "2025-03-07T10:00:00.000Z",
      "end": "2025-03-07T11:00:00.000Z",
      "duration": 60,
      "eventTypeId": 3687,
      "recurringBookingUid": "89e7ef26-ec0b-4898-9733-6488264ac438",
      "attendees": [
        {
          "name": "lauris",
          "timeZone": "Europe/Rome",
          "language": "lv",
          "absent": false
        }
      ],
      "meetingUrl": "integrations:daily",
      "absentHost": false
    }
  ]
}

3. Get all bookings using filters

Now let’s see how can we fetch multiple bookings and filters we can use. If you send GET /v2/bookings then you will see all bookings created (1 normal booking + 3 recurrences of a recurring booking). Notably, by default it returns upcoming bookings sorted by soonest meeting on the top.

You can use filters, sorting and pagination query parameters to fetch results as you want.

filters:

  1. status - upcoming, recurring, past, cancelled, unconfirmed e.g.?status=upcoming. Notably, you can pass multiple statuses ?status=past,cancelled which will return past and cancelled meetings.
  2. attendeeEmail - who booked the meeting e.g.[email protected]
  3. attendeeName - who booked the meeting e.g. ?attendeeName=lauris
  4. eventTypeIds - comma separated string containing event type ids for which you want to fetch bookings e.g.
    ?eventTypeIds=3686,3687
  5. eventTypeId - event type for which you want to fetch bookings e.g. ?eventTypeId=3686
  6. teamIds - comma separated string to get bookings of teams where user associated with the auth access token is part of e.g. ?teamIds=686,687
  7. teamId - bookings of a team where user associated with the auth access token is part of e.g. ?teamId=686
  8. afterStart - all bookings with start after this date string e.g. ?afterStart=2025-03-07T10:00:00.000Z
  9. beforeEnd - all bookings with end before this date string e.g. ?beforeEnd=2025-03-07T11:00:00.000Z

sort:

  1. sortStart - sort results by their start time in ascending e.g. ?sortStart=asc or descending ?sortStart=desc order.
  2. sortEnd - sort results by their end time in ascending e.g. ?sortEnd=asc or descending ?sortEnd=desc order.
  3. sortCreated - sort results by their time when the booking was done in ascending ?sortCreated=asc or descending ?sortCreated=desc order.

pagination:

  1. skip - how many results to skip.
  2. take - how many results to return. min value is 1 and max is 250. By default its 100.

4. Reschedule booking

It is possible to reschedule a regular booking or one of the recurrences of a recurring booking by sending a POST request to api/v2/bookings/:bookingUid/reschedule. After rescheduling the new booking will contain reference rescheduledFromUid and rescheduledReason provided in request body.

1. Reschedule normal booking

Request: api/v2/bookings/qM56A2BTnwCKuhitWc1pH5/reschedule
Body: provide new start time in UTC and optionally rescheduling reason:

{
   "start": "2030-01-21T10:00:00",
    "reschedulingReason": "wont have internet"
}

Response:

{
  "status": "success",
  "data": {
    "id": 1194,
    "uid": "qKcFyCSn9qfuj1Ba435EXE",
    "hosts": [
      {
        "id": 2465,
        "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
        "timeZone": "Europe/Rome"
      }
    ],
    "status": "accepted",
    "reschedulingReason": "wont have internet",
    "rescheduledFromUid": "qM56A2BTnwCKuhitWc1pH5",
    "start": "2030-01-21T10:00:00.000Z",
    "end": "2030-01-21T11:00:00.000Z",
    "duration": 60,
    "eventTypeId": 3686,
    "attendees": [
      {
        "name": "lauris",
        "timeZone": "Europe/Rome",
        "language": "lv",
        "absent": false
      }
    ],
    "meetingUrl": "https://daily.co/abc-xyz",
    "absentHost": false
  }
}

2. Reschedule recurrence of a recurring event

Request URL: api/v2/bookings/1pvo6RVzqbgr1hhP6AV4qB/reschedule
Body:

{
   "start": "2030-01-21T12:00:00",
    "reschedulingReason": "laptop broke"
}

Response:

{
  "status": "success",
  "data": {
    "id": 1212,
    "uid": "fsxHwC9xhrcpV77cx2uzhn",
    "hosts": [
      {
        "id": 2465,
        "name": "twenty-clywuonwt0001regwyzy6subr-onecorp",
        "timeZone": "Europe/Rome"
      }
    ],
    "status": "accepted",
    "reschedulingReason": "laptop broke",
    "rescheduledFromUid": "1pvo6RVzqbgr1hhP6AV4qB",
    "start": "2030-01-23T13:00:00.000Z",
    "end": "2030-01-23T14:00:00.000Z",
    "duration": 60,
    "eventTypeId": 3687,
    "recurringBookingUid": "ce796451-9ca0-453e-bf1c-976f4245b08d",
    "attendees": [
      {
        "name": "lauris",
        "timeZone": "Europe/Rome",
        "language": "lv",
        "absent": false
      }
    ],
    "meetingUrl": "integrations:daily",
    "absentHost": false
  }
}

If we now fetch the recurring booking that has 3 occurences by recurringBookingUid ce796451-9ca0-453e-bf1c-976f4245b08d then we will have array of 4 entries - 1 was changed to status = cancelled aka the one that was rescheduled and there is now a new 4th entry as a reason of the reschedule.

5. Cancel booking

Make request to v2/bookings/:bookingUid/cancel. If :bookingUid is equal to recurringBookingUid of a recurrence of a recurring booking, then all remaining recurrences will be cancelled.

6. Mark host or attendee as absent

Request URL: api/v2/bookings/:bookingUid/mark-absent

Body to mark host absent:

{
   "host": true
}

Body to mark one of the attendees absent:

{
   "attendees": [{email: "[email protected]", absent: true}]
}

Tests

npx jest apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.e2e-spec.ts --config jest-e2e.json --detectOpenHandles
npx jest src/ee/bookings/2024-08-13/controllers/bookings.controller.e2e-spec.ts --config jest-e2e.json

Copy link

vercel bot commented Aug 14, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Visit Preview Sep 23, 2024 11:39am
calcom-web-canary ⬜️ Ignored (Inspect) Visit Preview Sep 23, 2024 11:39am

Copy link

socket-security bot commented Aug 15, 2024

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report↗︎

Copy link

socket-security bot commented Sep 21, 2024

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@esbuild/[email protected] None 0 10.5 MB evanw
npm/@esbuild/[email protected] None 0 11.7 MB evanw
npm/@esbuild/[email protected] None 0 9.96 MB evanw
npm/@esbuild/[email protected] None 0 11.7 MB evanw
npm/@esbuild/[email protected] None 0 9.86 MB evanw
npm/@esbuild/[email protected] None 0 10.3 MB evanw
npm/@esbuild/[email protected] None 0 8.98 MB evanw
npm/@esbuild/[email protected] None 0 9.71 MB evanw
npm/@esbuild/[email protected] None 0 9.31 MB evanw
npm/@esbuild/[email protected] None 0 8.98 MB evanw
npm/@esbuild/[email protected] None 0 9.25 MB evanw
npm/@esbuild/[email protected] None 0 9.5 MB evanw
npm/@esbuild/[email protected] None 0 10.6 MB evanw
npm/@esbuild/[email protected] None 0 9.24 MB evanw
npm/@esbuild/[email protected] None 0 9.24 MB evanw
npm/@esbuild/[email protected] None 0 10.2 MB evanw
npm/@esbuild/[email protected] None 0 9.71 MB evanw
npm/@esbuild/[email protected] None 0 9.69 MB evanw
npm/@esbuild/[email protected] None 0 9.73 MB evanw
npm/@esbuild/[email protected] None 0 9.69 MB evanw
npm/@esbuild/[email protected] None 0 9.08 MB evanw
npm/@esbuild/[email protected] None 0 9.56 MB evanw
npm/@esbuild/[email protected] None 0 9.91 MB evanw
npm/@humanwhocodes/[email protected] unsafe 0 21.2 kB nzakas
npm/@nodelib/[email protected] filesystem 0 22.2 kB mrmlnc
npm/@nodelib/[email protected] filesystem 0 11.8 kB mrmlnc
npm/@nodelib/[email protected] None 0 26.4 kB mrmlnc
npm/@types/[email protected] None 0 25.7 kB types
npm/@types/[email protected] None 0 2.88 kB types
npm/@vitest/[email protected] None 0 149 kB vitestbot
npm/@vitest/[email protected] None 0 121 kB vitestbot
npm/@vitest/[email protected] environment 0 45.3 kB vitestbot
npm/@vitest/[email protected] None 0 87.9 kB vitestbot
npm/@vitest/[email protected] None 0 0 B
npm/@vitest/[email protected] None 0 19.1 kB vitestbot
npm/@vitest/[email protected] None 0 153 kB antfu, oreanno, patak, ...1 more
npm/[email protected] None 0 24.4 kB rreverser
npm/[email protected] eval 0 929 kB esp
npm/[email protected] None 0 17 kB sindresorhus
npm/[email protected] None 0 3.17 kB sindresorhus
npm/[email protected] None 0 5.83 kB chaijs
npm/[email protected] None 0 6.94 kB juliangruber
npm/[email protected] None 0 81.8 kB egoist
npm/[email protected] None 0 6.33 kB sindresorhus
npm/[email protected] None 0 506 kB chaijs
npm/[email protected] None 0 11.4 kB chaijs
npm/[email protected] filesystem 0 5.75 kB isaacs
npm/[email protected] None 0 27.2 kB qix
npm/[email protected] None 0 4.86 kB substack
npm/[email protected] environment, filesystem, shell 0 21.2 kB satazor
npm/[email protected] environment 0 42.4 kB qix
npm/[email protected] None 0 23.9 kB chaijs
npm/[email protected] None 0 8.11 kB thlorenz
npm/[email protected] None 0 5.42 kB sindresorhus
npm/[email protected] None 0 106 kB eslint
npm/[email protected] None 0 7.12 kB andris
npm/[email protected] None 0 10.2 kB sindresorhus
npm/[email protected] None 0 12.3 kB achingbrain
npm/[email protected] environment, filesystem, network, shell 0 133 kB evanw
npm/[email protected] filesystem 0 11.4 kB lukeed
npm/[email protected] None 0 13.5 kB michaelficarra
npm/[email protected] None 0 37.1 kB michaelficarra
npm/[email protected] None 0 17.6 kB rich_harris
npm/[email protected] None 0 50.6 kB michaelficarra
npm/[email protected] environment, shell 0 57.5 kB sindresorhus
npm/[email protected] None 0 13 kB esp
npm/[email protected] None 0 17 kB esp
npm/[email protected] None 0 9.44 kB hiddentao
npm/[email protected] filesystem 0 25.6 kB royriojas
npm/[email protected] None 0 11.8 kB sindresorhus
npm/[email protected] filesystem 0 30 kB royriojas
npm/[email protected] None 0 4.72 kB stefanpenner
npm/[email protected] None 0 8.68 kB keithamus
npm/[email protected] None 0 12.2 kB sindresorhus
npm/[email protected] filesystem 0 21.8 kB sindresorhus
npm/[email protected] None 0 35.9 kB kornel
npm/[email protected] None 0 44.3 kB ehmicky
npm/[email protected] None 0 4.87 kB sindresorhus
npm/[email protected] None 0 11.9 kB jensyt
npm/[email protected] None 0 4.4 kB sindresorhus
npm/[email protected] None 0 6.22 kB jonschlinkert
npm/[email protected] None 0 4.99 kB sindresorhus
npm/[email protected] None 0 13.6 kB phated
npm/[email protected] None 0 2.94 kB watson
npm/[email protected] None 0 9.62 kB jonschlinkert
npm/[email protected] None 0 4.12 kB sindresorhus
npm/[email protected] None 0 405 kB vitaly
npm/[email protected] None 0 14.2 kB samn
npm/[email protected] None 0 24.9 kB gkz
npm/[email protected] filesystem 0 7.02 kB sindresorhus
npm/[email protected] None 0 54.1 kB jdalton
npm/[email protected] None 0 60.5 kB chaijs
npm/[email protected] None 0 464 kB antfu
npm/[email protected] None 0 4.31 kB stevemao
npm/[email protected] None 0 8.9 kB zensh
npm/[email protected] None 0 4.46 kB sindresorhus
npm/[email protected] None 0 3.77 kB isaacs
npm/[email protected] None 0 7 kB isaacs
npm/[email protected] None 0 124 kB isaacs
npm/[email protected] None 0 17.3 kB isaacs
npm/[email protected] environment, filesystem 0 19.1 kB isaacs
npm/[email protected] None 0 6.84 kB styfle
npm/[email protected] None 0 24.4 kB ai
npm/[email protected] None 0 5.65 kB megawac
npm/[email protected] None 0 27.4 kB dougwilson
npm/[email protected] environment 0 8.13 kB sindresorhus
npm/[email protected] None 0 6.17 kB sindresorhus
npm/[email protected] None 0 7.75 kB sindresorhus
npm/[email protected] None 0 7.24 kB sindresorhus
npm/[email protected] None 0 3.92 kB sindresorhus
npm/[email protected] None 0 4.51 kB jbgutierrez
npm/[email protected] filesystem 0 5.41 kB sindresorhus
npm/[email protected] None 0 30.8 kB pi0
npm/[email protected] None 0 15 kB chaijs
npm/[email protected] environment 0 11.4 kB alexeyraspopov
npm/[email protected] None 0 90 kB mrmlnc
npm/[email protected] None 0 36.7 kB gkz
npm/[email protected] None 0 3.04 kB iarna
npm/[email protected] None 0 15.6 kB achingbrain
npm/[email protected] None 0 32.4 kB mathias
npm/[email protected] filesystem 0 12.1 kB troygoode
npm/[email protected] filesystem, unsafe 0 4.64 kB sindresorhus
npm/[email protected] None 0 32.2 kB tim-kos
npm/[email protected] None 0 9.44 kB matteo.collina
npm/[email protected] filesystem 0 17.3 kB isaacs
npm/[email protected] None 0 42.3 kB chalker
npm/[email protected] None 0 2.83 kB sindresorhus
npm/[email protected] None 0 4.79 kB emilbayes
npm/[email protected] None 0 3.51 kB sindresorhus
npm/[email protected] None 0 138 kB joshglazebrook
npm/[email protected] None 0 140 kB 7rulnik
npm/[email protected] None 0 11.8 kB kemitchell
npm/[email protected] None 0 6.88 kB shtylman
npm/[email protected] None 0 26.2 kB pi0
npm/[email protected] None 0 5.16 kB sindresorhus
npm/[email protected] None 0 3.05 kB sindresorhus
npm/[email protected] None 0 6.96 kB sindresorhus
npm/[email protected] None 0 9.18 kB ljharb
npm/[email protected] None 0 11 kB substack
npm/[email protected] None 0 62.9 kB aslemammad
npm/[email protected] environment, shell 0 45.4 kB 43081j
npm/[email protected] filesystem, shell, unsafe 0 49.9 kB ariperkkio
npm/[email protected] None 0 7.91 kB oreanno
npm/[email protected] None 0 17.6 kB antfu, aslemammad, oreanno
npm/[email protected] None 0 22.9 kB jonschlinkert
npm/[email protected] None 0 84 kB typescript-bot
npm/[email protected] None 0 21.2 kB gkz
npm/[email protected] None 0 470 kB garycourt
npm/[email protected] None 0 16.6 kB kemitchell
npm/[email protected] None 0 202 kB antfu, oreanno, patak, ...1 more
npm/[email protected] filesystem, unsafe 0 7.3 kB mafintosh

🚮 Removed packages: npm/@formkit/[email protected]

View full report↗︎

@ThyMinimalDev ThyMinimalDev merged commit 0eabe7f into main Sep 23, 2024
38 checks passed
@ThyMinimalDev ThyMinimalDev deleted the v2-refactor-bookings branch September 23, 2024 13:19
@Udit-takkar Udit-takkar mentioned this pull request Dec 20, 2024
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api area: API, enterprise API, access token, OAuth bookings area: bookings, availability, timezones, double booking core area: core, team members only ✨ feature New feature or request Medium priority Created by Linear-GitHub Sync platform Anything related to our platform plan ready-for-e2e
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bookings approved via the api do not land on destination calendars
4 participants