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

feat: global booking limits for teams #18

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e7415fe
feat: update vitest version v0.34 to V2.11 (#16676)
sean-brydon Sep 17, 2024
a53e697
chore: v4.5.1 (#16690)
keithwillcode Sep 17, 2024
5067f0d
fix: dates in ooo booking redirect email (#16692)
CarinaWolli Sep 17, 2024
5ad7360
feat: update translations (#16693)
calcom-bot Sep 17, 2024
3a5325f
fix: new user detection for dub analytics (#16695)
zomars Sep 18, 2024
2b43d9a
chore: EventTypeWebWrapper base pr (#16550)
ThyMinimalDev Sep 18, 2024
5b5a42e
refactor: v2 and atoms booking fields (#16685)
supalarry Sep 18, 2024
021e5f3
fix: fixed more flaky e2e tests (round 2) (#16660)
anikdhabal Sep 18, 2024
1058c0e
fix(eslint): Adds eslint-ignore-patterns to eslint config (#16701)
sean-brydon Sep 18, 2024
a9ebb0d
feat: Retell AI (#16706)
PeerRich Sep 18, 2024
abb4fd3
refactor: event setup tab web wrapper (#16672)
SomayChauhan Sep 18, 2024
a2b064b
feat: per user and team feature flags (#16040)
zomars Sep 18, 2024
019ef6d
chore: App router migration - (`/bookings`, `/booking`) Move `getServ…
hbjORbj Sep 18, 2024
c016241
chore: removes unnecessary prisma env warnings (#16708)
zomars Sep 19, 2024
44410c8
docs: v2 schedules and event-types swagger (#16608)
supalarry Sep 19, 2024
63339d8
fix: connect apple calendar atom nested <button>'s (#16715)
supalarry Sep 19, 2024
3ae53a4
chore: App router - Fix errors in settings pages & add remaining page…
hbjORbj Sep 19, 2024
6d133c2
Narrow argument type to the specific event being listened to (#16714)
hariombalhara Sep 19, 2024
d828470
fix: type error on booking cancelled page (#16716)
Udit-takkar Sep 19, 2024
bc203d7
Release latest embed (#16713)
hariombalhara Sep 19, 2024
a60aa1b
add create license key to admin tab if IS_CALCOM (#16721)
sean-brydon Sep 19, 2024
f8dc7a1
chore: App Router - remove references to `/pages` for remaining pages…
hbjORbj Sep 19, 2024
e0922c5
feat: update translations (#16726)
calcom-bot Sep 19, 2024
c4a1382
chore: add granular logging to the logger (#16734)
alishaz-polymath Sep 20, 2024
11f0d48
feat: onBeforeUpdate AvailabilitySettings prop (#16737)
supalarry Sep 20, 2024
8cb5a70
feat: Add EXPAND accepting "team" in API V1 Bookings (#16736)
alishaz-polymath Sep 20, 2024
b84cdc0
fix: bookings ilmits errror (#16739)
CarinaWolli Sep 20, 2024
97f213f
revert: be7d45afe232b52445a81a0ee70319e9243552b2 (#16742)
emrysal Sep 20, 2024
74bed31
chore: improve api-v2 rate limiting (#16746)
ThyMinimalDev Sep 20, 2024
62d579d
Default to connected Salesforce account as owner (#16747)
joeauyeung Sep 20, 2024
4a914c2
chore: Release v4.5.3 (#16728)
emrysal Sep 20, 2024
c1c4b12
chore: Use no isolation for unit tests (#16745)
keithwillcode Sep 20, 2024
f52497f
fix: flaky e2e patterns (#16696)
zomars Sep 20, 2024
9749ba1
refactor: make managed user's name required (#16678)
supalarry Sep 20, 2024
8e76d7b
chore: fix formatting (#16750)
zomars Sep 21, 2024
76a2773
fix: more general translation for 'seats 'in NL (#16722)
SDeVuyst Sep 21, 2024
1a60afa
chore: booking verification token and booking rejection logic from em…
anikdhabal Sep 21, 2024
6dd8812
fix: Flakyness on pages that use a hard refresh (#16752)
zomars Sep 21, 2024
16ca4dd
fix: update zoom integration doc to include user settings scope (#16724)
vijayraghav-io Sep 21, 2024
2fb1408
Update util.ts (#16753)
alishaz-polymath Sep 21, 2024
bc34e67
refactor: event limits web wrapper (#16679)
SomayChauhan Sep 23, 2024
f642a6e
fix: Issue with zoom meetings getting "invalid Meeting ID" (#16669)
askadityapandey Sep 23, 2024
3371602
feat: billing tab for platform (#16755)
Ryukemeister Sep 23, 2024
0eabe7f
refactor: v2 bookings (#16200)
supalarry Sep 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,14 @@ APP_ROUTER_APPS_SLUG_SETUP_ENABLED=0
APP_ROUTER_APPS_CATEGORIES_ENABLED=0
# whether we redirect to the future/apps/categories/[category] from /apps/categories/[category] or not
APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED=0
APP_ROUTER_BOOKING_ENABLED=0
APP_ROUTER_BOOKINGS_STATUS_ENABLED=0
APP_ROUTER_WORKFLOWS_ENABLED=0
APP_ROUTER_SETTINGS_TEAMS_ENABLED=0
APP_ROUTER_GETTING_STARTED_STEP_ENABLED=0
APP_ROUTER_APPS_ENABLED=0
APP_ROUTER_VIDEO_ENABLED=0
APP_ROUTER_TEAM_ENABLED=0
APP_ROUTER_TEAMS_ENABLED=0
APP_ROUTER_AVAILABILITY_ENABLED=0
APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED=0
Expand Down Expand Up @@ -392,3 +394,7 @@ VAPID_PRIVATE_KEY=
# Custom privacy policy / terms URLs (for self-hosters: change to your privacy policy / terms URLs)
NEXT_PUBLIC_WEBSITE_PRIVACY_POLICY_URL=
NEXT_PUBLIC_WEBSITE_TERMS_URL=

# NEXT_PUBLIC_LOGGER_LEVEL=3 sets to log info, warn, error and fatal logs.
# [0: silly & upwards, 1: trace & upwards, 2: debug & upwards, 3: info & upwards, 4: warn & upwards, 5: error & fatal, 6: fatal]
NEXT_PUBLIC_LOGGER_LEVEL=
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ assignees: ""
(Share it here.)

---

##### House rules

- If this issue has a `🚨 needs approval` label, don't start coding yet. Wait until a core member approves feature request by removing this label, then you can start coding.
- For clarity: Non-core member issues automatically get the `🚨 needs approval` label.
- Your feature ideas are invaluable to us! However, they undergo review to ensure alignment with the product's direction.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-api-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env:
IS_E2E: true
NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }}
NEXTAUTH_URL: ${{ secrets.CI_NEXTAUTH_URL }}
NODE_OPTIONS: --max-old-space-size=4096
NODE_OPTIONS: --max-old-space-size=29000
REDIS_URL: "redis://localhost:6379"
STRIPE_PRIVATE_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }}
STRIPE_API_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ jobs:
test:
name: Unit
timeout-minutes: 20
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: buildjet-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- run: yarn test
- run: yarn test -- --no-isolate
# We could add different timezones here that we need to run our tests in
- run: TZ=America/Los_Angeles yarn test -- --timeZoneDependentTestsOnly
- run: TZ=America/Los_Angeles yarn test -- --timeZoneDependentTestsOnly --no-isolate
- name: Run API v2 tests
working-directory: apps/api/v2
run: |
Expand Down
26 changes: 26 additions & 0 deletions .yarn/patches/@prisma-client-npm-5.4.2-fca489b2dc.patch

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,24 +177,25 @@ Do not commit your `yarn.lock` unless you've made changes to the `package.json`.

If your last commit has the `yarn.lock` file alongside other files and you only wish to uncommit the `yarn.lock`:

```bash
git checkout HEAD~1 yarn.lock
git commit -m "Revert yarn.lock changes"
```
```bash
git checkout HEAD~1 yarn.lock
git commit -m "Revert yarn.lock changes"
```

_NB_: You may have to bypass the pre-commit hook with by appending `--no-verify` to the git commit
If you've pushed the commit with the `yarn.lock`:

1. Correct the commit locally using the above method.
2. Carefully force push:
1. Correct the commit locally using the above method.
2. Carefully force push:

```bash
git push origin <your-branch-name> --force
```
```bash
git push origin <your-branch-name> --force
```

If `yarn.lock` was committed a while ago and there have been several commits since, you can use the following steps to revert just the `yarn.lock` changes without impacting the subsequent changes:

1. **Checkout a Previous Version**:

- Find the commit hash before the `yarn.lock` was unintentionally committed. You can do this by viewing the Git log:

```bash
Expand All @@ -208,13 +209,15 @@ If `yarn.lock` was committed a while ago and there have been several commits sin
```

2. **Commit the Reverted Version**:

- After checking out the previous version of the `yarn.lock`, commit this change:

```bash
git commit -m "Revert yarn.lock to its state before unintended changes"
```

3. **Proceed with Caution**:

- If you need to push this change, first pull the latest changes from your remote branch to ensure you're not overwriting other recent changes:

```bash
Expand Down
81 changes: 50 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,30 @@ yarn dx

#### Development tip

> Add `NEXT_PUBLIC_DEBUG=1` anywhere in your `.env` to get logging information for all the queries and mutations driven by **tRPC**.
Add `NEXT_PUBLIC_LOGGER_LEVEL={level}` to your .env file to control the logging verbosity for all tRPC queries and mutations.\
Where {level} can be one of the following:

`0` for silly \
`1` for trace \
`2` for debug \
`3` for info \
`4` for warn \
`5` for error \
`6` for fatal

When you set `NEXT_PUBLIC_LOGGER_LEVEL={level}` in your .env file, it enables logging at that level and higher. Here's how it works:

The logger will include all logs that are at the specified level or higher. For example: \

- If you set `NEXT_PUBLIC_LOGGER_LEVEL=2`, it will log from level 2 (debug) upwards, meaning levels 2 (debug), 3 (info), 4 (warn), 5 (error), and (fatal) will be logged. \
- If you set `NEXT_PUBLIC_LOGGER_LEVEL=3`, it will log from level 3 (info) upwards, meaning levels 3 (info), 4 (warn), 5 (error), and 6 (fatal) will be logged, but level 2 (debug) and level 1 (trace) will be ignored. \

```sh
echo 'NEXT_PUBLIC_DEBUG=1' >> .env
echo 'NEXT_PUBLIC_LOGGER_LEVEL=3' >> .env
```

for Logger level to be set at info, for example.

#### Gitpod Setup

1. Click the button below to open this project in Gitpod.
Expand Down Expand Up @@ -399,25 +417,25 @@ Cal.com, Inc. is a commercial open source company, which means some parts of thi
> [!NOTE]
> Our philosophy is simple, all "Singleplayer APIs" are open-source under AGPLv3. All commercial "Multiplayer APIs" are under a commercial license.

| | AGPLv3 | EE |
|---|---|---|
| Self-host for commercial purposes | ✅ | ✅ |
| Clone privately | ✅ | ✅ |
| Fork publicly | ✅ | ✅ |
| Requires CLA | ✅ | ✅ |
| Official Support| ❌ | ✅ |
| Derivative work privately | ❌ | ✅ |
| SSO | ❌ | ✅ |
| Admin Panel | ❌ | ✅ |
| Impersonation | ❌ | ✅ |
| Managed Event Types | ❌ | ✅ |
| Organizations | ❌ | ✅ |
| Payments | ❌ | ✅ |
| Platform | ❌ | ✅ |
| Teams | ❌ | ✅ |
| Users | ❌ | ✅ |
| Video | ❌ | ✅ |
| Workflows | ❌ | ✅ |
| | AGPLv3 | EE |
| --------------------------------- | ------ | --- |
| Self-host for commercial purposes | ✅ | ✅ |
| Clone privately | ✅ | ✅ |
| Fork publicly | ✅ | ✅ |
| Requires CLA | ✅ | ✅ |
|  Official Support | ❌  | ✅ |
| Derivative work privately | ❌ | ✅ |
|  SSO | ❌ | ✅ |
| Admin Panel | ❌ | ✅ |
| Impersonation | ❌ | ✅ |
| Managed Event Types | ❌ | ✅ |
| Organizations | ❌ | ✅ |
| Payments | ❌ | ✅ |
| Platform | ❌ | ✅ |
| Teams | ❌ | ✅ |
| Users | ❌ | ✅ |
| Video | ❌ | ✅ |
| Workflows | ❌ | ✅ |

> [!TIP]
> We work closely with the community and always invite feedback about what should be open and what is fine to be commercial. This list is not set and stone and we have moved things from commercial to open in the past. Please open a [discussion](https://github.com/calcom/cal.com/discussions) if you feel like something is wrong.
Expand Down Expand Up @@ -513,17 +531,18 @@ following

1. Open [Zoom Marketplace](https://marketplace.zoom.us/) and sign in with your Zoom account.
2. On the upper right, click "Develop" => "Build App".
3. On "OAuth", select "Create".
3. Select "General App" , click "Create".
4. Name your App.
5. Choose "User-managed app" as the app type.
6. De-select the option to publish the app on the Zoom App Marketplace.
7. Click "Create".
8. Now copy the Client ID and Client Secret to your `.env` file into the `ZOOM_CLIENT_ID` and `ZOOM_CLIENT_SECRET` fields.
9. Set the Redirect URL for OAuth `<Cal.com URL>/api/integrations/zoomvideo/callback` replacing Cal.com URL with the URI at which your application runs.
10. Also add the redirect URL given above as an allow list URL and enable "Subdomain check". Make sure, it says "saved" below the form.
11. You don't need to provide basic information about your app. Instead click on "Scopes" and then on "+ Add Scopes". On the left, click the category "Meeting" and check the scope `meeting:write`.
12. Click "Done".
13. You're good to go. Now you can easily add your Zoom integration in the Cal.com settings.
5. Choose "User-managed app" for "Select how the app is managed".
6. De-select the option to publish the app on the Zoom App Marketplace, if asked.
7. Now copy the Client ID and Client Secret to your `.env` file into the `ZOOM_CLIENT_ID` and `ZOOM_CLIENT_SECRET` fields.
8. Set the "OAuth Redirect URL" under "OAuth Information" as `<Cal.com URL>/api/integrations/zoomvideo/callback` replacing Cal.com URL with the URI at which your application runs.
9. Also add the redirect URL given above as an allow list URL and enable "Subdomain check". Make sure, it says "saved" below the form.
10. You don't need to provide basic information about your app. Instead click on "Scopes" and then on "+ Add Scopes". On the left,
1. click the category "Meeting" and check the scope `meeting:write:meeting`.
2. click the category "User" and check the scope `user:read:settings`.
11. Click "Done".
12. You're good to go. Now you can easily add your Zoom integration in the Cal.com settings.

### Obtaining Daily API Credentials

Expand Down
26 changes: 25 additions & 1 deletion apps/api/v1/lib/validations/booking.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { z } from "zod";

import { _AttendeeModel, _BookingModel as Booking, _PaymentModel, _UserModel } from "@calcom/prisma/zod";
import {
_AttendeeModel,
_BookingModel as Booking,
_EventTypeModel,
_PaymentModel,
_TeamModel,
_UserModel,
} from "@calcom/prisma/zod";
import { extendedBookingCreateBody, iso8601 } from "@calcom/prisma/zod-utils";

import { schemaQueryUserId } from "./shared/queryUserId";
Expand Down Expand Up @@ -46,7 +53,23 @@ export const schemaBookingEditBodyParams = schemaBookingBaseBodyParams
.merge(schemaBookingEditParams)
.omit({ uid: true });

const teamSchema = _TeamModel.pick({
name: true,
slug: true,
});

export const schemaBookingReadPublic = Booking.extend({
eventType: _EventTypeModel
.pick({
title: true,
slug: true,
})
.merge(
z.object({
team: teamSchema.nullish(),
})
)
.nullish(),
attendees: z
.array(
_AttendeeModel.pick({
Expand Down Expand Up @@ -87,6 +110,7 @@ export const schemaBookingReadPublic = Booking.extend({
timeZone: true,
attendees: true,
user: true,
eventType: true,
payment: true,
metadata: true,
status: true,
Expand Down
12 changes: 12 additions & 0 deletions apps/api/v1/lib/validations/shared/queryExpandRelations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { z } from "zod";

const expandEnum = z.enum(["team"]);

export const schemaQuerySingleOrMultipleExpand = z
.union([
expandEnum, // Allow a single value from the enum
z.array(expandEnum).refine((arr) => new Set(arr).size === arr.length, {
message: "Array values must be unique",
}), // Allow an array of enum values, with uniqueness constraint
])
.optional();
15 changes: 14 additions & 1 deletion apps/api/v1/pages/api/bookings/[id]/_get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { defaultResponder } from "@calcom/lib/server";
import prisma from "@calcom/prisma";

import { schemaBookingReadPublic } from "~/lib/validations/booking";
import { schemaQuerySingleOrMultipleExpand } from "~/lib/validations/shared/queryExpandRelations";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";

/**
Expand Down Expand Up @@ -89,9 +90,21 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
export async function getHandler(req: NextApiRequest) {
const { query } = req;
const { id } = schemaQueryIdParseInt.parse(query);

const queryFilterForExpand = schemaQuerySingleOrMultipleExpand.parse(req.query.expand);
const expand = Array.isArray(queryFilterForExpand)
? queryFilterForExpand
: queryFilterForExpand
? [queryFilterForExpand]
: [];
const booking = await prisma.booking.findUnique({
where: { id },
include: { attendees: true, user: true, payment: true },
include: {
attendees: true,
user: true,
payment: true,
eventType: expand.includes("team") ? { include: { team: true } } : false,
},
});
return { booking: schemaBookingReadPublic.parse(booking) };
}
Expand Down
9 changes: 9 additions & 0 deletions apps/api/v1/pages/api/bookings/_get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from "~/lib/utils/retrieveScopedAccessibleUsers";
import { schemaBookingGetParams, schemaBookingReadPublic } from "~/lib/validations/booking";
import { schemaQuerySingleOrMultipleAttendeeEmails } from "~/lib/validations/shared/queryAttendeeEmail";
import { schemaQuerySingleOrMultipleExpand } from "~/lib/validations/shared/queryExpandRelations";
import { schemaQuerySingleOrMultipleUserIds } from "~/lib/validations/shared/queryUserId";

/**
Expand Down Expand Up @@ -216,10 +217,18 @@ export async function handler(req: NextApiRequest) {
args.take = take;
args.skip = skip;
}
const queryFilterForExpand = schemaQuerySingleOrMultipleExpand.parse(req.query.expand);
const expand = Array.isArray(queryFilterForExpand)
? queryFilterForExpand
: queryFilterForExpand
? [queryFilterForExpand]
: [];

args.include = {
attendees: true,
user: true,
payment: true,
eventType: expand.includes("team") ? { include: { team: true } } : false,
};

const queryFilterForAttendeeEmails = schemaQuerySingleOrMultipleAttendeeEmails.parse(req.query);
Expand Down
24 changes: 23 additions & 1 deletion apps/api/v1/test/lib/bookings/_get.integration-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ describe("GET /api/bookings", async () => {

const responseData = await handler(req);
responseData.bookings.forEach((booking) => {
console.log(booking);
expect(new Date(booking.startTime).getTime()).toBeGreaterThanOrEqual(new Date().getTime());
});
});
Expand All @@ -188,4 +187,27 @@ describe("GET /api/bookings", async () => {
});
});
});

describe("Expand feature to add relational data in return payload", () => {
it("Returns only team data when expand=team is set", async () => {
const adminUser = await prisma.user.findFirstOrThrow({ where: { email: "[email protected]" } });
const { req } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
method: "GET",
query: {
expand: "team",
},
pagination: DefaultPagination,
});

req.userId = adminUser.id;
req.isOrganizationOwnerOrAdmin = true;

const responseData = await handler(req);
console.log("bookings=>", responseData.bookings);
responseData.bookings.forEach((booking) => {
if (booking.id === 31) expect(booking.eventType?.team?.slug).toBe("team1");
if (booking.id === 19) expect(booking.eventType?.team).toBe(null);
});
});
});
});
4 changes: 2 additions & 2 deletions apps/api/v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ Copy `.env.example` to `.env` and fill values.

## Add license Key to deployments table in DB

id, logo theme licenseKey agreedLicenseAt
1, null, null, 'c4234812-12ab-42s6-a1e3-55bedd4a5bb7', '2023-05-15 21:39:47.611'
id, logo theme licenseKey agreedLicenseAt
1, null, null, 'c4234812-12ab-42s6-a1e3-55bedd4a5bb7', '2023-05-15 21:39:47.611'

your CALCOM_LICENSE_KEY env var need to contain the same value

Expand Down
4 changes: 3 additions & 1 deletion apps/api/v2/jest-e2e.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@
"^.+\\.(t|j)s$": "ts-jest"
},
"setupFiles": ["<rootDir>/test/setEnvVars.ts"],
"reporters": ["default", "jest-summarizing-reporter"]
"reporters": ["default", "jest-summarizing-reporter"],
"workerIdleMemoryLimit": "512MB",
"maxWorkers": 2
}
Loading
Loading