Simplified app for creating appointments for clinicians. Allows user to creates and view appointments, and view per clinician. Idea here is mainly to have a basic TS server app up and connected to a DB.
docker compose up -d
(assumes you have a DB running - can always run the above command and then kill the app, so that below is the only version of the app left running)
npm install
npm run devnpm install
npm run build
npm startnpm run testnpm run test:runcurl --location 'localhost:8080/appointmentsThis endpoint can also use the from and to query params
curl --location 'localhost:8080/appointments?from=2025-11-18T17%3A34%3A47.000Z&to=2025-11-18T18%3A34%3A47.000Z'curl --location 'localhost:8080/appointments' \
--header 'Content-Type: application/json' \
--data '{
"start": "2025-11-20T17:34:47.000Z",
"end": "2025-11-20T18:34:47.000Z",
"clinicianId": "12",
"patientId": "13"
}'curl --location 'localhost:8080/clinicians/12/appointmentsThis endpoint can also use the from and to query params
curl --location 'localhost:8080/clinicians/12/appointments?from=2025-11-19T17%3A33%3A47.000Z&to=2025-11-19T18%3A34%3A47.000Z'- used express as familiar and simple with getting this up and running
- wanted to try using vitest because I only have used jest in the past
- used mysql for the DB - also just wanted to practice using a "real" DB with Docker as it's not something I've done recently and wanted to focus on getting a full end to end Dockerised app from the beginning
- Lots of documentation for this kind of thing suggested using Sequelize for an ORM. I had a look around, but Sequelize looked good enough for the job and pretty reputable so I was happy to continue as it was really nice
- I've split up routes and controllers to be as minimal as possible, so the interactions with the DB can be kept into the "services" which also don't need to know about anything to do with the format of the data itself.
- Validators are split out for testing purposes and to keep controllers as core to what it looks like it is doing as possible. That is, it only contains methods that are called directly on routes being hit.
- Should reject appointments in the past
- could use Zod or similar to validate incoming request schemas
- role authorization simulation - roles or headers - currently all endpoints hit by any user
- authentication simulation
- multiple database handling
- using sqlite over mysql as originally intended and sequelize would make this easy
- Endpoint documentation generation
- run tests on CI
- Concurrency - Currently absolutely nothing handled here
- I can see this will be an issue with the clash checking for appointments. I think we could lock the table while checks are being made so that we don't have multiple clients checking at the same time and thinking a space is valid.