├── .gitbook └── assets │ ├── 2.png │ ├── 9e22d93e-bec6-4a14-ba89-f64f45a896ce.jpg │ ├── Cal.com Organisation Chart.png │ ├── CleanShot 2022-07-25 at 09.40.14@2x.png │ ├── CleanShot 2022-07-25 at 09.43.41@2x.png │ ├── CleanShot 2022-07-26 at 12.48.32@2x.png │ ├── CleanShot 2022-07-26 at 12.49.52@2x.png │ ├── CleanShot 2022-07-26 at 12.51.37@2x.png │ ├── CleanShot 2022-07-26 at 14.44.47@2x.png │ ├── CleanShot 2022-07-26 at 15.12.15@2x.png │ ├── CleanShot 2022-07-29 at 22.29.58@2x.png │ ├── CleanShot 2022-07-29 at 22.30.40@2x.png │ ├── CleanShot 2022-08-02 at 11.07.17@2x.png │ ├── CleanShot 2022-08-02 at 11.09.23@2x.png │ ├── CleanShot 2022-08-02 at 11.10.56@2x.png │ ├── CleanShot 2022-08-18 at 14.56.37@2x.png │ ├── CleanShot 2022-10-12 at 20.47.42@2x.png │ ├── CleanShot 2022-10-12 at 20.49.56@2x.png │ ├── CleanShot 2022-10-13 at 10.38.32@2x.png │ ├── CleanShot 2023-09-27 at 15.19.05@2x.png │ ├── Group 1.png │ ├── Group 4 (1).svg │ ├── Group 4.svg │ ├── Group 6.png │ ├── In your PR... (1).svg │ ├── In your PR....pdf │ ├── In your PR....svg │ ├── Markets and Strategy.png │ ├── Refer to the project board.svg │ ├── Screen Shot 2023-11-14 at 11.40.45 AM.png │ ├── Screenshot 2022-07-15 at 10.41.55 AM (1).png │ ├── Screenshot 2022-07-15 at 10.41.55 AM.png │ ├── Screenshot 2022-07-15 at 10.41.59 AM.png │ ├── Screenshot 2022-10-04 at 4.18.54 PM.png │ ├── Screenshot 2022-10-04 at 4.23.15 PM.png │ ├── When tackling an issue... (1).svg │ ├── When tackling an issue....svg │ ├── image (1).png │ ├── image (10).png │ ├── image (11) (1).png │ ├── image (11).png │ ├── image (12).png │ ├── image (13).png │ ├── image (14) (1).png │ ├── image (14).png │ ├── image (15).png │ ├── image (16).png │ ├── image (17).png │ ├── image (18).png │ ├── image (19).png │ ├── image (2) (1).png │ ├── image (2).png │ ├── image (20).png │ ├── image (21).png │ ├── image (22).png │ ├── image (23).png │ ├── image (24).png │ ├── image (25).png │ ├── image (26).png │ ├── image (3).png │ ├── image (4) (1).png │ ├── image (4).png │ ├── image (5).png │ ├── image (6) (1).png │ ├── image (6).png │ ├── image (7) (1).png │ ├── image (7).png │ ├── image (8) (1).png │ ├── image (8).png │ ├── image (9).png │ ├── image.png │ ├── raw.png │ └── ray-so-export (5).png ├── README.md ├── SUMMARY.md ├── customer-success └── tone.md ├── engineering ├── best-practices │ ├── README.md │ ├── avoid-comparing-multiple-values-with-includes.md │ ├── avoid-prop-drilling.md │ ├── data-fetching.md │ ├── disallowing-the-use-of-unrestricted-metadata-fields.md │ ├── dont-modularize-prematurely.md │ ├── e2e-tests-best-practices.md │ ├── only-select-data-you-need.md │ ├── prefer-composition-over-prop-drilling.md │ ├── prefer-defaulthandler-for-simple-api-handlers.md │ ├── prefer-early-returns.md │ ├── prefer-inferred-types-over-explicit-ones.md │ ├── prefer-ternaries-over-short-circuiting-and-and-for-react-components.md │ └── validate-using-zod-instead-of-type-casting.md ├── cal.com-status-page.md ├── codebase │ ├── README.md │ ├── debug-desktop-app.md │ ├── deployment.md │ ├── feature-flags.md │ ├── git-private-submodules.md │ ├── keeping-the-lock-file-in-sync.md │ ├── merging-monday.md │ └── monorepo-turborepo.md ├── how-to-report-issues.md ├── how-we-work-on-tickets.md ├── https-and-subdomains.md ├── keeping-docs-up-to-date.md ├── managing-notifications.md ├── pr-reviews.md ├── resolving-failed-migration-on-vercel-preview.md ├── self-reviews.md ├── valuable-bookmarks.md └── what-to-do-during-emergencies.md ├── hr-and-careers ├── bonus-and-equity-structure.md ├── contract-to-hire-trials.md ├── ic-levels │ ├── README.md │ └── engineering-levels │ │ ├── README.md │ │ ├── ic1-engineer-code-cadet.md │ │ ├── ic2-engineer-code-craftsperson.md │ │ ├── ic3-engineer-code-connoisseur.md │ │ └── ic4-engineer-code-wizard.md ├── onboarding.md └── sharing-your-views.md ├── marketing ├── how-to-add-a-new-tip-to-sidebar.md └── media.md ├── policies ├── communications.md ├── expenses.md └── vacations.md ├── sales └── operations-stack.md └── the-company ├── glossary.md ├── mission-vision-and-values.md ├── organization-chart.md └── what-is-cal.com.md /.gitbook/assets/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/2.png -------------------------------------------------------------------------------- /.gitbook/assets/9e22d93e-bec6-4a14-ba89-f64f45a896ce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/9e22d93e-bec6-4a14-ba89-f64f45a896ce.jpg -------------------------------------------------------------------------------- /.gitbook/assets/Cal.com Organisation Chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Cal.com Organisation Chart.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-25 at 09.40.14@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-25 at 09.40.14@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-25 at 09.43.41@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-25 at 09.43.41@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-26 at 12.48.32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-26 at 12.48.32@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-26 at 12.49.52@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-26 at 12.49.52@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-26 at 12.51.37@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-26 at 12.51.37@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-26 at 14.44.47@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-26 at 14.44.47@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-26 at 15.12.15@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-26 at 15.12.15@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-29 at 22.29.58@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-29 at 22.29.58@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-07-29 at 22.30.40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-07-29 at 22.30.40@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-08-02 at 11.07.17@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-08-02 at 11.07.17@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-08-02 at 11.09.23@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-08-02 at 11.09.23@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-08-02 at 11.10.56@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-08-02 at 11.10.56@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-08-18 at 14.56.37@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-08-18 at 14.56.37@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-10-12 at 20.47.42@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-10-12 at 20.47.42@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-10-12 at 20.49.56@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-10-12 at 20.49.56@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2022-10-13 at 10.38.32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2022-10-13 at 10.38.32@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/CleanShot 2023-09-27 at 15.19.05@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/CleanShot 2023-09-27 at 15.19.05@2x.png -------------------------------------------------------------------------------- /.gitbook/assets/Group 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Group 1.png -------------------------------------------------------------------------------- /.gitbook/assets/Group 6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Group 6.png -------------------------------------------------------------------------------- /.gitbook/assets/In your PR....pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/In your PR....pdf -------------------------------------------------------------------------------- /.gitbook/assets/Markets and Strategy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Markets and Strategy.png -------------------------------------------------------------------------------- /.gitbook/assets/Screen Shot 2023-11-14 at 11.40.45 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Screen Shot 2023-11-14 at 11.40.45 AM.png -------------------------------------------------------------------------------- /.gitbook/assets/Screenshot 2022-07-15 at 10.41.55 AM (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Screenshot 2022-07-15 at 10.41.55 AM (1).png -------------------------------------------------------------------------------- /.gitbook/assets/Screenshot 2022-07-15 at 10.41.55 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Screenshot 2022-07-15 at 10.41.55 AM.png -------------------------------------------------------------------------------- /.gitbook/assets/Screenshot 2022-07-15 at 10.41.59 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Screenshot 2022-07-15 at 10.41.59 AM.png -------------------------------------------------------------------------------- /.gitbook/assets/Screenshot 2022-10-04 at 4.18.54 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Screenshot 2022-10-04 at 4.18.54 PM.png -------------------------------------------------------------------------------- /.gitbook/assets/Screenshot 2022-10-04 at 4.23.15 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/Screenshot 2022-10-04 at 4.23.15 PM.png -------------------------------------------------------------------------------- /.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (10).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (10).png -------------------------------------------------------------------------------- /.gitbook/assets/image (11) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (11) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (11).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (11).png -------------------------------------------------------------------------------- /.gitbook/assets/image (12).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (12).png -------------------------------------------------------------------------------- /.gitbook/assets/image (13).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (13).png -------------------------------------------------------------------------------- /.gitbook/assets/image (14) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (14) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (14).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (14).png -------------------------------------------------------------------------------- /.gitbook/assets/image (15).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (15).png -------------------------------------------------------------------------------- /.gitbook/assets/image (16).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (16).png -------------------------------------------------------------------------------- /.gitbook/assets/image (17).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (17).png -------------------------------------------------------------------------------- /.gitbook/assets/image (18).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (18).png -------------------------------------------------------------------------------- /.gitbook/assets/image (19).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (19).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (2) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (20).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (20).png -------------------------------------------------------------------------------- /.gitbook/assets/image (21).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (21).png -------------------------------------------------------------------------------- /.gitbook/assets/image (22).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (22).png -------------------------------------------------------------------------------- /.gitbook/assets/image (23).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (23).png -------------------------------------------------------------------------------- /.gitbook/assets/image (24).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (24).png -------------------------------------------------------------------------------- /.gitbook/assets/image (25).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (25).png -------------------------------------------------------------------------------- /.gitbook/assets/image (26).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (26).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (4) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (4).png -------------------------------------------------------------------------------- /.gitbook/assets/image (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (5).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (6) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (6).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (7) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (7).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (8) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (8).png -------------------------------------------------------------------------------- /.gitbook/assets/image (9).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image (9).png -------------------------------------------------------------------------------- /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/image.png -------------------------------------------------------------------------------- /.gitbook/assets/raw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/raw.png -------------------------------------------------------------------------------- /.gitbook/assets/ray-so-export (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calcom/handbook/dd4284ec468d6d88d5be555f167ffc171e9dbff8/.gitbook/assets/ray-so-export (5).png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: .gitbook/assets/9e22d93e-bec6-4a14-ba89-f64f45a896ce.jpg 3 | coverY: -97.22651222651223 4 | --- 5 | 6 | # 👋 Cal.com Handbook 7 | 8 | ## Welcome aboard! 9 | 10 | Welcome to the company handbook! Here you'll find everything you need to know about the company. Within our internal docs, there are a number of sections. Some are more important than others to read, so here's a guide on what you can find here. 11 | 12 | ## The Company 13 | 14 | This is an overview of our mission, our team, and some of the high level stuff about how we operate. This gives new employees a clear picture of the company and what you can expect from us. 15 | 16 | ## HR & Careers 17 | 18 | This is an important read for everyone, explaining some of the processes and policies which apply to your career here at Cal.com 19 | 20 | ## Policies 21 | 22 | Here are the details explaining what you can and can't do in relation to things such as vacations and expenses. 23 | 24 | ## Engineering, Customer Success & Marketing 25 | 26 | You can find team-specific details about each team's purpose and processes here. 27 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [👋 Cal.com Handbook](README.md) 4 | 5 | ## The Company 6 | 7 | * [❓ What is Cal.com?](the-company/what-is-cal.com.md) 8 | * [📈 Mission, Vision and Values](the-company/mission-vision-and-values.md) 9 | * [🅰️ Glossary](the-company/glossary.md) 10 | * [📈 Organization Chart](the-company/organization-chart.md) 11 | 12 | ## HR & Careers 13 | 14 | * [👷 Contract-to-hire trials](hr-and-careers/contract-to-hire-trials.md) 15 | * [🛫 Onboarding](hr-and-careers/onboarding.md) 16 | * [🏆 IC Levels](hr-and-careers/ic-levels/README.md) 17 | * [⛰️ Engineering Levels](hr-and-careers/ic-levels/engineering-levels/README.md) 18 | * [🕵️ IC1 Engineer (Code Cadet)](hr-and-careers/ic-levels/engineering-levels/ic1-engineer-code-cadet.md) 19 | * [👷‍♀️ IC2 Engineer (Code Craftsperson)](hr-and-careers/ic-levels/engineering-levels/ic2-engineer-code-craftsperson.md) 20 | * [🧘‍♀️ IC3 Engineer (Code Connoisseur)](hr-and-careers/ic-levels/engineering-levels/ic3-engineer-code-connoisseur.md) 21 | * [🧙‍♂️ IC4 Engineer (Code Wizard)](hr-and-careers/ic-levels/engineering-levels/ic4-engineer-code-wizard.md) 22 | * [💡 Sharing your views](hr-and-careers/sharing-your-views.md) 23 | * [💸 Bonus & Equity Structure](hr-and-careers/bonus-and-equity-structure.md) 24 | 25 | ## Policies 26 | 27 | * [🏖️ Vacations](policies/vacations.md) 28 | * [💳 Expenses](policies/expenses.md) 29 | * [🗣️ Communications](policies/communications.md) 30 | 31 | ## Engineering 32 | 33 | * [🔔 Managing Notifications](engineering/managing-notifications.md) 34 | * [⭐ Valuable Bookmarks](engineering/valuable-bookmarks.md) 35 | * [🐛 How to report issues](engineering/how-to-report-issues.md) 36 | * [💻 How we work on Tickets](engineering/how-we-work-on-tickets.md) 37 | * [🔥 What to do during Emergencies](engineering/what-to-do-during-emergencies.md) 38 | * [✅ PR Reviews](engineering/pr-reviews.md) 39 | * [☑️ Self-reviews](engineering/self-reviews.md) 40 | * [📚 Keeping Docs up-to-date](engineering/keeping-docs-up-to-date.md) 41 | * [🌐 HTTPS & Subdomains](engineering/https-and-subdomains.md) 42 | * [🎯 Best practices](engineering/best-practices/README.md) 43 | * [Data fetching](engineering/best-practices/data-fetching.md) 44 | * [Avoid Prop Drilling](engineering/best-practices/avoid-prop-drilling.md) 45 | * [Prefer defaultHandler for simple API handlers](engineering/best-practices/prefer-defaulthandler-for-simple-api-handlers.md) 46 | * [Prefer inferred types over explicit ones](engineering/best-practices/prefer-inferred-types-over-explicit-ones.md) 47 | * [Prefer early returns](engineering/best-practices/prefer-early-returns.md) 48 | * [Avoid comparing multiple values with \`includes\`](engineering/best-practices/avoid-comparing-multiple-values-with-includes.md) 49 | * [Validate using zod instead of type casting](engineering/best-practices/validate-using-zod-instead-of-type-casting.md) 50 | * [Prefer Composition over Prop Drilling](engineering/best-practices/prefer-composition-over-prop-drilling.md) 51 | * [Prefer ternaries over Short Circuiting “&&” for React Components](engineering/best-practices/prefer-ternaries-over-short-circuiting-and-and-for-react-components.md) 52 | * [Don't modularize prematurely](engineering/best-practices/dont-modularize-prematurely.md) 53 | * [Only select data you need](engineering/best-practices/only-select-data-you-need.md) 54 | * [Disallowing the use of unrestricted Metadata fields](engineering/best-practices/disallowing-the-use-of-unrestricted-metadata-fields.md) 55 | * [E2E Tests Best Practices](engineering/best-practices/e2e-tests-best-practices.md) 56 | * [💻 Codebase](engineering/codebase/README.md) 57 | * [🔓 Keeping the lock file in sync](engineering/codebase/keeping-the-lock-file-in-sync.md) 58 | * [🚫 Git Private Submodules](engineering/codebase/git-private-submodules.md) 59 | * [🏎️ Monorepo / Turborepo](engineering/codebase/monorepo-turborepo.md) 60 | * [🌝 Deploying to Production](engineering/codebase/merging-monday.md) 61 | * [☁️ Deployment](engineering/codebase/deployment.md) 62 | * [💻 Debug Desktop App](engineering/codebase/debug-desktop-app.md) 63 | * [🚩 Enabling/Disabling Features](engineering/codebase/feature-flags.md) 64 | * [🔺 Resolving failed migration on Vercel Preview](engineering/resolving-failed-migration-on-vercel-preview.md) 65 | * [🔦 Cal.com Status Page](engineering/cal.com-status-page.md) 66 | 67 | ## Customer Success 68 | 69 | * [💟 Tone](customer-success/tone.md) 70 | 71 | ## Marketing 72 | 73 | * [🎬 Media](marketing/media.md) 74 | * [☝️ How to add a new Tip to Sidebar](marketing/how-to-add-a-new-tip-to-sidebar.md) 75 | 76 | ## 🤲 Sales 77 | 78 | * [Operations Stack](sales/operations-stack.md) 79 | -------------------------------------------------------------------------------- /customer-success/tone.md: -------------------------------------------------------------------------------- 1 | # 💟 Tone 2 | 3 | {% hint style="info" %} 4 | Being in Customer Success isn't easy. Very few people contact Customer Success when they're happy. This document outlines the major guidelines that are needed to be a successful in Customer Success. 5 | {% endhint %} 6 | 7 | ### Why is tone important? 8 | 9 | In 1967, Albert Mehrabian came up with the “7%-38%-55%” rule determining that [communication is made up of three parts](http://www.ecademy.com/node.php?id=78144): 10 | 11 | 1. The actual words you use (7%), 12 | 2. The tone of delivery in your voice (38%), and 13 | 3. The body language accompanying your words and voice (55%). 14 | 15 | *** 16 | 17 | ## The PREACH Model 18 | 19 | At Cal.com, when speaking to customers, we use the PREACH approach — we aim to be Proud, Responsible, Empathetic, Articulate, Concise and Human: 20 | 21 | * **Proud** – Our goal is to make the experience we solve better for our users. We own this goal and its impact unapologetically. For instance, we don’t say “Unfortunately we have a fee”, we say “We have a small service fee of X% that enables us to keep Cal.com up and running." 22 | * **Responsible** – If a bad feature or bug ships and a customer is disappointed or frustrated, it’s on us. We don’t blame the engineers (e.g. "Our engineering team messed up"), or attempt to come up with excuses. We take ownership of our mistakes, and move forward. 23 | * **Empathetic** – We acknowledge, and aim to truly understand how our customers feel and handle each conversation accordingly. We match their tone of voice, and the situation wherever we can. 24 | * **Articulate** – Gracefully augmenting your conversations with personal language, emojis (from time to time), and exclamation points is encouraged, but typos, bad punctuation, poor phrasing, or missing the point of their question make us look less professional. This might seem like an obvious one, but it’s important to keep the fundamentals front and center in order to reinforce our high bar. 25 | * **Concise** – No matter how much fun you can have with your customers, never forget they contacted you for a reason. Our job is to fully understand their needs and resolve them as quickly as possible. It's best to use bullet points and numbered lists when possible, and keep paragraphs at 2-4 sentences. 26 | * **Human** – We want customers to know they're talking to a human, even if you're using an automated response. For custom responses, take this opportunity to really connect with your customers, and if you wouldn’t say the words in a “normal” spoken interaction, don’t say them during a customer interaction. 27 | 28 | ## Our Tone Guidelines 29 | 30 | ### Talk to customers like you would in a "normal" spoken interaction. 31 | 32 | Be a human when you're talking to the customers. Pretending that you're talking to your parent or grandparent is helpful to provide the right tone. 33 | 34 | ### Be casual, as long as you're not giving bad news. 35 | 36 | Emoticons: Typically okay to use for positive reinforcement with customers. 37 | 38 | Colloquial words or "text talk": No `lol` or `btw`. We're more professional than that. 39 | 40 | Exclamation points: Limit to 1 or 2 exclamation points per response. Only use when the overall gist of the response is very positive. 41 | 42 | **See the Zendesk study** 43 | 44 | In the first survey conducted by Software Advice, 65% of customers preferred their support staff to have a “casual” tone in the contents of their interactions. 45 | 46 | https://d26a57ydsghvgx.cloudfront.net/content/blog/How to satisfy customers using right tone 1.png 47 | 48 | Interestingly enough, the distribution was consistent across all age and gender demographics. No matter how young or old the customer was, they typically preferred a casual tone and style in writing. 49 | 50 | ### **Context matters** 51 | 52 | Although customers generally prefer a more human, friendly tone, each support interaction is different. A service staff must be able to assess the situation and any emotion at play, think about the right style of approach, and react appropriately. 53 | 54 | For example, according to Jay Ivey, customers are likely to interpret a casual attitude in a delicate situation as being insensitive, condescending, or otherwise inappropriate. It just may not create the most productive mood. 55 | 56 | https://d26a57ydsghvgx.cloudfront.net/content/blog/How to satisfy customers using right tone 2.png 57 | 58 | An overwhelming majority of customers—78%—would be dissatisfied if their request was denied using a casual tone. In contrast, if a request was granted in a formal tone, only 35% said it affected their satisfaction. 59 | 60 | ### **Pro tip:** 61 | 62 | A support staff must be careful when dealing with those who are angry or upset. No need to learn the hard way here about the power of emotion: Those customers are, understandably, much more likely to be sensitive to the tone in the contents of the exchange. The best course of action is to keep the tone neutral and rely on [other techniques](https://blog.zopim.com/2013/12/03/deal-unhappy-customers/) to help defuse the situation and create a more productive mood. It's OK if your support interaction winds up on Twitter — as long as the story being told is a happy one. 63 | 64 | ### **Colloquialisms are sometimes inappropriate** 65 | 66 | Casual banter can sometimes go too far. Yes, it's a popular default style, and it can make everyone feel at ease, especially if the speaker or writer representing your company is naturally funny. 67 | 68 | In the last decade emoticons \[ ;P ], emoji, and colloquialisms \[“lol”] have become commonplace in the contents of digital communication. They add some extra character to a sentence or a story, sure, sure, but is it something that every reader can appreciate? 69 | 70 | https://d26a57ydsghvgx.cloudfront.net/content/blog/How to satisfy customers using right tone 3.png 71 | 72 | Although 49% of customers didn’t consider any of the listed options as too casual, 35% felt that emoticons were too informal for support services. Similarly, 26% said the same about colloquial words. 73 | 74 | Jay Ivey does offer a caveat here. Unlike support emails, live chat is inherently more casual. The back-and-forth style of chat makes it easier to remember there’s a real human being with some personality on the other end. Sometimes, liberally using emoticons or colloquialisms in the contents of the chat might actually be appropriate, just so long as agents are conscientious of the reader's needs on the other side. 75 | 76 | ### **Pro tip:** 77 | 78 | Read the situation. If the customer is using emoticons or colloquial language, feel free to respond in kind. Just don't go overboard and treat it like a bad Twitter post. 79 | 80 | You are all characters in a story here: Staying alert to how the customer is feeling can help an agent with the right expression or word choice. A thoughtful approach to the content fueling these interactions can help ensure the message an agent communicates is well received. 81 | 82 | ### Use first names. 83 | 84 | * Don't use titles, like `Mr.`, `Mrs.`, `Miss`, or `Ma'am` 85 | * If you're not sure what their name is, address them by saying `Hey there` or `Hi again` (if they write back) 86 | 87 | ### Always use a salutation. 88 | 89 | * Opening: `Hey` or `Hi` 90 | * Closing: `Cheers,` or `Thanks!` 91 | 92 | ### Thank them when appropriate, especially in the first response. 93 | 94 | * Providing feedback:`Thank you for reaching out to us.` 95 | * Don't use this for every one of their responses; otherwise it will seem too scripted. 96 | 97 | ### Say "We're sorry" when needed. 98 | 99 | If you're late to respond to a friend or if they're experiencing an issue, you would say you're sorry. 100 | 101 | * Bugs/issues: `We're so sorry you're experiencing this issue.` 102 | 103 | ### No grammar, spelling, or syntax issues. 104 | 105 | * Have [**Grammarly**](https://chrome.google.com/webstore/detail/grammarly-for-chrome/kbfnbcaeplbcioakkpcpgfkobkghlhen?hl=en) turned on in Chrome when you're working to prevent errors. 106 | * The [**Grammarly blog**](https://www.grammarly.com/blog/) is a good resource. 107 | 108 | ### Be positive. 109 | 110 | * That's a great question! 111 | * Start with the good, not the bad. 112 | 113 | (e.g. `Try this` instead of `We can't help`) 114 | 115 | ### Use "we", not "I". 116 | 117 | * You're speaking on behalf of the company in every email you send. 118 | -------------------------------------------------------------------------------- /engineering/best-practices/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Here are some of the recommendations to achieve optimal code quality and to 4 | follow best practices. 5 | --- 6 | 7 | # 🎯 Best practices 8 | 9 | * [Data Fetching](data-fetching.md) 10 | * [Prefer inferred types over explicit ones](prefer-inferred-types-over-explicit-ones.md) 11 | * [Prefer early returns](prefer-early-returns.md) 12 | * [Avoid comparing multiple values with `includes`](avoid-comparing-multiple-values-with-includes.md) 13 | * [Validate using zod instead of type casting](validate-using-zod-instead-of-type-casting.md) 14 | * Don't hesitate extracting nested code into new React Components 15 | * Code organization tips 16 | * Consider state machines over simple boolean states 17 | * Don't extract function props outside render just because 18 | * Make proper user of React Children 19 | * Authed CRUDs should be user centric 20 | * Prefer adding tRPC queries over `/api/..` endpoints on `web` 21 | * [Prefer `defaultHandler` for simple API handlers](prefer-defaulthandler-for-simple-api-handlers.md) 22 | * [Prefer Composition over Prop Drilling](prefer-composition-over-prop-drilling.md) 23 | * [Avoid Prop Drilling](avoid-prop-drilling.md) 24 | * [prefer-ternaries-over-short-circuiting-and-and-for-react-components.md](prefer-ternaries-over-short-circuiting-and-and-for-react-components.md "mention") 25 | 26 | {% hint style="info" %} 27 | TODO: Expand each of these bullet points 28 | {% endhint %} 29 | 30 | ### Additional resources 31 | 32 | * [https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/basic\_type\_example/](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/basic\_type\_example/) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /engineering/best-practices/avoid-comparing-multiple-values-with-includes.md: -------------------------------------------------------------------------------- 1 | # Avoid comparing multiple values with \`includes\` 2 | 3 | Instead of doing: 4 | 5 | ```typescript 6 | if (req.method === "POST" || req.method === "PUT" || req.method === "DELETE") { 7 | console.log("Method allowed"); 8 | } 9 | ``` 10 | 11 | Do: 12 | 13 | ```typescript 14 | if (["POST", "PUT", "DELETE"].includes(req.method)) { 15 | console.log("Method allowed"); 16 | } 17 | ``` 18 | 19 | This will very situational, but when comparing multiple values you can use include to improve legibility. Also make sure that an [early return isn't more appropriate first](avoid-comparing-multiple-values-with-includes.md#prefer-early-returns). 20 | -------------------------------------------------------------------------------- /engineering/best-practices/avoid-prop-drilling.md: -------------------------------------------------------------------------------- 1 | # Avoid Prop Drilling 2 | 3 | {% embed url="https://twitter.com/asidorenko_/status/1623751929863016450?s=61&t=yL8-sVU9YPvKV53r6jcV1A" %} 4 | TLDR 5 | {% endembed %} 6 | -------------------------------------------------------------------------------- /engineering/best-practices/data-fetching.md: -------------------------------------------------------------------------------- 1 | # Data fetching 2 | 3 | When fetching for data in your Next.js pages you can follow the recommended approach for handling prefetching and loading states: 4 | 5 | ![](<../../.gitbook/assets/image (4).png>) 6 | 7 | This will allow to have this data already ready in the initial load, reducing the number of loading states and null/undefined checks. 8 | -------------------------------------------------------------------------------- /engineering/best-practices/disallowing-the-use-of-unrestricted-metadata-fields.md: -------------------------------------------------------------------------------- 1 | # Disallowing the use of unrestricted Metadata fields 2 | 3 | #### WHY? 4 | 5 | PostgreSQL has long been esteemed for its robustness and its ability to handle a wide variety of data types, including JSON. JSON support in PostgreSQL allows for a non-relational representation of data structures, providing flexibility in how data is stored and retrieved. However, while there are scenarios where JSON is beneficial, certain limitations exist that can make its use in PostgreSQL disadvantageous. 6 | 7 | Opting to use JSON because it's "easy" is akin to just spinning up a MongoDB cluster to store data we are not caring about enough to restrict with a specific schema. 8 | 9 | #### PERFORMANCE DRAWBACKS 10 | 11 | JSON data is not stored in a pre-defined manner, which can lead to significant performance overhead. The database engine must parse JSON data for each query, which can be computationally expensive, leading to slower query performance compared to traditional relational data storage. This is particularly noticeable in large-scale databases or when executing complex queries that require the database to sift through sizable JSON documents. 12 | 13 | #### INDEXING DIFFICULTIES 14 | 15 | While PostgreSQL does allow for indexing JSON data, these indexes are typically not as efficient as those on traditional column data. Indexing a JSON field requires the creation of a functional index on the specific key within the JSON blob, which can lead to a proliferation of indexes and increased maintenance overhead. Furthermore, these indexes can be less performant, especially if the queries are not well-aligned with the index structure. 16 | 17 | #### DATA MODIFICATION 18 | 19 | Modifying data within a JSON field can be cumbersome. Unlike standard fields that can be updated directly using SQL 'UPDATE' statements, changing a single value within a JSON document often requires rewriting the entire document. This can lead to inefficient data manipulation operations, particularly for larger JSON documents. 20 | 21 | {% hint style="info" %} 22 | #### HOW TO SOLVE THIS? 23 | 24 | In most cases, we're using metadata to store responses from third party APIs, e.g. Google Calendar, Stripe, etc. For most of these we're already defining a zod schema to parse said responses, thus, why not create columns or tables directly for those responses? We're getting type safety by the generated Prisma types, and we can index those fields (eg stripeCustomerId, which is currently living under the `metadata` within a User's object) 25 | {% endhint %} 26 | 27 | #### 28 | -------------------------------------------------------------------------------- /engineering/best-practices/dont-modularize-prematurely.md: -------------------------------------------------------------------------------- 1 | # Don't modularize prematurely 2 | 3 | The reason why you should not split files if they're not being used in more than one place is because it can lead to unnecessary complexity and maintenance overhead. If a file is only being used in one place, there is no need to split it into multiple files. This can make it harder to navigate and understand the codebase. 4 | 5 | On the other hand, splitting functions and components as much as possible can be beneficial. It can help with code organization, reuse, and testability. By breaking down large components into smaller ones, you can create a more modular and flexible codebase. This can make it easier to maintain and evolve the code over time. 6 | 7 | Collocating related code in the same file can also improve code organization and readability. If you have related code scattered across multiple files, it can be harder to understand how everything fits together. 8 | 9 | In summary, the decision to split files or not should be based on whether it improves code organization, readability, and maintainability. It's okay to split functions and components as much as possible, but don't split files unnecessarily. Collocating related code in the same file can also be helpful. 10 | -------------------------------------------------------------------------------- /engineering/best-practices/e2e-tests-best-practices.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | These are some basic principles that should be respected when working with E2E 4 | tests. Failure to follow these practices can be a motive for PR rejection. 5 | --- 6 | 7 | # E2E Tests Best Practices 8 | 9 | * A test should avoid using Text Locators: `page.locator('text=` 10 | * Add a proper to data-testid to the HTML element and retrieve it by using page.getByTestId 11 | * From [Playwright docs](https://playwright.dev/docs/locators#locate-by-test-id): 12 | * > Testing by test ids is the most resilient way of testing as even if your text or role of the attribute changes the test will still pass. QA's and developers should define explicit test ids and query them with page.getByTestId(). However testing by test ids is not user facing. If the role or text value is important to you then consider using user facing locators such as role and text locators. 13 | * A test should be able to run locally as well as on CI 14 | * A test should be able to be run multiple times and expect a consistent result 15 | * A test should not introduce side-effects that may affect other tests running in parallel 16 | * A test should use expect(page).toHaveURL() so we can fail fast if a new unexpected redirection is introduced 17 | * A test should avoid using fixed seeded records for testing. 18 | * This conflicts with parallelization and consistency 19 | * A test should reset the DB state to be the same after running tests than it was before running them. 20 | * This means all created records should be properly cleaned up after tests are run 21 | * If seeded records were used, return them to their original state afterwards. 22 | 23 | ### TODO 24 | 25 | * Guide for debugging E2E failures 26 | * What to do when checks fail? 27 | * How can I know where to look? 28 | * Recommended Tools and extensions 29 | * Workflow recommendations for working with E2E tests 30 | -------------------------------------------------------------------------------- /engineering/best-practices/only-select-data-you-need.md: -------------------------------------------------------------------------------- 1 | # Only select data you need 2 | 3 | 1\) Increased performance overhead: When you select all columns from a table, Prisma retrieves all the data associated with each row, which can result in a significant performance impact. This includes reading unnecessary columns and transferring a large volume of data between your application and the database. 4 | 5 | 2\) Unnecessary data exposure: Selecting all columns exposes sensitive data that might not be required by your application. This can pose security risks, especially if the table contains sensitive user information or proprietary data. (In our case app credentials and booking information) 6 | 7 | ![](<../../.gitbook/assets/ray-so-export (5).png>) 8 | 9 | TLDR: Never use Includes - use select 10 | 11 | * Select selects only the fields you specify explicitly 12 | * Include selects the relationship AND all the fields of the table the relationship belongs to 13 | 14 | {% embed url="https://www.prisma.io/docs/concepts/components/prisma-client/select-fields" %} 15 | -------------------------------------------------------------------------------- /engineering/best-practices/prefer-composition-over-prop-drilling.md: -------------------------------------------------------------------------------- 1 | # Prefer Composition over Prop Drilling 2 | 3 | Instead of relying on prop drilling, let's try to take advantage of react children feature. Having this as an example: 4 | 5 | {% code overflow="wrap" lineNumbers="true" %} 6 | ```typescript 7 | import React from "react"; 8 | import { Profile } from "./profile"; 9 | 10 | function Header({ loggedIn, handleSetLoggedIn }) { 11 | return ( 12 | <> 13 | 14 | 15 | ); 16 | } 17 | 18 | function App() { 19 | const [loggedIn, setLoggedIn] = React.useState(false); 20 | 21 | const handleSetLoggedIn = () => { 22 | setLoggedIn(!loggedIn); 23 | }; 24 | 25 | return
; 26 | } 27 | ``` 28 | {% endcode %} 29 | 30 | Instead of "drilling props" all the way down, focus having everything as top level as possible: 31 | 32 | ```typescript 33 | import React from "react"; 34 | import { Profile } from "./profile"; 35 | 36 | function Header({ children }) { 37 | return ( 38 | <> 39 | {children} 40 | 41 | ); 42 | } 43 | 44 | function App() { 45 | const [loggedIn, setLoggedIn] = React.useState(false); 46 | 47 | const handleSetLoggedIn = () => { 48 | setLoggedIn(!loggedIn); 49 | }; 50 | 51 | return ( 52 |
53 | 54 |
55 | ); 56 | } 57 | ``` 58 | 59 | ### More sources on this topic 60 | 61 | * [Composition: An Alternative to Props Drilling in React](https://javascript.plainenglish.io/composition-in-react-f02afe24bc46) 62 | * [A better way of solving prop drilling in React apps](https://blog.logrocket.com/solving-prop-drilling-react-apps/) 63 | * [Strategies for mitigating prop drilling with React and TypeScript](https://blog.logrocket.com/mitigating-prop-drilling-with-react-and-typescript/) 64 | -------------------------------------------------------------------------------- /engineering/best-practices/prefer-defaulthandler-for-simple-api-handlers.md: -------------------------------------------------------------------------------- 1 | # Prefer defaultHandler for simple API handlers 2 | 3 | Instead of checking for each method: 4 | 5 | ```typescript 6 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 7 | if (req.method === "GET") { 8 | res.status(202).json({ message: "getting something" }); 9 | } 10 | if (req.method === "POST") { 11 | res.status(202).json({ message: "posting something" }); 12 | } 13 | if (req.method === "PATCH") { 14 | res.status(202).json({ message: "patching something" }); 15 | } 16 | } 17 | ``` 18 | 19 | Prefer splitting each method logic in their own files and use `defaultHandler` to auto-handle missing methods. And keep legibility when checking for individual method logic. 20 | 21 | ```typescript 22 | // _get.ts 23 | import { defaultResponder } from "@calcom/lib/server"; 24 | 25 | async function getHandler(req: NextApiRequest, res: NextApiResponse) { 26 | req.statusCode = 200; 27 | return { message: "getting something" }; 28 | } 29 | 30 | export default defaultResponder(getHandler); 31 | 32 | 33 | // _post.ts 34 | import { defaultResponder } from "@calcom/lib/server"; 35 | 36 | async function postHandler(req: NextApiRequest, res: NextApiResponse) { 37 | req.statusCode = 200; 38 | return { message: "posting something" }; 39 | } 40 | 41 | export default defaultResponder(postHandler); 42 | 43 | 44 | // _patch.ts 45 | import { defaultResponder } from "@calcom/lib/server"; 46 | 47 | async function patchHandler(req: NextApiRequest, res: NextApiResponse) { 48 | req.statusCode = 200; 49 | return { message: "patching something" }; 50 | } 51 | 52 | export default defaultResponder(patchHandler); 53 | 54 | 55 | // index.ts 56 | import { defaultHandler } from "@calcom/lib/server"; 57 | 58 | export default defaultHandler({ 59 | GET: import("./_get"), 60 | POST: import("./_post"), 61 | PATCH: import("./_patch"), 62 | }); 63 | ``` 64 | 65 | {% hint style="info" %} 66 | If you have only one method, splitting in files may be overkill. Instead you can keep all in one file but still benefit from auto-method handling by doing the following to comply with the TS signature. 67 | {% endhint %} 68 | 69 | ```typescript 70 | import { defaultHandler, defaultResponder } from "@calcom/lib/server"; 71 | 72 | async function getHandler(req: NextApiRequest, res: NextApiResponse) { 73 | req.statusCode = 200; 74 | return { message: "getting something" }; 75 | } 76 | 77 | export default defaultHandler({ 78 | GET: Promise.resolve({ default: getHandler }), 79 | }); 80 | ``` 81 | -------------------------------------------------------------------------------- /engineering/best-practices/prefer-early-returns.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | It is recommend to throw/return early so we can ensure null-checks and prevent 4 | further nesting. 5 | --- 6 | 7 | # Prefer early returns 8 | 9 | Instead of doing: 10 | 11 | ```typescript 12 | function handler(req, res) { 13 | const session = await getSession({ req }); 14 | if (session) { 15 | const user = getUserFromSession(session) 16 | 17 | if (user) { 18 | return res.status(200).json({ user }); 19 | } 20 | return res.status(404).json({ message: "No user found" }); 21 | } 22 | 23 | res.status(401).json({ message: "Not authenticated" }); 24 | } 25 | ``` 26 | 27 | Do: 28 | 29 | ```typescript 30 | function handler(req, res) { 31 | const session = await getSession({ req }); 32 | if (!session) return res.status(401).json({ message: "Not authenticated" }); 33 | 34 | const user = getUserFromSession(session) 35 | 36 | if (!user) return res.status(404).json({ message: "No user found" }); 37 | 38 | return res.status(200).json({ user }); 39 | } 40 | ``` 41 | 42 | It is recommend to throw/return early so we can ensure null-checks and prevent further nesting. 43 | 44 | {% embed url="https://www.youtube.com/shorts/JnFh2NoAM4s?feature=share" %} 45 | -------------------------------------------------------------------------------- /engineering/best-practices/prefer-inferred-types-over-explicit-ones.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | In this example the constant isn't really being used anywhere else, so it 4 | doesn't add any benefit to abstract to a constant in the first place. 5 | --- 6 | 7 | # Prefer inferred types over explicit ones 8 | 9 | Instead of doing: 10 | 11 | ```typescript 12 | const teamInviteEvent: TeamInvite = { 13 | language: t, 14 | from: session.user.name, 15 | to: usernameOrEmail, 16 | teamName: team.name, 17 | joinLink: BASE_URL + "/settings/teams", 18 | }; 19 | 20 | await sendTeamInviteEmail(teamInviteEvent); 21 | ``` 22 | 23 | Do: 24 | 25 | ```typescript 26 | await sendTeamInviteEmail({ 27 | language: t, 28 | from: session.user.name, 29 | to: usernameOrEmail, 30 | teamName: team.name, 31 | joinLink: BASE_URL + "/settings/teams", 32 | }); 33 | ``` 34 | -------------------------------------------------------------------------------- /engineering/best-practices/prefer-ternaries-over-short-circuiting-and-and-for-react-components.md: -------------------------------------------------------------------------------- 1 | # Prefer ternaries over Short Circuiting “&&” for React Components 2 | 3 | [https://medium.com/geekculture/stop-using-for-conditional-rendering-in-react-a0f7b96200f8](https://medium.com/geekculture/stop-using-for-conditional-rendering-in-react-a0f7b96200f8) 4 | -------------------------------------------------------------------------------- /engineering/best-practices/validate-using-zod-instead-of-type-casting.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Whenever we are parsing unknown json where we know the shape the object should 4 | have but it is not typed from source, it is worth the extra effort to use zod 5 | so we get both type and runtime safety. 6 | --- 7 | 8 | # Validate using zod instead of type casting 9 | 10 | Instead of doing: 11 | 12 | ```typescript 13 | type DeploymentCreateBody = { 14 | deploymentName: string, 15 | deploymentType: "CLOUD" | "SELFHOSTED", 16 | } 17 | 18 | const { deploymentName, deploymentType } = req.body as DeploymentCreateBody; 19 | ``` 20 | 21 | Do: 22 | 23 | ```typescript 24 | const deploymentCreateSchema = z.object({ 25 | deploymentName: z.string().min(1), 26 | deploymentType: z.nativeEnum(DeploymentType), 27 | }); 28 | 29 | const { deploymentName, deploymentType } = deploymentCreateSchema.parse(req.body); 30 | ``` 31 | -------------------------------------------------------------------------------- /engineering/cal.com-status-page.md: -------------------------------------------------------------------------------- 1 | # 🔦 Cal.com Status Page 2 | 3 | We have a status page at status.cal.com. Credentials can be found in Bitwarden. 4 | 5 | If there’s an incident you’re aware of, please log in and report it so it appears on the status page. Message [Bailey Pumfleet](https://app.gitbook.com/u/hPuJel8hUYNpA3g72VGJHk6YSy73 "mention") with any questions. 6 | 7 | 8 | 9 | Potential Incidents: 10 | 11 | * Booking is down 12 | * Availability is down 13 | * Database is down (AWS for example) 14 | 15 | ### Show Status Banner on cal.com 16 | 17 | 1. Go to: [https://betteruptime.com/team/25874/status-pages/132963/edit](https://betteruptime.com/team/25874/status-pages/132963/edit) 18 | 19 |
20 | 2. Write an announcement message — share to #AllHands that you wrote an announcement 21 | 3. Enable the embed announcement\ 22 | 23 | 24 |
25 | 4. Once resolved, disable the embed announcement, and close the thread 26 | -------------------------------------------------------------------------------- /engineering/codebase/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | Specific tactical knowledge about how we organise, deploy and work with code 4 | at cal.com 5 | --- 6 | 7 | # 💻 Codebase 8 | 9 | -------------------------------------------------------------------------------- /engineering/codebase/debug-desktop-app.md: -------------------------------------------------------------------------------- 1 | # 💻 Debug Desktop App 2 | 3 | 4 | 5 | {% embed url="https://www.loom.com/share/5c2692775da446d9bd5072d0305526b9" %} 6 | -------------------------------------------------------------------------------- /engineering/codebase/deployment.md: -------------------------------------------------------------------------------- 1 | # ☁ Deployment 2 | 3 | Our apps are hosted at vercel.com, we use a custom `vercel-deploy.sh` deploy script in order to clone the monorepo, and the git submodules recursively. 4 | 5 | ### cal.com 6 | 7 | The fastest way to deploy from `main` to `production` is by force pushing (only admins can do that): 8 | 9 | ``` 10 | git push origin +main:production 11 | ``` 12 | 13 | 14 | 15 | ### app.cal.com 16 | 17 | ### api.cal.com 18 | 19 | ### console.cal.com 20 | 21 | -------------------------------------------------------------------------------- /engineering/codebase/feature-flags.md: -------------------------------------------------------------------------------- 1 | # 🚩 Enabling/Disabling Features 2 | 3 | To enable or disable certain features in the product, we leverage the use of database feature flags and cookies. 4 | 5 | ## Database Feature Flags 6 | 7 | When we want to enable or disable a feature for all users, we need to use feature flags. We have a model named `Feature` that represents these flags that are persisted in the database. A migration needs to be written to modify the records in this table. 8 | 9 | ## Cookies 10 | 11 | When we want to enable or disable a feature for a specific user, we instead will use cookies. This way, we can send users instructions on how to interact with select cookies. For example, to enable the new booker before it launched for everyone, we had the `api/newbooker/enable` route that returned a cookie with the key of `new-booker-enabled` allowing us to check that cookie on subsequent requests. 12 | -------------------------------------------------------------------------------- /engineering/codebase/git-private-submodules.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: As part of our monorepo, we have some private git submodules that are private. 3 | --- 4 | 5 | # 🚫 Git Private Submodules 6 | 7 | ### Why? 8 | 9 | Although we try to keep as much of our codebase as possible open source. We don't want to make it too easy for a wanna be competitor or copy-cat to just clone our repo and setup mycal.com to compete with us, thus, some more sensitive parts of our codebase or like our landing / marketing pages at cal.com will remain private closed source repos, which will live under git private submodules in our main monorepo. 10 | 11 | ### Website 12 | 13 | This is our main landing page when you go at cal.com, it contains our proprietary signup implementation, which let's you purchase a subscription for a -premium- username at cal. 14 | 15 | It also contains our blogposts and other landing pages. 16 | 17 | 18 | 19 | ### Console 20 | 21 | The console is a private repo and not shared with anyone, console is where we control all the related stuff to deployments, keys, add-ons, etc. All kind of users will access it via console.cal.com to manage their subscriptions/deployments/keys for self-hosted enterprise instances. 22 | 23 | Since we don't want any code related to console to leak into the public repos, it syncs with the user at website when you signup, but creates a new user in a separate console database that holds the customer data. This user data gets synced via cronjob once a day. 24 | 25 | 26 | 27 | ### API 28 | 29 | Although API is a private submodule and closed-source, self-hosted infra customers can get access to the code in order to run API alongside their self-hosted cal instance. 30 | -------------------------------------------------------------------------------- /engineering/codebase/keeping-the-lock-file-in-sync.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | These instructions will help to ensure we don't introduce unwanted changes to 4 | the lock file. 5 | --- 6 | 7 | # 🔓 Keeping the lock file in sync 8 | 9 | Since we use some private modules alongside the public monorepo, we have some special requirements when dealing with lock file changes. This can be confusing for [some contributors](https://github.com/calcom/cal.com/issues/10436) and there's [some discussion](https://github.com/calcom/cal.com/issues/10217) around it as well. 10 | 11 | The rule of thumb is: As long a we don't introduce new packages (either in a package.json or monorepo package) there shouldn't be any lock file changes in a core contributor local environment. 12 | 13 | ### For core-contributors, how to ensure a consistent setup for submodules 14 | 15 | * Make sure you're on main 16 | 17 | ```bash 18 | git checkout main 19 | ``` 20 | * Make sure you have private submodules initialized and updated 21 | 22 | ```bash 23 | ./git-setup.sh website console 24 | ``` 25 | * Run yarn install to see if there are lock file diffs 26 | 27 | ```bash 28 | yarn 29 | ``` 30 | 31 | ### For external contributors 32 | 33 | Please refer to the ["Guidelines for committing yarn lock file"](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md#guidelines-for-committing-yarn-lockfile) section in our [CONTRIBUTING.md guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md). 34 | -------------------------------------------------------------------------------- /engineering/codebase/merging-monday.md: -------------------------------------------------------------------------------- 1 | # 🌝 Deploying to Production 2 | 3 | We merge all reviewed and approved PR's to `main` and then merge to the `production` branch to start the automated deployment process. 4 | 5 | | Branch | Deployed | Envirorment | 6 | | ------------- | ---------------- | ----------- | 7 | | Pull Requests | \*cal.vercel.app | Preview | 8 | | main | app.cal.dev | Staging | 9 | | production | app.cal.com | Production | 10 | 11 | ### Steps to release a new version 12 | 13 | 1. [Bump "version" in `apps/web/package.json` ](https://github.com/calcom/cal.com/edit/main/apps/web/package.json)according to semver standards, stage it in git and "Commit changes" directly to the `main` branch.\ 14 | ![](<../../.gitbook/assets/Screen Shot 2023-11-14 at 11.40.45 AM.png>) 15 | 2. Create a new release in GitHub:\ 16 | [https://github.com/calcom/cal.com/releases/new](https://github.com/calcom/cal.com/releases/new) 17 | 3. Type the new version and hit "Create new tag: vX.Y.Z on publish"\ 18 | ![](<../../.gitbook/assets/image (14).png>) 19 | 4. Use the "Create auto generated release text" button\ 20 | ![](<../../.gitbook/assets/image (2) (1).png>) 21 | 5. Publish release\ 22 | ![](<../../.gitbook/assets/image (11) (1).png>) 23 | 6. Profit! 24 | 25 | ### Check for migrations 26 | 27 | This is important. When doing a release make sure you run proper migrations first. 28 | 29 | Also, important sidenote, if a migration is adding a new table. We need to re-grant proper permissions to each created username that are currently being used. Run these commands for each username (Replcing \ with the proper one): 30 | 31 | ``` 32 | GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ; 33 | GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ; 34 | ``` 35 | -------------------------------------------------------------------------------- /engineering/codebase/monorepo-turborepo.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | We use turborepo to manage our calcom monorepo, which contains all our code, 4 | both public open source (calcom, etc) and private closed source (website, api, 5 | console) 6 | --- 7 | 8 | # 🏎 Monorepo / Turborepo 9 | 10 | You might already be familiar with monorepos with lerna and yarn workspaces, but we also uso turborepo to cache as much as possible the deployment of our monorepo. 11 | 12 | [https://turborepo.org/](https://turborepo.org/) 13 | 14 | Turbo repo builds pipelines see `turbo.json` so you can require any packages in other `apps` or `packages` 15 | 16 | \ 17 | As you can see too, instead of having all code under packages, turborepo makes the apps distinction for apps that are inteneded to be deployed as full apps. This is mainly a nomenclature thing but helps differentiate them. 18 | 19 | ### apps 20 | 21 | Apps are intended to be deployed at vercel.com as full-fledged webapps, and are usually nextjs based in our case. 22 | 23 | ### Our apps 24 | 25 | * apps/web - main webapp that lives under app.cal.com 26 | * apps/website - our landing and marketing site at cal.com 27 | * apps/api - our Public API deployed at api.cal.com 28 | * apps/swagger - our API auto-generated OpenAPI Spect 29 | * apps/docs 30 | 31 | #### Publish in your app an empty folder for deployment, make use of .gitkeep 32 | 33 | {% hint style="info" %} 34 | When deploying an app, you will need to have an empty folder inside: 35 | 36 | `/apps/{yourappname}/apps/{yourappname}/.gitkeep` 37 | 38 | This is necessary in order for the cloning of the monorepo and submodules, and then deployment of your app, to work properly as orchestrated from the `scripts/vercel-deploy.sh` in your app. 39 | {% endhint %} 40 | 41 | 42 | 43 | ### packages 44 | 45 | When you're requiring a local package from the monorepo, like `@calcom/ui` (unlike one from npm) like `react`, you just need to provide it's name and an asterisk for version, in the `package.json` this will make it available when you transpile it if you require it, for example in your next.config.js with the plugin transpile-modules withTM() 46 | 47 | This allows you to require local packages from our monorepo in your own package or app, so there's no need to wrangle versions, releases and publishing to npm, since those packages are not to be consumed by 3rd party apps and only necessary for us there's no need to publish them. Some of the packages might be published on their own, like embed or sdk. 48 | 49 | -------------------------------------------------------------------------------- /engineering/how-to-report-issues.md: -------------------------------------------------------------------------------- 1 | # 🐛 How to report issues 2 | 3 | _**Always**_ create a Linear ticket first unless it’s 4 | 5 | * a severe security concern or 6 | * a bug that is user-specific / includes user information / doesn’t require code changes 7 | 8 | 1. Create the issue in **Linear** 9 | * At this point, it should go into **Triage**. From there, the **Product** team will triage the issue, decide its priority and will plan it to be worked. 10 | * If the issue is a urgent bug that we need to fix now, it can be **Accepted** and put directly into **In Progress** 11 | * Ensure you've correctly set the **Project** on the Linear issue to correspond with the current release we are working on (e.g. v3.6, v3.7, etc.) 12 | * If it's more an internal task we don't want the GitHub community to see, put the `private` label on the issue so it's not synced. 13 | * There have been many Linear/GitHub issues created with just a link to Threads. **We need to stop doing this since community members do not have access to Threads.** 14 | 2. Add all the labels (bug, etc.) 15 | 3. Only open a thread if the issue is **Urgent** and we need to coordinate the work immediately. 16 | * Otherwise, new threads should not be created in the normal course of working issues. 17 | * Let's try to keep discussions about how to implement a feature or bug in Linear/GitHub. This will provide more content on the project itself instead of hidden in Threads. 18 | -------------------------------------------------------------------------------- /engineering/how-we-work-on-tickets.md: -------------------------------------------------------------------------------- 1 | # 💻 How we work on Tickets 2 | 3 | ### Linear and SyncLinear.com 4 | 5 | We use [linear.app](https://linear.app) for all issue tracking and use [synclinear.com](https://synclinear.com), our self-made Linear 🔄 GitHub Sync tool to 1-to-1 sync tickets. 6 | 7 | > This app lets you mirror Linear tickets to public GitHub issues, comments and all. This way, open-source teams can chat with contributors without giving access to an internal Linear team. 8 | 9 | By default, every ticket from Linear will be sent to GitHub and comments and statuses will be synced back and forth. 10 | 11 | Non-team members such as open-source contributors can continue to create tickets on [Github](https://github.com/calcom/cal.com/issues) and Cal.com Core members can assign the label "linear" to sync it back into Linear. 12 | 13 | The roadmap will continue to be public: [cal.com/roadmap](https://cal.com/roadmap). 14 | 15 | We run on a monthly tagged release schedule with multiple minor releases each week. 16 | 17 | When you're joining the team, make sure to join the "Cal.com, Inc." Linear team and then visit [synclinear.com](https://synclinear.com) 18 | 19 | * click "Connect to Linear" and make sure to select the “Engineering team” on the Linear dropdown and not “Product team” 20 | * click "Connect to GitHub" and select calcom/cal.com 21 | 22 | ## Process for taking on work 23 | 24 | **It's extremely important all engineers follow this process. Otherwise, keeping milestones up to date with the latest and greatest prioritized work is almost impossible.** 25 | 26 | * Source of truth: [Priority engineering view](https://linear.app/calcom/view/b58fd0a4-3637-4980-b26a-5a4a3fd2e8ec) in Linear 27 | * For tracking milestones, we use Linear Projects (v3.5, v3.6, etc.). This view will be automatically filtered based on our current milestone. 28 | * **Project** in Linear lines up to the **Milestone** in GitHub (for now because cycles in Linear don't work well for lining up the dates) 29 | * This is what will always be kept up to date by the Product team. **Do not start work on something unless it's listed here.** If you think something needs to be taken on and it's not yet in this view, contact the Product team. 30 | * We should take work from the top down in terms of priority. It should be rare you find yourself taking on work that has lower priority than other issues with higher priority that have not yet been started. If you don't feel comfortable starting an issue with higher priority for whatever reason, contact someone from the **Product** team. 31 | * If any items are marked as **Urgent**, drop what you are doing and pick up the issue. 32 | * Assign yourself and change its status to **In Progress.** 33 | * If an **Urgent** item is already assigned but no marked as **In Progress**, contact that person and check on the status. If it's actually not in progress, take it. If it is in progress, mark it as **In Progress** in Linear. 34 | * If there are no **Urgent** items, take an item you are comfortable working on from the **next highest item in the list.** 35 | * Note: This list can be manually prioritized, which will be handled by the Product team. **Do not move items around.** 36 | 37 | ## Linear Tips and Tricks 38 | 39 | ### Use Favorites to reduce noise 40 | 41 | ![](<../.gitbook/assets/CleanShot 2022-10-12 at 20.47.42@2x.png>) 42 | 43 | ### Use Keyboard shortcuts 44 | 45 | * Hover over a function to see the keyboard shortcut 46 | 47 | ### Add mobile website to Homescreen for PWA experience 48 | 49 | * on iPhone, open linear.app on Safari and "Add to Homescreen" 50 | * on Android, open with Chrome and "Add to Homescreen" 51 | 52 | ### Add "linear" to Github tickets from Community members 53 | 54 | * They'll then show up and sync in Linear 55 | 56 | ### Remove "Public" label for private issues 57 | 58 | * For sensitive issues in Linear (such as userdata or security issues), remove the "Public" label 59 | 60 | ### Raycast App: [https://www.raycast.com/raycast/linear](https://www.raycast.com/raycast/linear) 61 | 62 |
63 | 64 | ## **Linear** Issue vs Discussion 65 | 66 | Our [Issues](https://github.com/calcom/cal.com/issues) should only include **code-related issues.** 67 | 68 | {% embed url="https://www.loom.com/share/1a632ac5341f4a1cb0182fb45cabdd76?t=3" %} 69 | -------------------------------------------------------------------------------- /engineering/https-and-subdomains.md: -------------------------------------------------------------------------------- 1 | # 🌐 HTTPS & Subdomains 2 | 3 | Since we’re going to start using cross-subdomain authentication it’s pretty important that we can test both `https://app.cal.localhost` and `https://cal.localhost` locally. This is a quick guide on how can we achieve this setup locally for development purposes. 4 | 5 | ## Prerequisites 6 | 7 | * Caddy Server 8 | * Dnsmasq 9 | 10 | ### Install Dnsmasq 11 | 12 | ```bash 13 | brew install dnsmasq 14 | ``` 15 | 16 | ### Configure Dnsmasq to resolve \*.localhost domains 17 | 18 | First let’s check where our brew installation config files are: 19 | 20 | ```bash 21 | $ brew --prefix 22 | /opt/homebrew 23 | ``` 24 | 25 | In my case it lives at `/opt/homebrew/etc/dnsmasq.conf` 26 | 27 | ```bash 28 | # Route all *.localhost addresses to localhost 29 | address=/localhost/127.0.0.1 30 | 31 | # Don't read /etc/resolv.conf or any other configuration files. 32 | no-resolv 33 | 34 | # Never forward plain names (without a dot or domain part) 35 | domain-needed 36 | 37 | # Never forward addresses in the non-routed address spaces. 38 | bogus-priv 39 | ``` 40 | 41 | ### **Run Dnsmasq now and anytime we restart the system** 42 | 43 | ```bash 44 | sudo brew services start dnsmasq 45 | ``` 46 | 47 | ### Make macOS use our local DNS server (Dnsmasq) for .localhost addresses 48 | 49 | Create the following file at `/etc/resolver/localhost`: 50 | 51 | ``` 52 | nameserver 127.0.0.1 53 | ``` 54 | 55 | With that, you can go to `subdomain.localhost` in your browser and it will point to `localhost`. So if your app is running on port `3000`, simply go to `subdomain.localhost:3000`. 56 | 57 | But what if you're looking for the following setup? 58 | 59 | ``` 60 | cal.localhost -> localhost:3001 61 | app.cal.localhost -> localhost:3000 62 | ``` 63 | 64 | This we can solve with [Caddy](https://caddyserver.com/) which is a super-awesome simple HTTP server! 65 | 66 | ### **Install Caddy** 67 | 68 | ```bash 69 | brew install caddy 70 | ``` 71 | 72 | ### **Configure Caddy** 73 | 74 | In my case (because my `brew --prefix` is `/opt/homebrew`), my global Caddyfile is at `/opt/homebrew/etc/Caddyfile`. This file we can setup to act as a simple reverse proxy for our individual apps running on different ports: 75 | 76 |
https://cal.localhost {
 77 |         reverse_proxy localhost:3001
 78 | }
 79 | 
 80 | https://app.cal.localhost {
 81 |         reverse_proxy localhost:3000
 82 | }
 83 | 
