api module
  • TypeScript 99.5%
  • Dockerfile 0.5%
Find a file
2026-06-03 14:18:56 +02:00
.yaak docs: add yaak api 2026-06-03 11:13:52 +02:00
deliverable chore: use insert into dump 2026-06-03 14:18:56 +02:00
src refactor(db): add cascade delete 2026-06-03 11:04:02 +02:00
.gitignore chore: initial 2026-06-03 09:45:32 +02:00
bun.lock chore(deps): bump 2026-06-03 11:24:02 +02:00
compose.yaml chore: add secret key used in compose 2026-06-03 11:17:24 +02:00
Dockerfile chore: initial 2026-06-03 09:45:32 +02:00
drizzle.config.ts chore: initial 2026-06-03 09:45:32 +02:00
package.json chore(deps): bump 2026-06-03 11:24:02 +02:00
README.md docs: add deliverable 2026-06-03 11:08:11 +02:00
tsconfig.json chore: add tsconfig paths 2026-06-03 10:42:25 +02:00

API Development — Cinema

You'll find in this repository my work for this module and my deliverable.

You have been tasked to build the new API for a famous cinema that has multiple places across France. Your goal will be to integrate the overall API for customers to easily browse movies and find places where they can watch a movie.

Information about the API

Each endpoint that forwards a list should handle pagination. Pagination is cursor based. Each entity in the API should have a public identifier which is mapped according to the Stripe style, meaning it is always prefixed with a 3 characters prefix which is unique per entity and that use a snowflake ID, see the attached snowflake.js file. It is up to you to come up with the prefix namings for each entity.

All dates in the API should be formatted using the ISO 8601 standard.

All errors should have the appropriate error code and message. It is your role to come up with the proper HTTP response code and the error code naming. One endpoint can return multiple errors, for instance, for validation purposes. All errors should have the same format, which is as follows:

content-type: application/json
body:
  errors:
    type: array
    items:
      type: object
      properties:
        code: string
        message: string

Creating an account

You should be able to create an account using your email & password.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/auth/signup
request:
  content-type: application/json
  body:
    email: string
    password: string
response:
  content-type: application/json
  body:
    user:
      id: string
      email: string
      created_at: string

Authentication

You should be able to sign in using your email & password.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/auth/signin
request:
  content-type: application/json
  body:
    email: string
    password: string
response:
  content-type: application/json
  body:
    token: string

Analytics

You must implement a tracking system so the company can track who visits what. When you switch from one page to another, an event should be sent to the backend to materialize which page the user visited. This endpoint does not have to be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/analytics/track
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint. If set, the tracking row should have the user identifier.
      required: false
  body:
    tracking_id: string
    type: string
    page:
      type: object
      properties:
        scheme: string
        path: string
        query:
          type: object
          description: Dynamic map of query parameter names to their values.

The type field can either be page_enter or page_exit. This endpoint does not return a response body.

List of movies

You should be able to list all the movies. Each movie has an identifier, a title, a description, a duration (in minutes), airing dates, which is an interval, from a certain date to another date. Those dates must be inclusive. It also has a rating. Airing dates should be derived from sessions and the rating should be derived from ratings. This endpoint does not have to be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: GET
  path: /v1/movies
request:
  content-type: application/json
  query:
    sort: string
    limit: integer
    cursor: string
response:
  content-type: application/json
  body:
    movies:
      type: array
      items:
        type: object
        properties:
          id: string
          title: string
          description: string
          poster: string
          duration: number
          airing_dates:
            type: object
            properties:
              from: string
              to: string
          rating: number
    metadata:
      type: object
      properties:
        has_more: boolean
        end_cursor: string

By default, the list should be ordered by rating. There are other sorting mechanisms such as "new" where the list will be ordered by airing_dates.from with the most recent first, or "leaving soon", where the list will be ordered by airing_dates.to with the oldest first. You can choose those settings using the query param sort. The accepted values are:

  • rating (default)
  • new
  • leaving_soon

Get a movie

You should be able to get the details of a single movie. This endpoint does not have to be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: GET
  path: /v1/movies/{movie_id}
request:
  content-type: application/json
  path:
    movie_id: string
response:
  content-type: application/json
  body:
    movie:
      type: object
      properties:
        id: string
        title: string
        description: string
        poster: string
        duration: number
        airing_dates:
          type: object
          properties:
            from: string
            to: string
        rating: number

See where a movie is aired

You should be able, for one movie, to know the places where it will be aired. Each place has an identifier, a name, and an address. Each place also has a number of seats (capacity) which is used for booking limits, but it should not be returned by this endpoint. This endpoint does not have to be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: GET
  path: /v1/movies/{movie_id}/places
