This document aims to ease new contributors into working on Kalle.
This introduction assumes that you've used Kalle and are familiar with the problem it solves.
To prevent misunderstanding, we agree on using the following terms to describe our problem domain:
Term | Description |
---|---|
Appointment | When the Invitee selects a Time Slot and triggers that the Appointment is written to the Calendar Owners calendar. |
Calendar Owner | Registered user that uses Kalle to invite people (aka to use Kalle to send a link to get Appointment Suggestions from Invitees) |
Connected Calendar | An external calendar, connected via CalDav / GCal / O365 / ... |
Meeting | Created by a Calendar Owner when they want to schedule an appointment with someone. Can be understood as "the desire to speak about some topic". Kalle is used to help to find an Appointment for a Meeting. |
Integrated Calendar | The Kalle-hosted calendar used for blocking slots |
Invite Link | Generated by Kalle for a specific Meeting. The Invite Link is sent to Invitee that can select a Time Slot to create an Appointment |
Invitee | Invited by the Calendar Owner to schedule an appointment with them. |
Schedule | Time windows set by the Calendar Owner in which an Appointment can be booked. It is the general availability (e.g. workdays from 9am to 5pm as "working days schedule") |
Target Calendar | The Connected Calendars where Appointments are inserted. |
Time Slot | A time period (its duration, e.g. 30 min. is defined by the calendar owner) in which the calendar owner is available and that can be picked from an invitee to create as appointment suggestion. |
Alice wants to meet with Bob to talk about Goldfishes. For this purpose, she creates a Meeting in Kalle with the topic "Goldfish Update". She sends Bob the Invite Link to this Meeting (e.g. kalle.app/alice/goldfish-updates).
Bob opens the link and gets a lot of Time Slots displayed in which Alice is available. He chooses one of them. This creates an Appointment for this Meeting.
Alice receives an e-mail: "Bob has chosen a meeting". It is also inserted into her Target Calendar.
Requirements:
- Docker, Docker-Compose
- Node.js
npm install
to fetch dependencies.
npm start
to start the dev environment.
CTRL+C to stop.
docker-compose down
to tear it down.
npm run db:seed
seeds the database (optional, but recommended).
npx prisma migrate dev --preview-feature
creates and applies a database migration, in case you changed your schema.prisma
.
npm test
executes unit & integration tests. The first run can take a while, it'll fetch some Docker images in the background.
npm cypress:open
starts Cypress (e2e tests).
We use Prisma as our database client.
Familiarize yourself with Kalle's database schema by reading db/schema.prisma
.
You can use Prisma-ERD to visualize it.
Familiarity with Blitz.js is assumed. Blitz.js Tutorial
Kalle's core can be found in app/
.
A good way of getting to grips with the codebase is to start at the pages/
-folders, and work your way from there.
db/
contains the database schema, migrations and a seed script.
test/
contains all kinds of utilities needed for our integration tests.
cypress/
contains end-to-end tests.
email/
contains email templates.
Great that you want to help to improve Kalle! Now you already know how our project is structured, but where to get started? This section will give you a brief overview on how to structure new features.
Let's assume you want to add a new Page that allows you to create groups of users. You will probably start off by creating a new folder groups
for this.
In general there then will be 5 main things you will be using:
- Adding a Page: To do so, create a
pages
subfolder. All files in here will automatically be pages that can be reached from the frontend by the name of the file. In our example you may be adding a file namedaddGroup
which will then represent a route that can be reached from the frontend. This file should contain a functional component of the typeBlitzPage
More info - Creating a DB model: In order for the groups to be represented you will need to add a model to your database. Therefore add a new model to the file
db/schema.prisma
that describes the new entity. More info - Getting DB entries: To get data from the database you will use queries, which should be bundled in the
queries
subfolder. Queries and mutations are functions that will be executed in the backend, but can be imported and used from your frontend files in thepages
subfolder. For example, you could create a query that returns all existing groups. This function could then be imported into alistGroups
file in thepages
folder. By calling the function the query will be executed in the backend, but you will receive the result as a value from the function and could use it to render the returned groups in the frontend. This may be confusing in the beginning, so make sure, to dive deeper into this concept in the Blitz.js documentation. - Creating DB entries: Adding or updating entries to the database happens via mutations. You should create a
mutations
subfolder containing these mutations. - Creating helper functions: If your code is getting cluttered or you need helper functions, such as a function to convert dates to a human-readable format, which you use multiple times, make sure to create an
utils
directory in which you add these functions for easier reuse.
Now you know the basic concepts of how our code is structured, so have fun diving deeper into our project!
- We follow the Github Flow.
- Make sure to name your branches semantically succinct. We like to use the prefixes
feature/
,fix/
andchore/
.