84 | 85 | ### **Run Caddy now and every time your system restarts** 86 | 87 | ```bash 88 | brew services start caddy 89 | ``` 90 | 91 | That's it! If you change your Caddyfile, you will need to `brew services restart caddy`. 92 | 93 | ### Setup our your environment variables 94 | 95 | ```bash 96 | NEXTAUTH_URL='https://app.cal.localhost' 97 | NEXT_PUBLIC_WEBAPP_URL='https://app.cal.localhost' 98 | NEXT_PUBLIC_WEBSITE_URL='https://cal.localhost' 99 | NODE_TLS_REJECT_UNAUTHORIZED=0 # Needed so HTTPS doesn't complain locally 100 | ``` 101 | 102 | ### Run website and web app at the same time 103 | 104 | ```bash 105 | yarn turbo run dev --scope="@calcom/web" --scope="@calcom/website" 106 | ``` 107 | 108 | ### Go to the website or web app domain 109 | 110 | You should be able to go to `https://app.cal.localhost` and `https://cal.localhost` successfully 🙌 111 | 112 | Thanks to Max 's article [Local subdomains on macOS with Dnsmasq](https://maxschmitt.me/posts/local-subdomains-dnsmasq-caddy/) and Caddy for making it easy to get started with Dnsmasq. 113 | -------------------------------------------------------------------------------- /engineering/keeping-docs-up-to-date.md: -------------------------------------------------------------------------------- 1 | # 📚 Keeping Docs up-to-date 2 | 3 | To ensure relevance of the documentation we must strictly follow a simple protocol whenever raising a PR.\ 4 | There is a tag in Github that says "Needs documentation update", and looks like the following:\ 5 | 6 | 7 |