request:
  content-type: application/json
  path:
    movie_id: string
  query:
    limit: integer
    cursor: string
response:
  content-type: application/json
  body:
    places:
      type: array
      items:
        type: object
        properties:
          id: string
          name: string
          address: string
    metadata:
      type: object
      properties:
        has_more: boolean
        end_cursor: string

See the sessions of a movie in a place

You should be able, for one movie and one place, to know the sessions that are airing. Each session has an identifier and a starts_at datetime. You should be able to filter dates, the bounds are inclusive, by default, it should be filtered by the most recent being returned first.

The specification of this endpoint is as follows:

endpoint:
  method: GET
  path: /v1/movies/{movie_id}/places/{place_id}/sessions
request:
  content-type: application/json
  path:
    movie_id: string
    place_id: string
  query:
    from: string
    to: string
    limit: integer
    cursor: string
response:
  content-type: application/json
  body:
    sessions:
      type: array
      items:
        type: object
        properties:
          id: string
          starts_at: string
    metadata:
      type: object
      properties:
        has_more: boolean
        end_cursor: string

Rate a movie

You should be able to rate a movie. Each rating has an identifier and a value from 0 to 5. A user can only rate a movie once, if they rate it again, the previous rating should be overridden. This endpoint should be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/movies/{movie_id}/rate
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint.
      required: true
  body:
    value: number
response:
  content-type: application/json
  body:
    rating:
      id: string
      value: number

Book a session

You should be able to book a session. Each booking has an identifier, a number of seats, and a date. This endpoint only opens a booking session. You will later be able to select the number of seats and then confirm the booking. Once you have created a booking session, you should make sure to confirm it in the next minute. Once a booking session is expired, it can not be touched anymore. Confirming a booking without any reserved seats should return an error. This endpoint should be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/sessions/{session_id}/book
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint.
      required: true
  path:
    session_id: string
response:
  content-type: application/json
  body:
    booking:
      id: string
      session_id: string
      created_at: string
      closes_at: string

Reserve seats from a booking

You should be able to reserve seats from a booking. Each reservation has an identifier, a number of seats, and a date. There should be a limit of seats based on the places. All of our cinemas only have one room. If there is not anymore seats available, the request should be rejected. You can call this endpoint multiple times for the same booking. If an update asks for more seats and they are not available, the request should fail. If an update asks for fewer seats, the difference should be freed up. This endpoint should be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/bookings/{booking_id}/reserve
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint.
      required: true
  path:
    booking_id: string
  body:
    seats: number
response:
  content-type: application/json
  body:
    booking:
      id: string
      session_id: string
      reserved_seats: number
      created_at: string
      closes_at: string

Confirm a booking

You should be able to confirm a booking. Once a booking is confirmed, it can not be touched anymore. Confirming a booking without any reserved seats should return an error. This endpoint should be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/bookings/{booking_id}/confirm
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint.
      required: true
  path:
    booking_id: string
response:
  content-type: application/json
  body:
    booking:
      id: string
      session_id: string
      reserved_seats: number
      created_at: string
      closes_at: string
      confirmed_at: string

List my bookings

You should be able to list all your bookings. This endpoint should be authenticated. Each booking should resolve the movie and the place from the session.

The specification of this endpoint is as follows:

endpoint:
  method: GET
  path: /v1/bookings
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint.
      required: true
  query:
    limit: integer
    cursor: string
response:
  content-type: application/json
  body:
    bookings:
      type: array
      items:
        type: object
        properties:
          id: string
          session_id: string
          reserved_seats: number
          created_at: string
          closes_at: string
          confirmed_at: string
          movie:
            type: object
            properties:
              id: string
              title: string
          place:
            type: object
            properties:
              id: string
              name: string
    metadata:
      type: object
      properties:
        has_more: boolean
        end_cursor: string

Cancel a booking

You should be able to cancel a booking. Once a booking is confirmed or expired, it can not be cancelled anymore. This endpoint should be authenticated.

The specification of this endpoint is as follows:

endpoint:
  method: POST
  path: /v1/bookings/{booking_id}/cancel
request:
  content-type: application/json
  headers:
    Authorization:
      description: Bearer token obtained from the signin endpoint.
      required: true
  path:
    booking_id: string
response:
  content-type: application/json
  body:
    booking:
      id: string
      session_id: string
      reserved_seats: number
      created_at: string
      closes_at: string
      confirmed_at: string
      cancelled_at: string

Deliverable

You must provide the following files alongside your implementation:

  • dump.sql: an export of your database schema (tables, indexes, constraints, etc.).
  • seeds.sql: an export of your seed data (sample movies, places, sessions, users, etc.) so the API can be tested immediately.