Documentation update tag

8 | 9 | Please follow these steps in your PRs from now on: 10 | 11 | 1. If you're working on a new feature, please make sure to add the "Needs Documentation Update" tag to the PR. 12 | 2. If you're working on an existing feature, please visit the Docs and confirm that the documentation is consistent with the changes you're making. If not, please add the "Needs Documentation Update" tag to the PR. 13 | 14 | For each PR where you place "Needs Documentation Update" tag, please make note of adding a Loom Video explaining the exact changes and how-to guide. Alternatively, you can write up the changes in as much detail as possible so that the docs can be updated to match the latest changes. 15 | -------------------------------------------------------------------------------- /engineering/managing-notifications.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | We rely on GitHub on our daily basis, here are some recommendations to keep on 4 | top of your notifications. 5 | --- 6 | 7 | # 🔔 Managing Notifications 8 | 9 | * Download [Neat.run](https://neat.run) 10 | 11 | **On Neat.run:** 12 | 13 | * On the bottom right corner, open controls:![](<../.gitbook/assets/image (15).png>) 14 | * Make sure to add the following filters to prevent too much clutter:\ 15 | ![](<../.gitbook/assets/image (21).png>) 16 | * Feel free to add more muted items if necessary, be careful to not mute too much or your might miss important mentions or notifications. 17 | 18 | **On GitHub:** 19 | 20 | * On the Cal.com repo, make sure you're subscribed to "Participating and mentions" notifications\ 21 | ![](<../.gitbook/assets/image (20).png>) 22 | * Go to your [account notification settings](https://github.com/settings/notifications), be sure to toggle off emails and leave only GitHub on:\ 23 | ![](<../.gitbook/assets/image (3).png>) 24 | * Go to [email settings](https://github.com/settings/emails) and select "Only receive account related emails, and those I subscribe to."\ 25 | ![](<../.gitbook/assets/image (23).png>) 26 | 27 | This should leave you with a cleaner email inbox, feel free to add more suggestions or to update existing tips. 28 | -------------------------------------------------------------------------------- /engineering/pr-reviews.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: How we review Pull Requests at Cal.com 3 | --- 4 | 5 | # ✅ PR Reviews 6 | 7 | ### Auto-update and auto-merge 8 | 9 | **How we use kodiak bot to auto-update and auto-merge approved PR's.** 10 | 11 | You will notice some PR's have the **`autoupdate`** and **`automerge`** tags assigned, those make sure that the PR is fresh and rebased automatically to main or whatever branch is based too, and the automerge one, will automatically merge the PR once it has the minimum required approval reviews (1). 12 | 13 | {% hint style="danger" %} 14 | Please do a thorough review and test the code, before approving, as it will get probably auto-merged once you do so. 15 | {% endhint %} 16 | 17 | We wouldn't want to merge stuff that hasn't been tested properly to main, and the PR might have one of such tags that would do so, so please don't approve before running the code and testing the bug has been fixed or the feature works as expected. 18 | 19 | ### What to look for? 20 | 21 | You can rely on the tools we already have, like all `github checks` being green on `types`, `eslint`, `e2e tests` and other tools. 22 | 23 | First of all, if you're dealing with any bug fix, make sure that you're able to reproduce the fix (and maybe the prior bug in main too), and that there are not any other edge cases that the author might have missed. 24 | 25 | Read the code changes, and try to think if the logic updates makes sense, or is there any other changes that could also improve it. Always try to simplify, don't overdo it though. Don't extract code until necessary. 26 | 27 | If you see anything you think could be improved, make a comment on that line, open a discussion about it and the author will resolve it either fixing it or providing their reasoning for their option. 28 | 29 | ### Drafts 30 | 31 | If your PR is not ready yet for review, please keep the `draft` tag in it until it's ready, once you're happy with your work, move it out of draft and ask for review either to a teammate specifically (if you know they're already familiar with that part of the codebase, or else) or you can tag `calcom/core` or `calcom/reviewers` team which will pick someone randomly for the team and notify them. 32 | 33 | Likewise, don't review any PR's that are on `draft` status, as they might not be yet ready for your excellent feedback! 34 | 35 | It's possible that either as part of `calcom/core` or `calcom/reviewers` team, or because a teammate has tagged you personally, they'll show up in your github review requests page. 36 | 37 | [https://github.com/pulls/review-requested](https://github.com/pulls/review-requested) 38 | 39 | ### 40 | -------------------------------------------------------------------------------- /engineering/resolving-failed-migration-on-vercel-preview.md: -------------------------------------------------------------------------------- 1 | # 🔺 Resolving failed migration on Vercel Preview 2 | 3 | We currently use a single DB for all preview deployments corresponding to various branches. (There is on going work to have different DB per branch. This approach would still remain applicable as repeat deployments of same branch would fail.) 4 | 5 | Sometimes, a faulty migration in one of those in progress branches, can fail which can start failing all builds of other branches as well. 6 | 7 | ![A sample failure on Vercel build.](<../.gitbook/assets/Screenshot 2022-07-15 at 10.41.55 AM (1).png>) 8 | 9 | #### Steps to fix the issue 10 | 11 | * Get the name of the failed migration(e.g. in the above case it is _20220714175322\_destination\_calendar\_one\_to\_many\_bookings_) 12 | * Go to **prisma** folder in the repo. Modify DATABASE\_URL temporarily to Preview DB. You can get the credentials from Vercel Environment Variables(Preview). _It might be a good idea to have that variable remain there as commented, so that you can easily switch_ 13 | * Once, you have ensured that, DATABASE\_URL is updated, run following command from prisma folder `yarn prisma migrate resolve --rolled-back 20220714175322_destination_calendar_one_to_many_bookings`. This should fix the rollback the failed migration ensuring all other branches deploy fine. 14 | * Note that the branch having the issue should fix the migration problem to avoid this issue from coming again and again. 15 | -------------------------------------------------------------------------------- /engineering/self-reviews.md: -------------------------------------------------------------------------------- 1 | # ☑ Self-reviews 2 | 3 | {% embed url="https://www.loom.com/share/48b98a9e279e4f03996de89372b0e9cf" %} 4 | A guide to PR self-reviews 5 | {% endembed %} 6 | 7 | ## Key points 8 | 9 | * Use the changed files tab to ensure the diff looks correct, and that there are no unintended changes added onto your PR 10 | * Use the review feature to add GitHub comments in the diff, so that other engineers can understand your PR more easily 11 | * Make sure you assign a few reviewers once you are complete 12 | 13 | ### Examples 14 | 15 | * If the Tailwind formatter changed the order of a ton of classes in the code as part of your PR, adding a review comment letting the other engineers that this is an automated reorder of classes and that you didn't add/modify any classes yourself 16 | * Explain caveats and drawbacks of your solution 17 | -------------------------------------------------------------------------------- /engineering/valuable-bookmarks.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: A list of valuable bookmarks for GitHub filters 3 | --- 4 | 5 | # ⭐ Valuable Bookmarks 6 | 7 | ### For Product: 8 | 9 | * [Needs Prioritization ](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+no%3Amilestone+-linked%3Apr+-label%3A%22Low+priority%22+-label%3A%22Medium+priority%22++-label%3A%22High+priority%22++-label%3A%22%F0%9F%9A%A7++wip+%2F+in+the+making%22+) 10 | * [Stale Issues](https://github.com/calcom/cal.com/issues?q=is:issue+is:open+sort:updated-desc+label:Stale+) 11 | * [No Area of Expertise](https://github.com/calcom/cal.com/issues?q=-linked%3Apr+is%3Aissue+is%3Aopen+sort%3Aupdated-desc+-label%3ACI+-label%3A%22platform%22++-label%3A%22crm-apps%22++-label%3A%22calendar-apps%22+-label%3Adocs+-label%3A%22automated-tests%22+-label%3A%22event-types%22+-label%3Aapi+-label%3Aavailability+-label%3Abookings+-label%3Aanalytics+-label%3Abilling+-label%3Aauthentication+-label%3A%22booking-page%22+-label%3Acaldav+-label%3Adst+-label%3Aemails+-label%3Aembed+-label%3A%22event-types%22+-label%3Ai18n+-label%3Aperformance+-label%3Aworkflows+-label%3Awebhooks+-label%3Aui+-label%3Aseats+-label%3A%22routing-forms%22+-label%3A%22organizations%22+-label%3Aself-hosting+-label%3Ateams+-label%3A%22app-store%22+-label%3A%22%F0%9F%9A%A7++wip+%2F+in+the+making%22+-label%3A%22%E2%9D%93+needs+spec%22++no%3Aassignee+) 12 | * [High Priority but unassigned, unlinked](https://github.com/calcom/cal.com/issues?q=is:issue+is:open+sort:updated-desc+no:assignee+-linked:pr+label:%22High+priority%22) 13 | * [PRs without Priority](https://github.com/calcom/cal.com/pulls?q=is:pr+is:open+sort:updated-desc+-label:Urgent+-label:%22Low+priority%22+-label:%22High+priority%22+-label:%22Medium+priority%22+-label:%22%F0%9F%9A%A7++wip+/+in+the+making%22+draft:false) 14 | 15 | ### For Engineering: 16 | 17 | * [Review Required](https://github.com/calcom/cal.com/pulls?q=is:pr+is:open+review:required+draft:false) 18 | * [Open non-draft PRs without changes requested](https://github.com/calcom/cal.com/pulls?q=is:pr+is:open+archived:false+draft:false+-review:changes\_requested+sort:created-asc) 19 | * [Approved PRs but unmerged](https://github.com/calcom/cal.com/pulls?q=is:pr+is:open+archived:false+draft:false+sort:created-asc+review:approved) 20 | 21 | ### Per Engineer: 22 | 23 | * [Ali](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Aalishaz-polymath) 24 | * [Carina](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3ACarinaWolli) 25 | * [Alex](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Aemrysal) 26 | * [Hariom](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Ahariombalhara) 27 | * [Eric](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Aericrommel) 28 | * [Joe](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Ajoeauyeung) 29 | * [Sean](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Asean-brydon) 30 | * [Udit](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3AUdit-takkar) 31 | * [Zomars](https://github.com/calcom/cal.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+assignee%3Azomars) 32 | -------------------------------------------------------------------------------- /engineering/what-to-do-during-emergencies.md: -------------------------------------------------------------------------------- 1 | # 🔥 What to do during Emergencies 2 | 3 | {% embed url="https://media0.giphy.com/media/QMHoU66sBXqqLqYvGO/giphy.gif?cid=790b7611d6ef2df86bbca97e2e4410e27265a17d524f2ad7&ct=g&rid=giphy.gif" %} 4 | 5 | We've recently experienced a DDoS attack, but an emergency can also be a faulty code change or unexpected downtime (Vercel, AWS, ...) 6 | 7 | 1. Keep a cool head 8 | 2. Gather as much information and open a thread titled: "\[Outage]: XYZ" 9 | 3. Research the Primary and Secondary Owners (see Areas of Expertise: [https://cal.com/open](https://cal.com/open)) 10 | 4. If you are an owner, expect to drop whatever you are doing right now. 11 | * If you are working on an equally important ticket or are OOO, find another expert. 12 | * If you’re unsure of which task has more priority, contact **Bailey**, **Peer**, **Keith**, **Ciarán** 13 | * If you do not have access to prod and suspect it will be needed to resolve the issue, contact **Peer**, **Bailey**, **Keith**, **Zomars**, **Alex**, **Morgan** or **Erik** immediately. 14 | 5. Update the [cal.com-status-page.md](cal.com-status-page.md "mention") to inform users that we are investigating a reported outage and inform leadership, support and marketing teams to post on Twitter and Slack. 15 | 6. **Important: Our primary objective is to restore service to our users quickly.** Even before looking for root cause, ask yourself, "would a rollback to the previous version of Cal.com potentially fix this issue and not cause other problems?" 16 | * If rolling back seems like a legitimate option to restore service and there will not be other negative side effects (e.g. rolling back introduces other critical bugs that have been fixed) do the rollback and see if service is restored. 17 | * Example: A revert of [https://github.com/calcom/cal.com/pull/12019](https://github.com/calcom/cal.com/pull/12019) is what ultimately restored service for our booking page issues in negative UTC offset regions on October 23-24, 2023. Finding that this was the culprit was quite challenging due to other circumstances regarding idle DB connections and Cloudflare outages but it's a good reminder that by asking ourselves the question of "can we just rollback to the previous version" before trying to going deep to find the root cause, we might be able to bring service back to our users faster. 18 | * If a rollback is not a legitimate option, start to research root cause. 19 | 7. Once the root cause is found, update [cal.com-status-page.md](cal.com-status-page.md "mention") to inform users that we are currently working on a fix. 20 | 8. Keep the Threads thread up-to-date on all steps that have been taken, so other people know what to search for. 21 | * e.g. "Database not affected, just checked the logs" 22 | * e.g. "Vercel is reporting a downtime, see https://vercel-status.com" 23 | * e.g. "I can reproduce the issue locally, I am now rolling-back our last commit" 24 | 9. If you are approaching end-of-the-day and the problem is still ongoing, find a new owner and explain what steps you would've tried next. 25 | 10. Once service has been restored, update [cal.com-status-page.md](cal.com-status-page.md "mention") to inform users and update the Thread with the verification steps you took to ensure service was restored. 26 | * We need to see what was checked as part of giving the green light that everything is back to normal so that in the event everything is **not** actually back to normal or if the outage arises again, we'll be able to add further verification steps to ensure service is restored. 27 | 11. Keep a cool head. This too shall pass. 28 | -------------------------------------------------------------------------------- /hr-and-careers/bonus-and-equity-structure.md: -------------------------------------------------------------------------------- 1 | # 💸 Bonus & Equity Structure 2 | 3 | #### **Equity Retainers** 4 | 5 | **Definition:** Equity retainers represent a portion of company ownership or stock that is provided to employees as a reward and incentive. 6 | 7 | **Our Approach:** We believe in rewarding those who have committed their time, effort, and expertise to our company. Our equity retainers are not just random handouts; they're a reflection of your loyalty and continuity within the company. 8 | 9 | 1. **Time-Based Allocation:** The longer you are with us, the higher your equity retainer. Your retainer will be calculated based on the cumulative time you spend with the company. This is to ensure that those who have been with us through thick and thin, weathering the ups and downs, are aptly rewarded. 10 | 2. **Periodic Evaluation:** We conduct reviews at our discretion of all equity retainers to ensure that they are in line with our company's objectives and your personal contribution. 11 | 12 | *** 13 | 14 | #### **Payout** 15 | 16 | **Definition:** Payout refers to a special financial reward given to employees when the company achieves a specific revenue milestone. 17 | 18 | **Our Approach:** Success is sweeter when celebrated together. Every time we achieve a significant revenue milestone, we recognize and reward those who have played a pivotal role in reaching that goal. 19 | 20 | 1. **Celebration of Success:** Revenue milestones are a testament to our collective hard work. To mark these achievements, we distribute a payout to our top performers. 21 | 2. **Periodic Evaluation:** Our leadership team will periodically evaluate our revenue targets and the associated payouts to ensure that they are competitive and reflect the company's trajectory and market conditions. 22 | 23 | *** 24 | 25 | #### **Payrise** 26 | 27 | **Definition:** A payrise is an increase in an employee's regular salary, typically awarded for exceptional performance or as part of a periodic review. 28 | 29 | **Our Approach:** We believe in recognizing and compensating talent appropriately. Payrises in our company are a reflection of your commitment, talent, and contribution to our shared goals. 30 | 31 | 1. **Performance-Based Increments:** Your performance is the primary criterion for receiving a payrise. We conduct regular performance reviews, and those who consistently meet or exceed expectations are considered for salary increments. 32 | 2. **Bi-annual Reviews:** Every employee will have a bi-annual salary review where their pay, performance, and potential future contributions are assessed. 33 | 3. **Market Competitiveness:** Apart from performance, we also periodically review our salary structures in relation to market standards. This ensures that our pay scales are competitive and that we continue to attract and retain the best talent. 34 | 35 | *** 36 | 37 | At Cal.com, we are committed to fostering a culture of recognition and reward. Our policies around equity retainers, payouts, and payrises are crafted to ensure that each member of our team feels valued and motivated to contribute their best to our collective success. If you have any questions, please do not hesitate to reach out. 38 | -------------------------------------------------------------------------------- /hr-and-careers/contract-to-hire-trials.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: aka Lean Hire 3 | cover: >- 4 | https://images.unsplash.com/photo-1521791136064-7986c2920216?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwxOTcwMjR8MHwxfHNlYXJjaHw4fHxoYW5kc2hha2V8ZW58MHx8fHwxNjU1MDY0ODg2&ixlib=rb-1.2.1&q=80 5 | coverY: 0 6 | --- 7 | 8 | # 👷 Contract-to-hire trials 9 | 10 | At [Cal.com](https://cal.com/), we take a very different approach to hiring. Most of our full time employees will be preceded in a 30 day contract-to-hire trial period. A contract will be administered for a 30 day period with the company, and then at the end of the contract a final decision will be made on whether the person will be brought on full time. 11 | 12 | A lot of people ask (for very good reason) what “success” looks like during the trial. The trial is less about “showing why you should join” and more like “finding reasons why you shouldn’t join” 13 | 14 | If we extend an offer as a trial, we do it because we think you could be a great addition to the team. The trial is the last step to show both to you and the team if there are any red flags **while** working on the team. 15 | 16 | Don’t feel like you need to be excellent only during the trial. See this as some sort of dating: be you, authentic, real. 17 | 18 | The trial is more about you than us: it’s your chance to work without committing immediately. Your job is to figure out: 19 | 20 | Do I like … 21 | 22 | * the mission? 23 | * the code base? 24 | * my team members? 25 | * working with the founders? 26 | * the market? 27 | * building in public? 28 | * working async? 29 | * threads and looms? 30 | * wearing pyjamas? 31 | 32 | Lastly, for us it’s a chance to get to know you too, before extending a proper contract. Why? Because it is terrible for everyone, if we poach you from your existing employer, sign you into a yearly commitment, and then you (or us) figure out it’s not a good fit. 33 | 34 | The bad outcome: you left your existing job and took a big risk without any upside. 35 | 36 | We hate firing. Every company does. By discontinuing a LeanHire trial it feels a bit less shitty because you haven’t fully committed yet. 37 | 38 | Like dating, it’s perfectly fine to part ways after the second week. 39 | 40 | TLDR: 41 | 42 | * a lean hire has no “goal” in a sense of “success” 43 | * it is a tool for you to look behind the scenes faster 44 | * discontinuing should feel less bad as firing (still sucks, I know 😞) 45 | -------------------------------------------------------------------------------- /hr-and-careers/ic-levels/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1573497620053-ea5300f94f21?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwxOTcwMjR8MHwxfHNlYXJjaHw3fHx3b3JrfGVufDB8fHx8MTY1NTA2NDkwMg&ixlib=rb-1.2.1&q=80 4 | coverY: 0 5 | --- 6 | 7 | # 🏆 IC Levels 8 | 9 | When you work at Cal.com, you will have an assigned **IC level**. These are often posted in our job listings and can be found on the employee list at cal.com/open. 10 | 11 | IC levels range from 1 to 4, and determine the pay band and responsibilities you have within the company. 12 | 13 | One of the reasons behind clearly defined pay bands is that **we pay everyone equally**, no matter where they come from or any other demographics. For this reason, **we don't allow salary negotiation** or individual 'deals' when it comes to employment and instead stand firmly behind equal pay. 14 | 15 | {% hint style="info" %} 16 | **For example:** 17 | 18 | Somebody who's doing the same job as you in India whilst you are in San Francisco does not mean that the person from India should be paid less than you because they have a lower cost of living. Hence, if you're on the same IC band, then you're compensated the same both in salary and equity as anyone else in your band. 19 | {% endhint %} 20 | -------------------------------------------------------------------------------- /hr-and-careers/ic-levels/engineering-levels/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1502101872923-d48509bff386?crop=entropy&cs=srgb&fm=jpg&ixid=M3wxOTcwMjR8MHwxfHNlYXJjaHwyfHxzdGFpcnN8ZW58MHx8fHwxNjk5Mjk2OTkwfDA&ixlib=rb-4.0.3&q=85 4 | coverY: 0 5 | --- 6 | 7 | # ⛰ Engineering Levels 8 | 9 | ### Base expectations for all engineers at any level 10 | 11 | * **You are doing the responsibilities of areas where you are Primary or Secondary owner (see** [**cal.com/open**](https://cal.com/open)**).** 12 | * Staying on top of the errors occurring in your areas. You need to make sure your alerts and notifications are properly configured so you immediately know when critical errors happen. It's a bad sign if a customer alerts a severe problem before we know about it. These errors should be addressed quickly and you should coordinate with the team to get them shipped efficiently. 13 | * You are shaping the technical backlog for your areas. You need to maintain a list of improvements, refactors and fixes that should happen in your areas. Working collectively with Head of Product and Head of Engineering, you ensure these items are properly slotted in when appropriate. 14 | * Typically this best happens when feature work happens or bugs are fixed in the same area where technical changes are needed. 15 | * If you are a lower IC level and feel less comfortable in this area, please reach out to senior engineers for guidance. 16 | * **You are active in Threads.** 17 | * We thrive on async work but we have folks located in different time zones across the world. A long delay in responding to your teammate could result in them not seeing the message until the next day, resulting in lots of slow back and forth communication. 18 | * For threads you are mentioned directly in, you should actively follow up and give insights where needed. Once initially mentioned, people should not have to feel like they are chasing you down to get a response. 19 | * **You are consistently posting your weekly stand-up in Threads on Monday.** 20 | * We intentionally don't have daily stand-ups to avoid lots of meetings but we all need to be aware of what each other is working on so work can properly be prioritized and planned. Not posting your weekly stand-up hinders the team's ability to working efficiently in an async manner. 21 | * **You write code that is tested.** 22 | * You should not be introducing code that isn't backed by some level of automated tests. It's risky and prevents us from building stable systems. If you need assistance getting new code under tests, reach out to more senior engineers for help. 23 | 24 | ### What does a higher IC level entail? 25 | 26 | * A common misconception with IC levels here is that people expect that they should aim to move up to the highest band because then that means they're the best. This is not correct as IC bands are based on responsibilities in the team. Higher IC bands usually consist of more management-related responsibilities and high-level engineering tasks, whereas lower levels focus more on building new features, fixing bugs and doing PR reviews. 27 | * As a result of this, we encourage you to look at what each IC band means and consider whether you would prefer a role where you can focus on getting code written, or if you want to move up to higher levels, where you'll then be expected to lead others on the team, research, design systems, document and more. 28 | * **IC levels do not determine the complexity of code that you work on.** Although higher IC levels tend to focus on the more foundational code, lower IC levels have an equal opportunity to work on core or complex parts of the code, but there is less of a responsibility to design, document and evolve it. 29 | 30 | {% content-ref url="ic1-engineer-code-cadet.md" %} 31 | [ic1-engineer-code-cadet.md](ic1-engineer-code-cadet.md) 32 | {% endcontent-ref %} 33 | 34 | {% content-ref url="ic2-engineer-code-craftsperson.md" %} 35 | [ic2-engineer-code-craftsperson.md](ic2-engineer-code-craftsperson.md) 36 | {% endcontent-ref %} 37 | 38 | {% content-ref url="ic3-engineer-code-connoisseur.md" %} 39 | [ic3-engineer-code-connoisseur.md](ic3-engineer-code-connoisseur.md) 40 | {% endcontent-ref %} 41 | 42 | {% content-ref url="ic4-engineer-code-wizard.md" %} 43 | [ic4-engineer-code-wizard.md](ic4-engineer-code-wizard.md) 44 | {% endcontent-ref %} 45 | -------------------------------------------------------------------------------- /hr-and-careers/ic-levels/engineering-levels/ic1-engineer-code-cadet.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | "I'm in the early stages of my engineering journey, but I'm eager to learn, 4 | write code, and make a difference one issue at a time." 5 | --- 6 | 7 | # 🕵 IC1 Engineer (Code Cadet) 8 | 9 | * **Role**: Junior engineers are essential to our engineering team and play a major role in developing and maintaining our software. 10 | * **Responsibilities**: 11 | * Contribute to code development, adding new features to the software. 12 | * Review Pull Requests 13 | * Fix bugs and contribute across various functionalities. 14 | * Contribute to our team's goal of increasing automated tests (unit, integration and E2E). 15 | * **Ownership**: While IC1s make significant contributions, they have limited formal responsibility of the design and longevity of the software. They sometimes work closely under the guidance of more experienced engineers. 16 | * **Learning:** 17 | * You should be hungry to learn and grow in the software engineering field. This includes lots of research, reading, building PoCs and exploration so you are exposed to new ideas. 18 | * It's ok to ask questions. In fact, we want you to! This is a sign that you are trying to take in as much information as possible to get better. 19 | * Don't wait hours to ask for help if you are stuck on a problem. It will not be looked down upon. Instead, jot down a list of things you've tried so far so you have this to present to the person who are asking help from. 20 | * **Path to IC2 Engineer:** 21 | * **Typical timeframe** 22 | * 1-2 years 23 | * You need to consistently demonstrate skills of an IC2 in order to be promoted. 24 | * **Expand your skill set** 25 | * Become more of an expert in the code base and contribute to larger projects. 26 | * Write code that is solid. No obvious bugs should come out of your code. 27 | * **Show initiative** 28 | * Demonstrate your ability to tackle more complex problems and take on leadership responsibilities within your team. This might involve mentoring other junior engineers, providing technical guidance, or helping with project planning. 29 | -------------------------------------------------------------------------------- /hr-and-careers/ic-levels/engineering-levels/ic2-engineer-code-craftsperson.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | "I'm in the sweet spot of my career, designing features that solve real 4 | problems and shaping the future of our software." 5 | --- 6 | 7 | # 👷♀ IC2 Engineer (Code Craftsperson) 8 | 9 | * **Role**: Engineers at this level are expected to delve deeper into the foundational code and provide leadership in project development. 10 | * **Responsibilities**: 11 | * Design, implement, and maintain software systems and components. 12 | * Lead larger projects independently. 13 | * Take full ownership and responsibility for designated projects and functionalities. 14 | * **Leadership**: IC2s not only contribute but also guide and help in the growth of IC1s, but they serve as points of reference for certain projects or modules. 15 | * **Learning:** You should be diving into more complex concepts like design patterns, IoC, safe refactoring, introduction of seams, architectural patterns, etc. 16 | * **Expertise**: You're now producing more solid code. The beginner mistakes you used to make are now fading away as you hone your craft. 17 | * **Path to IC3 Engineer:** 18 | * **Typical timeframe** 19 | * 2-4 years 20 | * You need to consistently demonstrate skills of an IC3 in order to be promoted. 21 | * You do **not** need to work on **Foundation** team to move to IC3. 22 | * **Lead by example** 23 | * Be a role model for junior and mid-level engineers by consistently delivering high-quality work, following best practices, and actively participating in code reviews and knowledge sharing. 24 | * **Initiate and drive projects** 25 | * Take the initiative to propose and lead technical projects that will have a substantial impact on the team. This demonstrates your ability to set and achieve technical objectives. 26 | * **Deepen technical expertise** 27 | * Continue to expand your technical knowledge and expertise in your chosen domain. Specialize in areas that are relevant to our team and company's goals. 28 | -------------------------------------------------------------------------------- /hr-and-careers/ic-levels/engineering-levels/ic3-engineer-code-connoisseur.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | "I've come a long way in my journey, and now I'm leading projects, making 4 | architectural decisions, and helping the next generation of engineers." 5 | --- 6 | 7 | # 🧘♀ IC3 Engineer (Code Connoisseur) 8 | 9 | * **Role**: IC3s are the backbone of our engineering efforts, holding ultimate responsibility for critical parts of our infrastructure and application. 10 | * **Responsibilities**: 11 | * Handle and solve complex backend logic tasks. 12 | * Plan, build and maintain complex features. 13 | * Tackle technical debt to help the team build more efficiently. 14 | * Be a mentor to your teammates. When they are stuck, you should proactively help them push work to completion. 15 | * Ensure application uptime and be the primary point of contact during application downtimes. (DevOps realm) 16 | * Oversee and manage the build pipeline and database structures. (DevOps realm) 17 | * **Learning:** 18 | * IC3 engineers should now start learning about how to help other engineers be more productive. 19 | * They should actively research new technologies, architectural and design patterns, examine trade-offs for long-term technical decisions. 20 | * **Expertise**: 21 | * IC3s possess top-tier TypeScript knowledge and know our code very deeply. 22 | * They are specialists in timezone logic, Prisma and our deployments. 23 | * They are often called upon for tasks that require deep technical expertise and understanding. 24 | * Their code is clean, tested and easily extended. 25 | * **Path to IC4:** 26 | * **Typical timeframe** 27 | * 1-3 years 28 | * You need to consistently demonstrate skills of an IC4 in order to be promoted. 29 | * You do **not** need to work on **Foundation** team to move to IC4. 30 | * **Lead complex initiatives** 31 | * Take ownership of complex, company-wide technical initiatives, and demonstrate your ability to plan, lead, and successfully deliver them. 32 | * Example: Our production database is in us-east-2 but our serverless functions are in us-east-1, causing a system-wide reduction in performance. What do we do? 33 | * **Mentorship and leadership** 34 | * Continue to mentor and coach engineers at all levels, but also become more involved in actively sharing your expertise with a wider audience. 35 | * Example: Share books you've been reading, post interesting threads about new technologies, explain in detail a recent technical decision you've made and why. 36 | * **Technical strategy and architecture** 37 | * Play a significant role in shaping the technical strategy, architecture, and design of major projects and potentially influence the direction of the organization's technology stack. 38 | -------------------------------------------------------------------------------- /hr-and-careers/ic-levels/engineering-levels/ic4-engineer-code-wizard.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | "I'm the wizard behind the code, conjuring up solutions to the most 4 | challenging problems and guiding our technical vision into the future." 5 | --- 6 | 7 | # 🧙♂ IC4 Engineer (Code Wizard) 8 | 9 | * **Role**: IC4s lead from the front, guiding the entire engineering team and working closely with collaborators from outside the company. 10 | * **Responsibilities**: 11 | * Mentor and guide team members across all IC levels. 12 | * Collaborate with external partners and lead integration projects with companies such as Prisma, BoxyHQ, and tRPC. 13 | * Work closely with Head of Engineering to drive technical roadmaps. 14 | * Respond to application alerts extremely quickly and ensure we are striving towards extremely high uptime. 15 | * **Leadership**: 16 | * IC4s are not just experts in their field but are also responsible for the growth and direction of the engineering team. 17 | * Be the rock the team needs when things are on fire. Your ability to demonstrate calmness and composure during difficult outages will go a long way in bringing the team together to quickly resolve the issue. 18 | * **Expertise**: 19 | * There's no problem they can't solve. 20 | * They know our tech like the back of their hand. 21 | * Their code is practically flawless. 22 | * They expertly design functions, classes and modules such that they are easily testable with unit and integration tests. 23 | * Other engineers easily understand their code and can extend it with little-to-no complications. 24 | -------------------------------------------------------------------------------- /hr-and-careers/onboarding.md: -------------------------------------------------------------------------------- 1 | # 🛫 Onboarding 2 | 3 | * Sign Deel Contract 4 | * Sign NDA 5 | * Compliance will invite you to 6 | * Threads.com 7 | * Linear.com 8 | * Ramp.com 9 | * GitHub.com 10 | 11 | **Employee Accounts** 12 | 13 | Leadership can request for a new hire to be set up and a departing employees account to be closed using the following forms: 14 | 15 | New User: [https://forms.gle/tSXrxHWNgW8XwX816](https://forms.gle/tSXrxHWNgW8XwX816) 16 | 17 | User Removal: [https://forms.gle/p9qzQJcYWzd63iiS6](https://forms.gle/p9qzQJcYWzd63iiS6) 18 | 19 | **Require access to a particular system or application?** 20 | 21 | When requiring access to a system or application, you can use the following form which will go through to our compliance team: 22 | 23 | [https://forms.gle/5oL3R865nYWf4Fu36](https://forms.gle/5oL3R865nYWf4Fu36) 24 | -------------------------------------------------------------------------------- /hr-and-careers/sharing-your-views.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1555848962-6e79363ec58f?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwxOTcwMjR8MHwxfHNlYXJjaHw0fHxwb2xpdGljc3xlbnwwfHx8fDE2NTUwNjQ5MjM&ixlib=rb-1.2.1&q=80 4 | coverY: 0 5 | --- 6 | 7 | # 💡 Sharing your views 8 | 9 | Discussions about your views about politics, religion, ethics or anything similar can be quite a controversial thing in the workplace. For instance, some of you may have seen the "No Politics" policy of Coinbase announcement two years ago: [https://blog.coinbase.com/coinbase-is-a-mission-focused-company-af882df8804](https://blog.coinbase.com/coinbase-is-a-mission-focused-company-af882df8804) 10 | 11 | We're trying to keep this as simple as possible, so we've laid out some core principles that we believe in that you should be following at Cal.com: 12 | 13 | * The workspace is fundamentally a place to work, and we want the work to be meaningful, with the least amount of distractions 14 | * We are inclusive of all genders, looks, religions, and political opinions **as long as** their opinions are inclusive as well 15 | * We **do not tolerate intolerance** such as hate speech or anything fringe that makes people feel uncomfortable (read: the paradox of tolerance [https://en.wikipedia.org/wiki/Paradox\_of\_tolerance](https://en.wikipedia.org/wiki/Paradox\_of\_tolerance)) 16 | * The company itself has no political agenda (neither left, nor right, nor centrist) other than a humanist approach: offer a workspace of **dignity**, **respect**, **fairness,** and **inclusivity** 17 | * You are welcome to celebrate and talk about your religion and beliefs with us as long as it is respectful to others and their views. 18 | * We are a team that is spread out into many many countries and most people are only politically active within their own country (sometimes only their district). Would you really care if Peer posts a lot about Germany's elections or if Bailey spends his time arguing about Britain's latest policies? Probably not. 19 | * We want to offer a workspace where you have enough time for yourself. Time for hobbies, time for physical and mental health, time for friends, time for gaming, whatever your passion is, but also time for political and religious activities. 20 | 21 | > #### **TLDR:** 22 | > 23 | > * we tolerate everything but intolerance 24 | > * we ask you to spend time campaigning outside of the workspace 25 | > * **focus on connecting 1B people by 2031** – that's likely more political impact (reducing bureaucracy, saving time for government appointments, increasing GDP by digitising manual processes) 26 | -------------------------------------------------------------------------------- /marketing/how-to-add-a-new-tip-to-sidebar.md: -------------------------------------------------------------------------------- 1 | # ☝ How to add a new Tip to Sidebar 2 | 3 | ### What's a Tip? 4 | 5 | ![](<../.gitbook/assets/image (12).png>) 6 | 7 | 1. Edit [https://github.com/calcom/cal.com/blob/main/packages/features/tips/Tips.tsx](https://github.com/calcom/cal.com/blob/main/packages/features/tips/Tips.tsx) 8 | 2. add a new {object} 9 | 3. increase id by one 10 | 4. create a new youtube thumbnail [https://img.youtube.com/vi/\/0.jpg](https://img.youtube.com/vi/60HJt8DOVNo/0.jpg%22,) 11 | 5. copy youtube link 12 | 6. add title and description 13 | 7. select "Create a new branch for this commit and start a pull request." 14 | 8. create a new PR 15 | 16 | {% embed url="https://www.loom.com/share/d41a0bd858fa4da388a983dc68f7cce0" %} 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /marketing/media.md: -------------------------------------------------------------------------------- 1 | # 🎬 Media 2 | 3 |
LinkPublisher
https://venturebeat.com/2022/04/18/open-source-calendly-rival-cal-com-raises-25m/VentureBeat
https://venturebeat.com/2021/12/21/open-source-calendly-alternative-cal-com-promises-greater-data-control/VentureBeat
https://gritdaily.com/cal-com-raises-25-million-in-series-a-funding-to-bring-order-to-the-chaos/Grit Daily
https://www.cbinsights.com/research/cal-com-competitors-calendly-chili-piper-commanddot-doodle/CB Insights
https://domainnamewire.com/2022/01/06/cal-com-raises-7-4-million-after-rebrand/DomainNameWire
https://techacute.com/calcom-open-source-app-meeting-scheduling/TechAcute
https://hitechglitz.com/open-source-calendly-rival-cal-com-raises-25-million/HiTechGlitz
https://www.vultr.com/docs/how-to-install-self-hosted-cal-on-ubuntu-20-04/Vultr
4 | -------------------------------------------------------------------------------- /policies/communications.md: -------------------------------------------------------------------------------- 1 | # 🗣 Communications 2 | 3 | We use threads.com and gitbook.com for communications. 4 | 5 | Threads.com has: 6 | 7 | * **threads** and 8 | * **group messages** (#General and #Engineering, potentially #Operations and #Marketing later) 9 | * **direct messages** 10 | 11 | **GitBook** has: 12 | 13 | * long-form entries and playbooks 14 | 15 | ### Here's how to know what to use: 16 | 17 | * **things that are only relevant for today** => **group message** in #General / #Engineering 18 | * Example: "hey ESLint is breaking for me, can someone help?" 19 | * **things that are for a week up to a month** => **thread** (see below for etiquette) 20 | * Example: RFCs, Bug Reports, Sales Notes, ... 21 | * **things that are only relevant for one person** => **direct messages** 22 | * Example: "Hey can you book my link for peer programming?" 23 | * **things that are relevant forever and future hires** => **GitBook** 24 | * Example: This entry 25 | 26 | ### The "Thread Police" 27 | 28 | ![](<../.gitbook/assets/image (26).png>) 29 | 30 | One thing we've adopted company-wide is the "Thread Police" 🚓🚓🚓🚓 essentially when a conversation either goes out-of-topic or is too sync-heavy (i.e. too many people chiming in, too many different opinions etc.) we move things into an async thread. 31 | 32 | Threads are more structured and less noisy, async friendly and easier to follow up at a later time. 33 | 34 | Every employee in the team is empowered to share the "Thread Police" emojis :police\_car::police\_car::police\_car: when they feel like something gets out of hand in a group chat. 35 | 36 | Anyone who keeps talking about this topic in the sync chat afterwards goes to async-jail immediately, you do not pass Go and do not collect $200. 37 | 38 | 39 | 40 | ### Threads Best Practices 41 | 42 | 43 | 44 | #### Using Blocks 45 | 46 | Using blocks allows others to reply to specific ideas and/or sections of a thread instead of a large piece of text. Simply hit "enter" to add more blocks. See the example below: 47 | 48 | ![](<../.gitbook/assets/CleanShot 2023-09-27 at 15.19.05@2x.png>)[\ 49 | ](https://twitter.com/peer\_rich/status/1706677503136280888)[\ 50 | ](https://twitter.com/peer\_rich/status/1706677416993620440) 51 | -------------------------------------------------------------------------------- /policies/expenses.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1554224155-6726b3ff858f?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwxOTcwMjR8MHwxfHNlYXJjaHwzfHxhY2NvdW50aW5nfGVufDB8fHx8MTY1MzQ4OTg0Mg&ixlib=rb-1.2.1&q=80 4 | coverY: 0 5 | --- 6 | 7 | # 💳 Expenses 8 | 9 | This policy applies to all our employees that need to spend money on work-related activities/items. The idea of this policy is to keep it simple, rather than have a 3000 word that nobody can actually understand. Hence, if something isn’t clear, clarify it with Bailey before spending.\ 10 | 11 | 12 | Everything should be charged to the appropriate Ramp card. Do not pay for it yourself and reimburse, unless you have approval from Bailey.\ 13 | 14 | 15 | If reimbursement is needed, we will reimburse the mentioned business expenses, after they are approved, in part or in full, depending on their alignment with this policy. 16 | 17 | ## Business trips 18 | 19 | There are two categories of business trip: 20 | 21 | * Job-related trip\ 22 | This type of trip is where you are told by leadership that you are required to travel for business purposes in relation to your job role. This is considered to be a part of your responsibilities, and it’s generally expected for you to attend. 23 | * Optional trip\ 24 | This type of trip is where there is either an open offer posted in a group chat, or you’re directly invited by a member of leadership to join in with a trip. These are completely optional, and there is no pressure to join. 25 | 26 | Pretty much everything when it comes to expense rules depends on which of the above two categories your trip falls under. 27 | 28 | ### Allowed expenses 29 | 30 | These two lists set out the things you’re allowed to expense based on the type of trip. For anything that’s not on this list, seek approval from Bailey before spending. 31 | 32 | #### Job-related 33 | 34 | * Accommodation, if not already arranged for you 35 | * Legal document expenses, such as a visa 36 | * Air, train, ship or other international transportation fares 37 | * Local transportation during the trip 38 | * Other minor or per diem expenses that have been approved by an employee’s manager (e.g. meals, business material) 39 | 40 | #### Optional 41 | 42 | * Accommodation, if not already arranged for you 43 | * Air, train, ship or other international transportation fares 44 | 45 | ### ‘Cheapest viable option’ rule 46 | 47 | All transportation fares, both international and local, are subject to the cheapest viable option rule. This just means using a common-sense approach of going for the cheapest option, unless it’s significantly worse. 48 | 49 | For instance, if Joe wants to fly to New York, it’s cheaper to get to Toronto and just take the one flight from Toronto to New York rather than getting the connecting flight from his nearest city too. But to get to Toronto by bus would take 7 hours, so that’s unreasonable and hence it’s all good to expense the connecting flight direct from his city. 50 | 51 | #### International transportation 52 | 53 | When booking a flight, go to comparison sites (we recommend Skyscanner and Google Flights), and find the cheapest flight to get to your destination. Pick the first and cheapest option, not the airline you want to collect points with :) 54 | 55 | We only allow expensing of economy (or whichever the most basic) class of travel is. None of those $30k Emirates flights where you get an entire room on the plane… 56 | 57 | All tickets include some form of baggage allowance, such as a personal item, and that’s the extent of what we’ll cover, unless we’re requiring you to bring certain things that require extra baggage space. 58 | 59 | You’re more than welcome to purchase additional upgrades and baggage as a separate transaction on your own card. Usually, you can just make the booking under the company card, then on the ‘manage booking’ page, upgrade and use your own card. 60 | 61 | #### Local transportation 62 | 63 | One of the most prominent examples of this is for local transport, where you should be using public transportation. We’re not going to allow expensing an $80 Uber ride when you could have taken the subway for $2.90, for instance.\ 64 | 65 | 66 | Examples where it’s acceptable to go for Uber and other ridesharing apps: 67 | 68 | * If you’re sharing the ride with other coworkers and it is cheaper to pool in one ride 69 | * If you’re transporting company equipment where it’s not practical or safe to do so via public transportation 70 | * If there’s a safety concern (please don’t ride the BART in SF at 2am) 71 | * If public transportation will take significantly longer 72 | 73 | ## Software 74 | 75 | For any SaaS products that are relevant to the entire company, such as SendGrid or Vercel, please talk to Bailey and then use the “Company-wide SaaS” card in Bitwarden.\ 76 | 77 | 78 | For software products that will be used individually, get approval from Bailey. Make sure the product is directly related to your job and yields a benefit in your performance. For instance if you’re a content writer, then Grammarly makes a lot of sense. But if you’re an engineer, you don’t need Grammarly - feel free to misspell all of your GitHub PR descriptions. Just kidding. 79 | 80 | ## Workspace 81 | 82 | The process here is different depending if you’re looking to get furniture or an actual laptop and IT equipment. 83 | 84 | ### IT equipment 85 | 86 | Here you can request equipment: [https://forms.gle/qeLEKrtj2X1yTNaDA](https://forms.gle/qeLEKrtj2X1yTNaDA)\ 87 | 88 | 89 | If you already have a personal device or peripheral that you are willing to use please don't buy a duplicate through Cal.com. 90 | 91 | If you require something which is not listed on the form, please contact compliance@cal.com and each request will be reviewed individually. 92 | 93 | You are only eligible to request equipment if you are a full-time employee and have passed any probationary period (usually a few months after employment). We will place any requests made before this point on hold until you are deemed eligible. 94 | 95 | ### Furniture 96 | 97 | The workplace furniture stipend allows you to purchase a desk and a chair. 98 | 99 | You can only expense fairly simple desks, not one of those huge multi-piece ones that has like 3 full filing cabinets attached to it. 100 | 101 | Chairs are limited to a maximum price of $150. None of those fancy Herman Millers… 102 | 103 | Basically, just go to IKEA and get something reasonable. There’s a Ramp card assigned to you for workplace furniture to use for this. 104 | 105 | ## Education 106 | 107 | You can expense things like courses and books that are directly related to your job or position at Cal.com, including future job positions you may be going for within the company. You can request the purchase of any of these by asking Bailey or Peer. 108 | 109 | ## Uploading your documentation 110 | 111 | Ramp makes it super easy to upload receipts and submit memos for each of your transactions. 112 | 113 | For all transactions above $75 USD, you must upload an invoice. 114 | 115 | For transactions under that limit, we require either an invoice or if it’s obvious by the statement descriptor what it’s for (e.g. Grammarly), then a detailed memo will suffice. If it says something like “Best Buy”, which could be any number of products, we’ll need a receipt. 116 | 117 | If you’re just providing a note, you’ll need to explain precisely what it is, why it is relevant to the business and any further justification. This is important for demonstrating the expense and its necessity to the IRS. 118 | 119 | Please note that invoices have to conform to legal standards and requirements and must have the company name and address printed on it. We can’t accept a piece of paper with “$20 for a bluetooth keyboard” handwritten on it. 120 | 121 | ## Other (obvious) rules 122 | 123 | Here’s a few things that may have been covered in sections above, but are just to outline some of the things it’s important to make clear. 124 | 125 | ### You can’t expense: 126 | 127 | * Anything incurred by spouses or other non-employees 128 | * Unauthorised or unscheduled business meetings with clients, partners or job candidates 129 | * Unauthorised/non-approved service upgrades (e.g. business class or hotel rooms) 130 | * Personal services (beauty treatments etc.) 131 | * Personal purchases (gifts, clothes, etc.) 132 | * Lost personal property (e.g. luggage) 133 | * Baggage oversize or overweight charges 134 | * Fines or penalties 135 | * Personal trips, including if you go and do something for personal enjoyment whilst on a business trip 136 | 137 | Essentially, anything that you only have to pay for due to your own fault, for instance if you damaged a rental car and had to pay, that’s not expensable. 138 | 139 | ### You need to: 140 | 141 | * Document all expenses, including confirmations, receipts, invoices and anything that could be relevant. 142 | * Provide a reason why that expense was necessary 143 | * For transportation, you should explain why you used that method of transportation 144 | * Upload and submit all documentation relating to your expenses within 7 days after the transaction. 145 | 146 | ### Audits and non-compliance 147 | 148 | All transactions and reimbursements are regularly audited to make sure that we’re all in compliance with these rules. We take all of these rules very seriously, because every transaction that you make opens us up to liability with the IRS if the proper documentation isn’t in place. 149 | 150 | Hence, if you’re found not to be in compliance with these rules, not uploading the correct stuff in good time or anything else mentioned here, we will cancel any cards immediately and restrict ability to make future purchases and reimbursements. I want to be focusing on building a billion dollar company, not navigating IRS audits and investigations :) 151 | 152 | \ 153 | -------------------------------------------------------------------------------- /policies/vacations.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1511497584788-876760111969?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=3432&q=80 4 | coverY: 0 5 | --- 6 | 7 | # 🏖 Vacations 8 | 9 | We’ve tried to make our PTO policy as simple as possible. If you’re in a part-time role, contact Peer or Bailey to find out more. We insist that you take your full amount of vacation days! 10 | 11 | | Type | Days per year | Notes | 12 | | ------------------------- | ------------- | ------------------------------------- | 13 | | Personal Days (full time) | 30 | Paid in full. Additional days unpaid. | 14 | | Public holidays | 7 | See list below. | 15 | | Sick days | as you need | Paid in full. | 16 | 17 | ### Recognized Public Holidays 18 | 19 | * Martin Luther King Day 20 | * Memorial Day 21 | * Independence Day 22 | * Labor Day 23 | * Thanksgiving Day 24 | * Christmas Day 25 | * New Years Day 26 | 27 | ## Key points 28 | 29 | 1. Never feel bad for taking time off for being sick, spending time with your family, or any other priority in your life. This is what PTO is for, so make sure you use it :) 30 | 2. Post your OOO in the standups channel with as much notice as possible (if necessary, mention what projects are open and if you need help from someone) 31 | 3. Set your Threads status to "🚫 OOO" to inform your colleagues, and mark yourself OOO as an event in the team calendar 32 | 4. Keep track of your OOO days in a spreadsheet or note-taking app for yourself 33 | 5. We'll occasionally ask you if you've taken any days off as a reminder 34 | 6. Please be mindful of not taking PTO during a high-priority project or immediately after a launch (in case you are needed for debugging). If you do have to be away, then please ensure all knowledge is transferred to someone else in the team so they can effectively cover your position. 35 | 7. We work much like a sports team, and like every other sports team during a game, you can temporarily substitute yourself with another team member, whether you’re going to be away, if you’re struggling or for anything else 36 | 37 | 38 | 39 | ## How to Vacation 40 | 41 | 1. Add to Team Calendar and Copy to Personal Calendar 42 | 2. Put yourself as OOO in Threads 43 | 3. Create a Vacation Auto-Responder (email) 44 | 4. Check with team members in your department on responsibilities that need to be taken care of. 45 | 46 | ### OOO for Only One Day 47 | 48 | If you're out for part of a day, you don't need to block out the specific time in the team calendar (feel free to do so in your personal calendars if you're trying to block meetings). Other notes when going out for the day: 49 | 50 | 1. No need to report anything that's less than three hours 51 | 2. No need for a reason, unless it's absolutely necessary 52 | 3. Feel free to use Thread's OOO feature to put your notifications on "do not disturb" 53 | 54 | ## Vacation accrual 55 | 56 |
57 | 58 | Will my unused vacation days carry over to the following year? 59 | 60 | Unused days _can_ be carried over into the following year. While we encourage you to get out of the office and refresh, we won't penalize you for showing up to work 😉 61 | 62 |
63 | 64 |
65 | 66 | As a new employee, will my vacation days be prorated? 67 | 68 | Yes. The number of personal days will be adjusted based on your start date. Sick days and holidays will not be affected. 69 | 70 |
71 | -------------------------------------------------------------------------------- /sales/operations-stack.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: >- 3 | The objective of this section is to explain how the new Ops Stack was 4 | implemented and for what purpose each element exists to serve that objective. 5 | --- 6 | 7 | # Operations Stack 8 | 9 | Taking into consideration how important is to have the right information in the right time to be able to help the best way possible our customers, having a solid stack to support Ops activities is a big deal 💪 10 | 11 | ### CRM 12 | 13 | Customer relationship management (CRM) is a process in which a business or other organization administers its interactions with customers, typically using data analysis to study large amounts of information.\[^1] 14 | 15 | #### **Close.com** 16 | 17 | ### Email provider 18 | 19 | A customer communication platform for transactional and marketing email is a powerful tool to keep your customer engaged and aware of your business or product. 20 | 21 | #### **SendGrid** 22 | 23 | ### Customer Ticketing System 24 | 25 | A Customer Ticketing System is software that keeps track of customer issues so your support team can resolve them in a timely manner. It gives a team the everyday tools they need to do their job well, from answering tickets to collaborating with other team members.\[^2] 26 | 27 | #### **Help Scout** 28 | -------------------------------------------------------------------------------- /the-company/glossary.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: A guide to all of the terms we use internally. 3 | cover: >- 4 | https://images.unsplash.com/photo-1507842217343-583bb7270b66?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwxOTcwMjR8MHwxfHNlYXJjaHw5fHxib29rfGVufDB8fHx8MTY1NTA0MjIzMA&ixlib=rb-1.2.1&q=80 5 | coverY: 0 6 | --- 7 | 8 | # 🅰️ Glossary 9 | 10 |
LFElooking for engineer
LFDlooking for designer
LFRlooking for review
SIUSuper Important and Urgent. Use very carefully. (When typing you need to shout a SIUUUU)
Destination calendarThe calendar that events are created on
MonorepoMultiple projects (e.g. app, docs and API) all in one GitHub repository
CommitAddition to the code
Pull request (PR)The way in which code is reviewed and then added to the codebase. A PR is made of commits
MergeIf a PR is good, it is merged, which accepts the changes and ‘merges’ them into the codebase
i18nInternationalization (translating text)
a11yAccessibility
CTRClick-Through Rate
UIUser Interface
UXUser Experience
Event typesDifferent events that you offer on your booking link. For instance, hiring (30 mins) and performance review (60 mins) are both examples of event types.
Opt-in bookingAn event type where you must accept/deny the booking before it’s created
SlotsTime slots that are offered on your booking page that are determined to be free
RFCRequest for comments. Essentially a proposal, where we’re looping in the team to get their thoughts
Round robinSchedules each person in the team. If a team is made up of persons A, B and C, the first booking goes to person A, second goes to B, third to C etc.
CalDAVAn open standard for calendars. Essentially a ton of different calendar providers (e.g. Yandex, NextCloud) all support CalDAV, which allows you to connect those providers to Cal.com
KangarooA tall animal that hops around
WebhooksA way for Cal.com to send data to an external server when something happens (e.g. booking created)
SAML SSOA way for enterprises to let everyone in their company log in to any application, including Cal.com
VercelThe platform that builds our code and publishes it to the live site
e2eEnd to end testing. Essentially a robot that checks if our application is working each time we push code
LintingA way to make code look nice and neat
.envA file where you configure settings for Cal.com, like your database and email servers
WEBAPP_URLThe setting that tells Cal.com which URL it’s hosted on
TypeScriptAn extension of the language JavaScript, which can do things like check if values are the correct type
APIA way to get data and perform actions on the Cal.com service using code
NPM packageDependencies (things your app uses) can be packaged into NPM packages, which are bundles of code that you can use in other applications
MetadataData that is in a computer readable format, like JSON, which looks like {”make”: “Volvo”, “model”: “V40”}
11 | 12 | -------------------------------------------------------------------------------- /the-company/mission-vision-and-values.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1552664730-d307ca884978?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2970&q=80 4 | coverY: 0 5 | --- 6 | 7 | # 📈 Mission, Vision and Values 8 | 9 | ![Mission Pyramid](<../.gitbook/assets/CleanShot 2022-08-18 at 14.56.37@2x.png>) 10 | 11 | ## Mission 12 | 13 | {% hint style="info" %} 14 | Our mission is to connect a billion people by 2031 through calendar scheduling. 15 | {% endhint %} 16 | 17 | In a few words, our mission is to connect people. Scheduling enables people to meet, appointments for services to be booked, and so much more. We aim to build the core infrastructure of the web that facilitates scheduling and enables people to manage their time. 18 | 19 | ## Vision 20 | 21 | {% hint style="info" %} 22 | Bring the world closer together – for real this time. 23 | {% endhint %} 24 | 25 | Connecting a billion people by the year 2031 means expanding our SaaS consumer product and gaining market share first and then closing enterprise/infrastructure customers down the road. Our hope is to eventually work with most Fortune500 enterprises and governments around the world. 26 | 27 | ## Values 28 | 29 | ### **Move with urgency and focus** 30 | 31 | Our users entrust us with their money, their businesses, and their livelihoods. Millions of businesses around the world (individuals, startups, and large enterprises) are open for business only if we are. When we mess up, miss a deadline, or slow down, it matters. We take that responsibility seriously. 32 | 33 | ### **Think rigorously** 34 | 35 | We care about being right and it often takes reasoning from first principles to get there. Considering the huge impact that we have (as described above), we care about not just making the best decisions possible. We like to involve everyone in the decision-making process. 36 | 37 | ### **Trust and amplify** 38 | 39 | By the standards of the rest of the world, we overtrust. We’re okay with that. As an open-source company, someone could take our code and launch a rip-off using our software. Yet, we still remain to be open-source. That's because our philosophy is just to trust that few people will do this, and work on amplifying our brand to the point that rip-offs would gain absolutely no traction and no harm would be done. If you could get the source code to Facebook and launch a competitor, it wouldn’t get anywhere, would it? 40 | 41 | ### Foundational 42 | 43 | Through the tools that we build, we want to push the world to create better products and services. We want to build one of the core pillars of the internet, like Stripe, Cloudflare or other companies. 44 | 45 | ### **Optimism** 46 | 47 | We are micro pessimists but macro optimists. 48 | 49 | ### Transparency 50 | 51 | We’ll always be transparent both internally and externally, so regardless of your position in our company, we’ll always share everything with you. We also share a lot of details about our inner workings with the community too. Every important KPI, including salaries, are open at [https://cal.com/open](https://cal.com/open). This very handbook you are reading is open. 52 | 53 | ### Honesty 54 | 55 | We’re open and honest with each other and the public, even when things go wrong. We hope that our honesty helps build trust within our team and trust in our company as a whole. 56 | 57 | ### Empathy 58 | 59 | We should always be understanding of each other’s mistakes. Things happen, and we should all be understanding of that. Offer each other support instead of anything negative. 60 | 61 | ### Big goals 62 | 63 | Whilst we want to keep our team small, we have big goals and a rapid pace. 64 | 65 | ### Inclusive 66 | 67 | You won’t find any discrimination at our company. No matter who you are, we will always be welcoming and supportive of your position in our team. Our open and global salary policy makes compensation more fair and inclusive. 68 | 69 | ### Remote and Async 70 | 71 | You’re already aware of the fact that we’re remote and async which we plan to be forever, and we’ll always have a remote-first culture. We're inviting the team to retreats every once in a while. 72 | 73 | ### Sustainable 74 | 75 | We are always thinking about the long-term when we make our decisions, as we plan to be a sustainable company. Our most recent fundraising gives us a long runway to prefer long-term over short-term decisions. 76 | 77 | ### No-competition thinking 78 | 79 | Our only competitor is the [Cal.com](https://cal.com/) of yesterday. We're constantly improving and never compare ourselves to others (in terms of market competition). We do not compete with proprietary SaaS companies. The next best Cal.com alternative needs to be another open-source scheduling tool–which does not exist yet. 80 | 81 | ### Employee growth 82 | 83 | We give all of our employees a clear path of growth, enabling them to develop within our company. 84 | 85 | ### Salary equality 86 | 87 | Equal pay for equal jobs, regardless of location, gender, race, or anything else. Pretty much all salaries are open at [https://cal.com/open](https://cal.com/open). 88 | 89 | ### Capital-efficient 90 | 91 | We plan to run the company in a very capital-efficient way to preserve longevity. 92 | -------------------------------------------------------------------------------- /the-company/organization-chart.md: -------------------------------------------------------------------------------- 1 | # 📈 Organization Chart 2 | 3 | {% embed url="https://www.figma.com/embed?embed_host=share&url=https://www.figma.com/file/0YWGKlZHWxaA7VwsAV5QdF/Org-Chart?node-id=0%3A1" %} 4 | -------------------------------------------------------------------------------- /the-company/what-is-cal.com.md: -------------------------------------------------------------------------------- 1 | --- 2 | cover: >- 3 | https://images.unsplash.com/photo-1517048676732-d65bc937f952?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwxOTcwMjR8MHwxfHNlYXJjaHwzfHxjb21wYW55fGVufDB8fHx8MTY1OTI1NzI4NQ&ixlib=rb-1.2.1&q=80 4 | coverY: -214.27701232777375 5 | --- 6 | 7 | # ❓ What is Cal.com? 8 | 9 | {% embed url="https://www.youtube.com/watch?v=V2Pripb427E" %} 10 | Bailey Pumfleet on building an open source rocketship ("Stripe for Time") 11 | {% endembed %} 12 | 13 | ### General 14 | 15 | From the very first day, [Cal.com](https://cal.com/) started to connect 1 billion people by 2031. We fundamentally believe **infrastructure software** needs to be open, accessible, and here to stay. To achieve this, we started out as an open-source company from its inception. 16 | 17 | Being open-source has a lot of tradeoffs. It’s been an incredible growth journey so far thanks to its word-of-mouth nature and developer interest, but OSS is known for making it hard to capture the generated value early on. 18 | 19 | A SaaS business can capture a higher % of revenue per customer, but ultimately they will be capped by the people they can reach. Governments, Healthcare, and other highly regulated industries not only prefer but are often required to self-host. 20 | 21 | Our hunch is that proprietary SaaS alternatives are only scratching the surface of the scheduling space and CEOs in the space believe that the entire market is still in its infancy. 22 | 23 | Competing with incumbents as a SaaS business ourselves seems like a stupid idea, hence we try to do something similar but in a fundamentally different market segment: Open Source. 24 | 25 | SaaS companies are much closer to pure sales companies than tech companies. It’s primarily about increasing revenue through **maximising value capturing**. 26 | 27 | While every company's purpose is to make money, we fundamentally believe it’s never the goal, but the side-effect of having an amazing product, in a massive market, with viral network effects and a strong moat to defend your position. 28 | 29 | This is why our roadmap is to create **as much value** as possible and capture a small amount of it down the road from enterprise deals. Something that closed-source SaaS businesses have a hard time capturing due to its proprietary code-base that cannot be easily self-hosted or audited. 30 | 31 | **Value creation vs value capturing:** If a SaaS competitor has 10M customers and charges 30% of them, our goal is to have 1B customers and charge 1% of them. 32 | 33 | Keep that in mind when thinking about how we monetize features and sell to customers. 34 | 35 | To achieve this, we’re looking to build infrastructure for the masses and not for the niches. It may mean being light on some niche features that other competitors provide, in order to be more accessible to the entire market. We hope these missing features will be built by third-party engineers and launched in our upcoming App Store. 36 | 37 | MRR may be a great metric to show initial interest and retention, but the reason why we’ve raised $32.4M in funding was to give this vision the runway that it deserves and buy us time to focus on value creation and not value capturing. 38 | 39 | ### Competitive Landscape 40 | 41 | Calendly is not the only player in the scheduling game. There is SavvyCal, TidyCal, zcal, Motion, Cron, and more. 42 | 43 | **None of these competitors are relevant to us as they all focus on a B2C consumer SaaS market and do not focus on an infrastructure approach.** 44 | 45 | ### Short-term 46 | 47 | After reading this, you may think the correct thing is to immediately focus on the tail-end of the market: enterprise and sell self-hosted & infrastructure plans. After all, that’s likely a great strategy to bring in thousands of new users via a single deal. 48 | 49 | While we initially thought the same, we’ve come to the conclusion that B2C bottom-up growth (i.e. people signing up for [cal.com/username](https://cal.com/username)) is the most relevant strategy for us going forward in the short term. 50 | 51 | **Here’s why:** A single active customer shares their link about 50-100 times in the first 6 months. If only 10% of the link receivers sign up for their own account, that’s an`R0`of 5 to 10 new users per active customer. 52 | 53 | A high percentage of these new customers are developers or technical decision-makers. These people become the best salespeople and evangelists in their existing organizations, whether it's a startup or fortune500 company. 54 | 55 | We’re already seeing companies reach out for an infrastructure plan after one of their employees has been a power user of the hosted [Cal.com](https://cal.com/) plan. 56 | 57 | ### Long-term 58 | 59 | Scheduling is really hard and really important. Without a doubt, we can be charging enterprise businesses anywhere from $150,000 to multiple million dollars a year for providing proper infrastructure. 60 | 61 | While these deals would be amazing to close early on, we’re still early into the product journey and have not built out enough enterprise features and stability bug fixes to confidently sell into the market. 62 | 63 | Other companies may also be afraid to sign a multi-year contract with a young startup. Understandably. 64 | 65 | Time will help us build reputation, trust, and evangelists who sell from within the organization. That’s the plan. 66 | 67 | ![Roadmap to 2030](../.gitbook/assets/2.png) 68 | 69 | #### TLDR: 70 | 71 | * revenue is great, but not the immediate north-star to optimize for 72 | * build an army of evangelists 73 | * turn scheduling into a commodity and become the market owner 74 | * focus on the [cal.com/username](https://cal.com/username) customer experience first 75 | * sell into Fortune500 companies later to capture value 76 | * base your decision around: “how can this what I’m working on reach more people” 77 | --------------------------------------------------------------------------------