openapi.yaml

openapi: 3.0.3

info:

  title: FireBnB API — Express 2025

  version: 1.0.1-firebnb-2025

  description: |-

    Kontrakt HTTP backendu Node.js / Express w repozytorium trak2025zz/firebnb.

    Zakres: 16 operacji domenowych pod /api, udostępnianych aplikacjom React i Vue.

    Źródłem szczegółów są routery, walidatory, middleware oraz modele danych tej wersji.


    Sposób użycia:

    1. Utwórz konto przez POST /user/create; wymagane są full_name, email i password.

    2. Zaloguj się przez POST /auth/login i odczytaj pole token.

    3. Dla operacji chronionych ustaw Authorization: Bearer <token>.

    4. Pobierz id własnego konta przez GET /auth/me; jest potrzebne jako user_id przy tworzeniu noclegu.

    5. Przy rezerwacji przekaż bnb_id z pola _id dokumentu noclegu. Użytkownik rezerwujący jest ustalany z JWT.


    JWT jest ważny 3600 sekund. Zmiana konta przez PUT /user/update zwraca nowy token,

    którym należy zastąpić dotychczasowy. Wylogowanie w kliencie usuwa token lokalnie;

    backend nie udostępnia operacji logout ani odświeżania tokenu.

    Przykładowe tokeny w dokumentacji służą wyłącznie ilustracji i nie uwierzytelniają w aplikacji.


    Konwencje danych:

    - Nocleg ma _id jako 24-znakowy ObjectId MongoDB; użytkownik i rezerwacja mają liczbowe id MariaDB.

    - Żądania używają m.in. full_name, user_id, bnb_id, start_date i end_date.

    - Odpowiedzi użytkowników i rezerwacji używają fullName, userId, bnbId, startDate i endDate.

    - Daty pobytu mają format YYYY-MM-DD, a znaczniki createdAt/updatedAt format date-time.

    - Listy nie mają paginacji. GET /bnb/list zwraca tablicę; listy rezerwacji zwracają obiekt z data.

    - Rezerwacja jest tworzona z kodem 200; nocleg z kodem 201; rejestracja konta z kodem 200.



servers:

  - url: http://localhost:5000/api

    description: Express uruchomiony lokalnie lub przez docker compose

externalDocs:

  description: Kod źródłowy FireBnB — wersja Express 2025

  url: https://github.com/trak2025zz/firebnb/tree/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3

tags:

  - name: Auth

    description: Logowanie JWT i tożsamość aktualnego użytkownika.

  - name: Users

    description: Rejestracja oraz modyfikacja i usuwanie kont.

  - name: Bnbs

    description: Noclegi przechowywane w MongoDB.

  - name: Reservations

    description: Rezerwacje przechowywane w MariaDB.

security:

  - BearerAuth: []

paths:

  /auth/login:

    post:

      tags:

        - Auth

      summary: Zaloguj użytkownika

      operationId: login

      description: Zwraca token JWT ważny 3600 sekund. Nie ma endpointu refresh ani serwerowego logout;

        frontend usuwa token lokalnie. Błędne dane logowania dają 403, zgodnie z implementacją.

      security: []

      x-code-reference:

        path: api/express/routes/authRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/authRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/LoginRequest'

            example:

              email: jan@example.com

              password: Przyklad123!

      responses:

        '200':

          description: 'Zalogowano; token należy podawać jako Authorization: Bearer <token>.'

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/TokenResponse'

              examples:

                loggedIn:

                  summary: Przykładowy token; do wywołań pobierz rzeczywisty token z serwera

                  value:

                    token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImphbkBleGFtcGxlLmNvbSIsImlhdCI6MTc5MjgzNjAwMCwiZXhwIjoxNzkyODM5NjAwfQ.o8wePLszo2CXAZK5rDTp4TPCxe_s3nX4lkFX6w6cM2U

        '403':

          description: Nieznany użytkownik albo niepoprawne hasło.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: unauthenticated

  /auth/me:

    get:

      tags:

        - Auth

      summary: Pobierz tożsamość z JWT

      operationId: getCurrentUser

      description: |-

        Zwraca email, iat i exp z prawidłowego JWT oraz id konta odczytane z MariaDB.

        Nie zwraca pełnego profilu ani fullName. Gdy JWT jest nadal ważny, ale konto

        o email z tokenu nie istnieje, handler odpowiada 200 bez pola id.

      x-code-reference:

        path: api/express/routes/authRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/authRoutes.js

      responses:

        '200':

          description: Zweryfikowana tożsamość.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/AuthMe'

              example:

                email: jan@example.com

                iat: 1792836000

                exp: 1792839600

                id: 1

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

  /user/create:

    post:

      tags:

        - Users

      summary: Utwórz konto użytkownika

      operationId: createUser

      description: |-

        Publiczna rejestracja. full_name jest wymagane i ma maksymalnie 255 znaków;

        email musi być prawidłowy i nieużywany; password musi mieć od 8 do 32 znaków.

        Hasło jest hashowane bcrypt, a odpowiedź UserApiEntity pomija password.

        Po utworzeniu konta należy wywołać POST /auth/login — rejestracja nie zwraca JWT.

        Zajęty email jest zgłaszany jako błąd walidacji 422.

      security: []

      x-code-reference:

        path: api/express/routes/userRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/userRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/RegisterRequest'

            example:

              full_name: Jan Kowalski

              email: jan@example.com

              password: Przyklad123!

      responses:

        '200':

          description: Konto utworzono.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/UserCreatedResponse'

              example:

                message: User created successfully

                user:

                  id: 1

                  fullName: Jan Kowalski

                  email: jan@example.com

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Email must be unique

                        path: email

                        location: body

                        value: jan@example.com

  /user/update:

    put:

      tags:

        - Users

      summary: Zmień dane własnego konta

      operationId: updateUser

      description: |-

        Zmienia konto wyszukane według email ze zweryfikowanego JWT.

        W poprawnym żądaniu do tej wersji należy przekazać nowy, wolny email;

        full_name i password można pominąć. Odpowiedź zawiera profil oraz nowy JWT ważny godzinę.


        Ograniczenie K-03: wynik userUpdateValidation nie jest sprawdzany.

        Pominięcie email prowadzi do zapytania Sequelize z undefined, bez ustalonej odpowiedzi HTTP.

        Przekazanie obecnego email tego samego konta daje 409, ponieważ kontrola unikalności

        nie wyklucza edytowanego użytkownika. Schemat opisuje profil poprawnego wywołania;

        nie stanowi deklaracji kompletnej walidacji wykonywanej przez backend.

      x-code-reference:

        path: api/express/routes/userRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/userRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/UserUpdateRequest'

            examples:

              allFields:

                summary: Zmiana wszystkich danych

                value:

                  email: jan.nowy@example.com

                  full_name: Jan Nowak

                  password: NoweHaslo123!

              emailOnly:

                summary: Zmiana wyłącznie adresu email

                value:

                  email: jan.nowy@example.com

      responses:

        '200':

          description: Zmieniono konto; zwrócono także nowy token JWT ważny godzinę.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/UserUpdatedResponse'

              examples:

                updated:

                  value:

                    message: User updated successfully

                    user:

                      id: 1

                      fullName: Jan Nowak

                      email: jan.nowy@example.com

                      createdAt: '2026-10-24T10:00:00.000Z'

                      updatedAt: '2026-10-24T10:05:00.000Z'

                    token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imphbi5ub3d5QGV4YW1wbGUuY29tIiwiaWF0IjoxNzkyODM2MDAwLCJleHAiOjE3OTI4Mzk2MDB9.QREOieYsSNGwiw5b6AxiTcYWWYQ5CW5Fr1VPLWCW5-A

        '401':

          description: Brak JWT (tekst) albo konto przypisane do JWT nie istnieje (JSON).

          content:

            text/plain:

              schema:

                type: string

              example: Unauthorized

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: User is not logged in

        '403':

          $ref: '#/components/responses/InvalidToken'

        '409':

          description: Email już istnieje, także gdy należy do bieżącego użytkownika.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: 'User with email: jan@example.com already exists'

  /user/delete:

    delete:

      tags:

        - Users

      summary: Usuń konto wskazane adresem e-mail

      operationId: deleteUser

      description: |-

        Wymaga JWT oraz body z email wskazującym konto do fizycznego usunięcia.

        W poprawnym użyciu należy przekazać własny adres. Sukces zwraca 200 i usunięty model.

        Powiązane rezerwacje mogą zablokować usunięcie przez klucz obcy MariaDB;

        handler nie definiuje dla tego błędu stabilnego kodu ani reprezentacji.


        Ograniczenie K-02: konto jest wybierane na podstawie email z body; serwer nie sprawdza

        jego zgodności z JWT. Ograniczenie K-04: zwracany surowy model zawiera hash password.

        Body w DELETE jest wymagane przez ten handler; należy sprawdzić obsługę body przez klienta HTTP.

      x-code-reference:

        path: api/express/routes/userRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/userRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/UserDeleteRequest'

            example:

              email: jan@example.com

        description: Wymagane przez wersję 2025; w prawidłowym użyciu należy podać własny email.

      responses:

        '200':

          description: Usunięto konto. Odpowiedź obejmuje hash hasła z surowego modelu.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/UserDeletedResponse'

              examples:

                deleted:

                  summary: Surowy model zawiera także przykładowy hash password (K-04)

                  value:

                    message: User deleted successfully

                    user:

                      id: 1

                      fullName: Jan Kowalski

                      email: jan@example.com

                      createdAt: '2026-10-24T10:00:00.000Z'

                      updatedAt: '2026-10-24T10:00:00.000Z'

                      password: $2b$12$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

        '404':

          description: Konto o podanym email nie istnieje.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: 'User with email: jan@example.com not found'

  /bnb/create:

    post:

      tags:

        - Bnbs

      summary: Dodaj nocleg

      operationId: createBnb

      description: |-

        Tworzy dokument noclegu w MongoDB. Body zawiera space, cost, address i user_id.

        Id własnego konta można pobrać przez GET /auth/me. Odpowiedź 201 zawiera pole newBnB.

        space i cost muszą być różne od zera, a address nie może być pustym ciągiem.

        Model wymaga również user_id; jego pominięcie nie ma jawnie obsłużonej odpowiedzi błędu.


        Ograniczenie K-01: user_id pochodzi z body i nie jest porównywane z JWT.

        Ograniczenie K-07: handler nie sprawdza dodatniości space/cost; model przechowuje liczby

        bez zdefiniowanej jednostki space, waluty i skali ceny. Dane mające poprawny sens biznesowy

        powinny używać dodatnich wartości, ale backend nie gwarantuje tej reguły.

      x-code-reference:

        path: api/express/routes/bnbRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/bnbRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/BnbCreateRequest'

            example:

              space: 45

              cost: 250.5

              address: Rzeszow, ul. Przykladowa 10

              user_id: 1

      responses:

        '201':

          description: Nocleg utworzono.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/BnbCreatedResponse'

              example:

                message: BnB created successfully

                newBnB:

                  _id: 507f1f77bcf86cd799439011

                  space: 45

                  cost: 250.5

                  address: Rzeszow, ul. Przykladowa 10

                  user_id: 1

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

                  __v: 0

          links:

            GetCreatedBnb:

              operationId: getBnb

              parameters:

                id: $response.body#/newBnB/_id

              description: Odczytaj utworzony nocleg.

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

        '400':

          description: Brak lub fałszywa wartość space, cost albo address.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/BnbError'

              example:

                error: Please provide space, cost and address

  /bnb/list:

    get:

      tags:

        - Bnbs

      summary: Wyszukaj noclegi

      operationId: listBnbs

      description: |-

        Publiczna lista noclegów jako bezpośrednia tablica JSON. Wszystkie filtry są opcjonalne,

        łączone koniunkcją; brak wyników daje []. Granice min/max są wyłączone: używane są gt i lt.

        Brak paginacji oraz parametrów page, limit i sort.


        Rzeczywiste filtry handlera: min_cost, max_cost, min_space, max_space, user_id i address_like.

        Ograniczenie K-05: walidator sprawdza space_min/space_max, ale handler ich nie odczytuje.

        Parametry min_space/max_space działają jako filtry, lecz nie przechodzą tej walidacji.

        address_like wyszukuje fragment adresu bez rozróżniania wielkości liter, ale walidator

        dopuszcza wyłącznie litery ASCII i cyfry — bez spacji i polskich znaków.

      security: []

      x-code-reference:

        path: api/express/routes/bnbRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/bnbRoutes.js

      parameters:

        - name: min_cost

          in: query

          required: false

          description: Cena > min_cost; granica wyłączona. Parametr walidowany przez isNumeric().

          schema:

            type: number

          example: 100

        - name: max_cost

          in: query

          required: false

          description: Cena < max_cost; granica wyłączona. Parametr walidowany przez isNumeric().

          schema:

            type: number

          example: 400

        - name: min_space

          in: query

          required: false

          description: space > min_space; granica wyłączona. Parametr jest używany przez handler, lecz

            walidator sprawdza space_min (K-05).

          schema:

            type: number

          example: 20

        - name: max_space

          in: query

          required: false

          description: space < max_space; granica wyłączona. Parametr jest używany przez handler, lecz

            walidator sprawdza space_max (K-05).

          schema:

            type: number

          example: 80

        - name: user_id

          in: query

          required: false

          description: Dokładne dopasowanie liczbowego user_id właściciela noclegu.

          schema:

            type: integer

            format: int32

            example: 1

          example: 1

        - name: address_like

          in: query

          required: false

          description: Fragment adresu bez rozróżniania wielkości liter. isAlphanumeric() dopuszcza wyłącznie

            litery ASCII i cyfry, a długość wynosi 1–255 znaków. Wzorzec jest przekazywany do MongoDB

            jako tekst $regex.

          schema:

            type: string

            pattern: ^[A-Za-z0-9]+$

            maxLength: 255

            minLength: 1

          example: Rzeszow

      responses:

        '200':

          description: Tablica noclegów; brak wyników daje [].

          content:

            application/json:

              schema:

                type: array

                items:

                  $ref: '#/components/schemas/Bnb'

              examples:

                results:

                  value:

                    - _id: 507f1f77bcf86cd799439011

                      space: 45

                      cost: 250.5

                      address: Rzeszow, ul. Przykladowa 10

                      user_id: 1

                      createdAt: '2026-10-24T10:00:00.000Z'

                      updatedAt: '2026-10-24T10:00:00.000Z'

                      __v: 0

                empty:

                  summary: Brak wyników

                  value: []

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: address_like

                        location: query

                        value: Rzeszów

  /bnb/index/{id}:

    parameters:

      - $ref: '#/components/parameters/BnbId'

    get:

      tags:

        - Bnbs

      summary: Pobierz szczegóły noclegu

      operationId: getBnb

      description: |-

        Publiczny odczyt pojedynczego noclegu po ObjectId. Odpowiedź ma postać {"bnb": {...}}.

        Segment index jest częścią zarejestrowanej ścieżki. Brak dokumentu daje 404,

        a id niespełniające isMongoId() daje 422.

      security: []

      x-code-reference:

        path: api/express/routes/bnbRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/bnbRoutes.js

      responses:

        '200':

          description: Dokument noclegu w polu bnb.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/BnbDetailResponse'

              example:

                bnb:

                  _id: 507f1f77bcf86cd799439011

                  space: 45

                  cost: 250.5

                  address: Rzeszow, ul. Przykladowa 10

                  user_id: 1

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

                  __v: 0

          links:

            ListBnbReservations:

              operationId: listBnbReservations

              parameters:

                bnb_id: $response.body#/bnb/_id

              description: Pobierz rezerwacje tego noclegu.

        '404':

          $ref: '#/components/responses/BnbNotFound'

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: id

                        location: params

                        value: abc

  /bnb/update:

    put:

      tags:

        - Bnbs

      summary: Zmień dane noclegu

      operationId: updateBnb

      description: |-

        Id noclegu jest przekazywane w body. Walidator wymaga id, space, cost i address;

        space musi być całkowite, cost liczbowe, a address ciągiem do 255 znaków.

        Nie jest to żądanie z dowolnym podzbiorem pól.


        Ograniczenie K-01: JWT jest wymagany, lecz serwer nie sprawdza właściciela noclegu.

        Ograniczenie K-08: findByIdAndUpdate jest wywoływane bez new:true, więc pole bnb

        zawiera stan sprzed zmiany. Po aktualizacji należy ponownie wykonać GET /bnb/index/{id}.

        Gdy id ma prawidłowy format, ale dokument nie istnieje, handler zwraca 200 z bnb:null.

      x-code-reference:

        path: api/express/routes/bnbRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/bnbRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/BnbUpdateRequest'

            example:

              id: 507f1f77bcf86cd799439011

              space: 50

              cost: 280

              address: Rzeszow, ul. Przykladowa 10

      responses:

        '200':

          description: Operację wykonano; bnb zawiera stan sprzed zmiany albo null.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/BnbUpdatedResponse'

              examples:

                previousState:

                  summary: Nocleg znaleziony; odpowiedź zawiera stan sprzed zmiany

                  value:

                    message: BnB updated successfully

                    bnb:

                      _id: 507f1f77bcf86cd799439011

                      space: 45

                      cost: 250.5

                      address: Rzeszow, ul. Przykladowa 10

                      user_id: 1

                      createdAt: '2026-10-24T10:00:00.000Z'

                      updatedAt: '2026-10-24T10:00:00.000Z'

                      __v: 0

                notFound:

                  summary: Poprawny ObjectId, lecz brak dokumentu

                  value:

                    message: BnB updated successfully

                    bnb: null

          links:

            ReadCurrentBnb:

              operationId: getBnb

              parameters:

                id: $request.body#/id

              description: Odczytaj aktualny stan po zmianie. Przy bnb:null odczyt zwróci 404.

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: space

                        location: body

                        value: 45.5

  /bnb/delete/{id}:

    parameters:

      - $ref: '#/components/parameters/BnbId'

    delete:

      tags:

        - Bnbs

      summary: Usuń nocleg i powiązane rezerwacje

      operationId: deleteBnb

      description: |-

        Fizycznie usuwa dokument noclegu z MongoDB i następnie powiązane rezerwacje z MariaDB.

        Odpowiedź 200 zawiera deletedBnB. Brak noclegu daje 404.


        Ograniczenie K-01: handler wymaga JWT, ale nie sprawdza właściciela noclegu.

        Ograniczenie K-09: operacje w dwóch bazach nie są jedną transakcją;

        błąd usuwania rezerwacji może wystąpić już po usunięciu noclegu.

      x-code-reference:

        path: api/express/routes/bnbRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/bnbRoutes.js

      responses:

        '200':

          description: Usunięto nocleg i wykonano usunięcie jego rezerwacji.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/BnbDeletedResponse'

              example:

                message: BnB and related reservations deleted successfully

                deletedBnB:

                  _id: 507f1f77bcf86cd799439011

                  space: 45

                  cost: 250.5

                  address: Rzeszow, ul. Przykladowa 10

                  user_id: 1

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

                  __v: 0

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

        '404':

          $ref: '#/components/responses/BnbNotFound'

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: id

                        location: params

                        value: abc

  /reservation/create:

    post:

      tags:

        - Reservations

      summary: Utwórz rezerwację

      operationId: createReservation

      description: |-

        Tworzy rezerwację wskazanego noclegu. bnb_id pochodzi z _id dokumentu Bnb;

        start_date i end_date mają postać YYYY-MM-DD. userId jest ustalane z email w JWT.

        Sukces ma kod 200 i zwraca message oraz reservation. Statusów pending i confirmed

        ani limitu czasu na płatność nie ma w modelu tej wersji.


        Handler odrzuca start_date > end_date; równe daty nie są odrzucane.

        Zalecany poprawny pobyt ma start_date < end_date. Kolizja wykryta przez isConflicting

        daje 400. Ograniczenie K-06: zapytanie isConflicting nie wykrywa wszystkich nałożeń,

        a sprawdzenie i zapis nie mają transakcyjnej ochrony przed współbieżnością.

        Brak nagłówka Idempotency-Key i deduplikacji żądań.

      x-code-reference:

        path: api/express/routes/reservationRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/reservationRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/ReservationCreateRequest'

            example:

              bnb_id: 507f1f77bcf86cd799439011

              start_date: '2026-12-10'

              end_date: '2026-12-12'

      responses:

        '200':

          description: Rezerwacja utworzona.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ReservationMutationResponse'

              example:

                message: Reservation created

                reservation:

                  id: 81

                  startDate: '2026-12-10'

                  endDate: '2026-12-12'

                  userId: 1

                  bnbId: 507f1f77bcf86cd799439011

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

          links:

            GetCreatedReservation:

              operationId: getReservation

              parameters:

                id: $response.body#/reservation/id

              description: Odczytaj utworzoną rezerwację.

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

        '400':

          description: Odwrócony zakres dat albo konflikt wykryty przez isConflicting. Kod używa 400,

            nie 409.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              examples:

                reversedDates:

                  value:

                    message: reservation start is later than the end

                conflictingDates:

                  value:

                    message: reservation date is already reserved

        '404':

          description: Nocleg nie istnieje.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: bnb not found

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: bnb_id

                        location: body

                        value: abc

  /reservation/update:

    put:

      tags:

        - Reservations

      summary: Zmień daty własnej rezerwacji

      operationId: updateReservation

      description: |-

        Aktualizuje daty własnej rezerwacji wskazanej przez id w body.

        Wymagane jest id; start_date i end_date są opcjonalne. Można zmienić jedną datę.

        Handler porównuje właściciela rezerwacji z kontem ustalonym na podstawie JWT.

        Nie zmienia bnbId, userId ani żadnego statusu; bnb_id z body jest ignorowane.


        Wynikowa endDate < startDate daje 422 z polem message; błędy express-validator

        dają 422 z polem errors. Równe daty są dopuszczane. Kontrola kolizji ma ograniczenie K-06.

      x-code-reference:

        path: api/express/routes/reservationRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/reservationRoutes.js

      requestBody:

        required: true

        content:

          application/json:

            schema:

              $ref: '#/components/schemas/ReservationUpdateRequest'

            examples:

              bothDates:

                summary: Zmiana obu dat

                value:

                  id: 81

                  start_date: '2026-12-12'

                  end_date: '2026-12-14'

              endOnly:

                summary: Zmiana tylko daty zakończenia

                value:

                  id: 81

                  end_date: '2026-12-14'

      responses:

        '200':

          description: Rezerwacja zaktualizowana.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ReservationMutationResponse'

              examples:

                updated:

                  value:

                    message: Successfully updated

                    reservation:

                      id: 81

                      startDate: '2026-12-12'

                      endDate: '2026-12-14'

                      userId: 1

                      bnbId: 507f1f77bcf86cd799439011

                      createdAt: '2026-10-24T10:00:00.000Z'

                      updatedAt: '2026-10-24T10:05:00.000Z'

          links:

            GetUpdatedReservation:

              operationId: getReservation

              parameters:

                id: $response.body#/reservation/id

              description: Odczytaj rezerwację po zmianie dat.

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          description: Niepoprawny lub wygasły JWT (tekst) albo brak praw do rezerwacji (JSON).

          content:

            text/plain:

              schema:

                type: string

              example: Forbidden

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: forbidden

        '400':

          description: Wykryto konflikt terminu.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: reservation date is already reserved

        '404':

          description: Rezerwacja nie istnieje.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: not found

        '422':

          description: Błąd reguł wejściowych albo końcowa data wcześniejsza od początkowej.

          content:

            application/json:

              schema:

                oneOf:

                  - $ref: '#/components/schemas/ValidationError'

                  - $ref: '#/components/schemas/MessageError'

              examples:

                dateOrder:

                  value:

                    message: reservation start is later than end

                invalidId:

                  value:

                    errors:

                      - type: field

                        value: abc

                        msg: Invalid value

                        path: id

                        location: body

  /reservation/list:

    get:

      tags:

        - Reservations

      summary: Pobierz rezerwacje wybranego noclegu

      operationId: listBnbReservations

      description: |-

        Publiczna lista rezerwacji konkretnego noclegu; wymagany jest bnb_id.

        Filtry start_date i end_date są opcjonalne i łączone koniunkcją:

        endDate >= start_date oraz startDate <= end_date. Granice są włączne,

        więc wynik może objąć rezerwację stykającą się z granicą okresu wyszukiwania.

        Brak wyników daje {"data": []}; brak paginacji.


        Ograniczenie K-02: odczyt nie wymaga JWT i obejmuje także userId rezerwujących.

      security: []

      x-code-reference:

        path: api/express/routes/reservationRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/reservationRoutes.js

      parameters:

        - name: bnb_id

          in: query

          required: true

          description: Nocleg, którego rezerwacje są odczytywane.

          schema:

            $ref: '#/components/schemas/MongoId'

          example: 507f1f77bcf86cd799439011

        - name: start_date

          in: query

          required: false

          description: 'Dolna granica wyszukiwania: endDate >= start_date; porównanie włączne.'

          schema:

            type: string

            format: date

            example: '2026-12-10'

          example: '2026-12-01'

        - name: end_date

          in: query

          required: false

          description: 'Górna granica wyszukiwania: startDate <= end_date; porównanie włączne.'

          schema:

            type: string

            format: date

            example: '2026-12-31'

          example: '2026-12-31'

      responses:

        '200':

          description: Rezerwacje w polu data; brak wyników daje data:[].

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ReservationListResponse'

              examples:

                results:

                  value:

                    data:

                      - id: 81

                        startDate: '2026-12-10'

                        endDate: '2026-12-12'

                        userId: 1

                        bnbId: 507f1f77bcf86cd799439011

                        createdAt: '2026-10-24T10:00:00.000Z'

                        updatedAt: '2026-10-24T10:00:00.000Z'

                empty:

                  summary: Brak wyników

                  value:

                    data: []

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: bnb_id

                        location: query

  /reservation/list/user:

    get:

      tags:

        - Reservations

      summary: Pobierz własne rezerwacje wraz z noclegami

      operationId: listMyReservations

      description: |-

        Zwraca rezerwacje konta ustalonego z JWT. Nie przyjmuje user_id ani bnb_id

        jako filtrów tożsamości. Opcjonalne daty są interpretowane tak jak w /reservation/list.

        Każdy element data zawiera rezerwację i pole bnb z pełnym dokumentem noclegu.

        Gdy dokument noclegu nie istnieje, bnb ma wartość null. Brak paginacji.

      x-code-reference:

        path: api/express/routes/reservationRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/reservationRoutes.js

      parameters:

        - name: start_date

          in: query

          required: false

          description: 'Dolna granica wyszukiwania: endDate >= start_date; porównanie włączne.'

          schema:

            type: string

            format: date

            example: '2026-12-10'

          example: '2026-12-01'

        - name: end_date

          in: query

          required: false

          description: 'Górna granica wyszukiwania: startDate <= end_date; porównanie włączne.'

          schema:

            type: string

            format: date

            example: '2026-12-31'

          example: '2026-12-31'

      responses:

        '200':

          description: Własne rezerwacje w polu data.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/UserReservationListResponse'

              examples:

                results:

                  value:

                    data:

                      - id: 81

                        startDate: '2026-12-10'

                        endDate: '2026-12-12'

                        userId: 1

                        bnbId: 507f1f77bcf86cd799439011

                        createdAt: '2026-10-24T10:00:00.000Z'

                        updatedAt: '2026-10-24T10:00:00.000Z'

                        bnb:

                          _id: 507f1f77bcf86cd799439011

                          space: 45

                          cost: 250.5

                          address: Rzeszow, ul. Przykladowa 10

                          user_id: 1

                          createdAt: '2026-10-24T10:00:00.000Z'

                          updatedAt: '2026-10-24T10:00:00.000Z'

                          __v: 0

                missingBnb:

                  summary: Rezerwacja z brakującym dokumentem noclegu

                  value:

                    data:

                      - id: 81

                        startDate: '2026-12-10'

                        endDate: '2026-12-12'

                        userId: 1

                        bnbId: 507f1f77bcf86cd799439011

                        createdAt: '2026-10-24T10:00:00.000Z'

                        updatedAt: '2026-10-24T10:00:00.000Z'

                        bnb: null

                empty:

                  summary: Brak własnych rezerwacji

                  value:

                    data: []

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          $ref: '#/components/responses/InvalidToken'

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: start_date

                        location: query

                        value: '2026-02-30'

  /reservation/index/{id}:

    parameters:

      - $ref: '#/components/parameters/ReservationId'

    get:

      tags:

        - Reservations

      summary: Pobierz szczegóły rezerwacji

      operationId: getReservation

      description: |-

        Publiczny odczyt rezerwacji po liczbowym id. Segment index jest wymagany.

        Odpowiedź ma postać {"data": {...}}. Brak rekordu daje 404.

        Ograniczenie K-02: handler nie sprawdza JWT ani prawa do wskazanej rezerwacji.

      security: []

      x-code-reference:

        path: api/express/routes/reservationRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/reservationRoutes.js

      responses:

        '200':

          description: Rezerwacja w polu data.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ReservationDetailResponse'

              example:

                data:

                  id: 81

                  startDate: '2026-12-10'

                  endDate: '2026-12-12'

                  userId: 1

                  bnbId: 507f1f77bcf86cd799439011

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

          links:

            GetReservedBnb:

              operationId: getBnb

              parameters:

                id: $response.body#/data/bnbId

              description: Odczytaj nocleg wskazany przez rezerwację.

        '404':

          description: Rezerwacja nie istnieje.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: Not Found

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: id

                        location: params

                        value: abc

  /reservation/delete/{id}:

    parameters:

      - $ref: '#/components/parameters/ReservationId'

    delete:

      tags:

        - Reservations

      summary: Usuń własną rezerwację

      operationId: deleteReservation

      description: |-

        Usuwa fizycznie własną rezerwację po liczbowym id z URL.

        Konto jest ustalane na podstawie JWT, a właściciel rezerwacji jest sprawdzany.

        Odpowiedź 200 obejmuje usunięty rekord; operacja nie zapisuje statusu anulowania ani historii.

        Brak rekordu daje 404; cudza rezerwacja daje 403 w formacie application/json.

      x-code-reference:

        path: api/express/routes/reservationRoutes.js

        url: https://github.com/trak2025zz/firebnb/blob/848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3/api/express/routes/reservationRoutes.js

      responses:

        '200':

          description: Rezerwacja usunięta.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ReservationMutationResponse'

              example:

                message: successfully deleted

                reservation:

                  id: 81

                  startDate: '2026-12-10'

                  endDate: '2026-12-12'

                  userId: 1

                  bnbId: 507f1f77bcf86cd799439011

                  createdAt: '2026-10-24T10:00:00.000Z'

                  updatedAt: '2026-10-24T10:00:00.000Z'

        '401':

          $ref: '#/components/responses/MissingToken'

        '403':

          description: Niepoprawny lub wygasły JWT (tekst) albo brak praw do rezerwacji (JSON).

          content:

            text/plain:

              schema:

                type: string

              example: Forbidden

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: Forbidden

        '404':

          description: Rezerwacja nie istnieje.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/MessageError'

              example:

                message: reservation not found

        '422':

          description: Dane nie spełniają reguł express-validator; odpowiedź ma kod 422.

          content:

            application/json:

              schema:

                $ref: '#/components/schemas/ValidationError'

              examples:

                invalidInput:

                  value:

                    errors:

                      - type: field

                        msg: Invalid value

                        path: id

                        location: params

                        value: abc

components:

  securitySchemes:

    BearerAuth:

      type: http

      scheme: bearer

      bearerFormat: JWT

      description: Token z POST /auth/login lub PUT /user/update. JWT wygasa po 3600 sekundach.

  parameters:

    BnbId:

      name: id

      in: path

      required: true

      description: Id noclegu z MongoDB.

      schema:

        $ref: '#/components/schemas/MongoId'

    ReservationId:

      name: id

      in: path

      required: true

      description: Id rezerwacji z MariaDB.

      schema:

        type: integer

        format: int32

        example: 81

  responses:

    MissingToken:

      description: Brak tokenu w nagłówku Authorization. Middleware używa res.sendStatus(401).

      content:

        text/plain:

          schema:

            type: string

          example: Unauthorized

    InvalidToken:

      description: Token JWT niepoprawny lub wygasły. Middleware używa res.sendStatus(403).

      content:

        text/plain:

          schema:

            type: string

          example: Forbidden

    BnbNotFound:

      description: Nie znaleziono dokumentu noclegu.

      content:

        application/json:

          schema:

            $ref: '#/components/schemas/BnbError'

          example:

            error: BnB not found

  schemas:

    MongoId:

      type: string

      pattern: ^[0-9a-fA-F]{24}$

      example: 507f1f77bcf86cd799439011

      description: 'Identyfikator MongoDB ObjectId: 24 znaki szesnastkowe.'

    User:

      type: object

      description: Reprezentacja UserApiEntity. Odpowiedzi używają fullName; żądania używają full_name.

      required:

        - id

        - fullName

        - email

        - createdAt

        - updatedAt

      properties:

        id:

          type: integer

          format: int32

          example: 1

          readOnly: true

        fullName:

          type: string

        email:

          type: string

          format: email

        createdAt:

          type: string

          format: date-time

          readOnly: true

        updatedAt:

          type: string

          format: date-time

          readOnly: true

      example:

        id: 1

        fullName: Jan Kowalski

        email: jan@example.com

        createdAt: '2026-10-24T10:00:00.000Z'

        updatedAt: '2026-10-24T10:00:00.000Z'

    DeletedUser:

      description: Aktualny DELETE zwraca surowy model Sequelize, łącznie z hashem password. Jest to ujawnienie

        danych, które należy usunąć z implementacji.

      allOf:

        - $ref: '#/components/schemas/User'

        - type: object

          required:

            - password

          properties:

            password:

              type: string

              readOnly: true

              description: Hash bcrypt; kod nie filtruje tego pola w odpowiedzi DELETE.

    RegisterRequest:

      type: object

      required:

        - full_name

        - email

        - password

      properties:

        full_name:

          type: string

          minLength: 1

          maxLength: 255

        email:

          type: string

          format: email

          description: Walidator wymaga nieużywanego adresu e-mail.

        password:

          type: string

          format: password

          writeOnly: true

          minLength: 8

          maxLength: 32

    LoginRequest:

      type: object

      description: Dane istniejącego konta. Trasa logowania nie używa express-validator.

      required:

        - email

        - password

      properties:

        email:

          type: string

          format: email

        password:

          type: string

          format: password

          writeOnly: true

    TokenResponse:

      type: object

      required:

        - token

      properties:

        token:

          type: string

          description: 'JWT z serwera, ważny 3600 sekund; podawany jako Authorization: Bearer <token>.'

    AuthMe:

      type: object

      description: Payload zweryfikowanego JWT oraz id konta odczytane przez /auth/me.

      required:

        - email

        - iat

        - exp

      properties:

        email:

          type: string

          format: email

        iat:

          type: integer

          format: int64

          description: Czas wystawienia JWT w sekundach Unix.

        exp:

          type: integer

          format: int64

          description: Czas wygaśnięcia JWT w sekundach Unix.

        id:

          type: integer

          format: int32

          example: 1

          description: Id konta odczytany z bazy; może być pominięty, gdy konto nie istnieje.

    UserUpdateRequest:

      type: object

      description: 'Profil poprawnego wywołania obecnego handlera: wymagany nowy, wolny email; full_name

        i password są opcjonalne. Zadeklarowane userUpdateValidation nie jest egzekwowane (K-03).'

      required:

        - email

      properties:

        email:

          type: string

          format: email

          description: Należy podać nowy adres. Handler zwraca 409 także dla dotychczasowego adresu tego

            samego użytkownika.

        full_name:

          type: string

          description: Nowa nazwa użytkownika. Reguła max 255 z walidatora nie jest egzekwowana przez

            handler.

        password:

          type: string

          format: password

          writeOnly: true

          description: Nowe hasło. Reguła długości 8–32 z walidatora nie jest egzekwowana przez handler.

    UserDeleteRequest:

      type: object

      description: Wymagane body z email konta do usunięcia. Handler nie porównuje go z email z JWT.

      required:

        - email

      properties:

        email:

          type: string

          format: email

    Bnb:

      type: object

      description: Dokument noclegu Mongoose; _id ma format ObjectId, a user_id jest liczbowym id konta

        MariaDB.

      required:

        - _id

        - space

        - cost

        - address

        - user_id

        - createdAt

        - updatedAt

      properties:

        _id:

          type: string

          pattern: ^[0-9a-fA-F]{24}$

          example: 507f1f77bcf86cd799439011

          description: 'Identyfikator MongoDB ObjectId: 24 znaki szesnastkowe.'

          readOnly: true

        space:

          type: number

          description: Wartość space przechowywana jako Number. Backend nie określa jednostki; aktualizacja

            wymaga liczby całkowitej.

        cost:

          type: number

          description: Wartość ceny. Kod nie definiuje waluty ani przeliczenia na jednostki mniejsze.

        address:

          type: string

        user_id:

          type: integer

          format: int32

          example: 1

        createdAt:

          type: string

          format: date-time

          readOnly: true

        updatedAt:

          type: string

          format: date-time

          readOnly: true

        __v:

          type: integer

          readOnly: true

          description: Wewnętrzne pole wersji dokumentu Mongoose; nie jest wersją HTTP ETag.

      example:

        _id: 507f1f77bcf86cd799439011

        space: 45

        cost: 250.5

        address: Rzeszow, ul. Przykladowa 10

        user_id: 1

        createdAt: '2026-10-24T10:00:00.000Z'

        updatedAt: '2026-10-24T10:00:00.000Z'

        __v: 0

    NullableBnb:

      type: object

      required:

        - _id

        - space

        - cost

        - address

        - user_id

        - createdAt

        - updatedAt

      properties:

        _id:

          type: string

          pattern: ^[0-9a-fA-F]{24}$

          example: 507f1f77bcf86cd799439011

          description: 'Identyfikator MongoDB ObjectId: 24 znaki szesnastkowe.'

          readOnly: true

        space:

          type: number

        cost:

          type: number

        address:

          type: string

        user_id:

          type: integer

          format: int32

          example: 1

        createdAt:

          type: string

          format: date-time

          readOnly: true

        updatedAt:

          type: string

          format: date-time

          readOnly: true

        __v:

          type: integer

          readOnly: true

          description: Wewnętrzne pole wersji dokumentu Mongoose; nie jest wersją HTTP ETag.

      nullable: true

      description: Dokument Bnb albo null, gdy findByIdAndUpdate/findById nie znalazło dokumentu.

    BnbCreateRequest:

      type: object

      required:

        - space

        - cost

        - address

        - user_id

      properties:

        space:

          type: number

          not:

            enum:

              - 0

          description: Handler wymaga wartości różnej od zera; brak walidacji dodatniości i całkowitości.

        cost:

          type: number

          not:

            enum:

              - 0

          description: Handler wymaga wartości różnej od zera; brak walidacji dodatniości.

        address:

          type: string

          minLength: 1

        user_id:

          type: integer

          format: int32

          example: 1

          description: Id konta z /auth/me. Wymagane przez model Mongoose; serwer nie sprawdza zgodności

            z JWT (K-01).

    BnbUpdateRequest:

      type: object

      description: Walidator wymaga wszystkich czterech pól, mimo warunkowego przypisywania wartości w

        handlerze.

      required:

        - id

        - space

        - cost

        - address

      properties:

        id:

          $ref: '#/components/schemas/MongoId'

        space:

          type: integer

        cost:

          type: number

        address:

          type: string

          maxLength: 255

    Reservation:

      type: object

      description: Model Sequelize rezerwacji. Odpowiedź używa camelCase, żądania używają snake_case.

        Model nie zawiera statusu ani danych płatności.

      required:

        - id

        - startDate

        - endDate

        - userId

        - bnbId

        - createdAt

        - updatedAt

      properties:

        id:

          type: integer

          format: int32

          example: 81

          readOnly: true

        startDate:

          type: string

          format: date

          example: '2026-12-10'

        endDate:

          type: string

          format: date

          example: '2026-12-12'

        userId:

          type: integer

          format: int32

          example: 1

          readOnly: true

        bnbId:

          type: string

          pattern: ^[0-9a-fA-F]{24}$

          example: 507f1f77bcf86cd799439011

          description: 'Identyfikator MongoDB ObjectId: 24 znaki szesnastkowe.'

          readOnly: true

        createdAt:

          type: string

          format: date-time

          readOnly: true

        updatedAt:

          type: string

          format: date-time

          readOnly: true

      example:

        id: 81

        startDate: '2026-12-10'

        endDate: '2026-12-12'

        userId: 1

        bnbId: 507f1f77bcf86cd799439011

        createdAt: '2026-10-24T10:00:00.000Z'

        updatedAt: '2026-10-24T10:00:00.000Z'

    ReservationWithBnb:

      allOf:

        - $ref: '#/components/schemas/Reservation'

        - type: object

          required:

            - bnb

          properties:

            bnb:

              $ref: '#/components/schemas/NullableBnb'

      description: 'Element listy /reservation/list/user: rezerwacja uzupełniona o dokument bnb lub null.'

    ReservationCreateRequest:

      type: object

      description: Daty kalendarzowe YYYY-MM-DD. userId jest wyznaczane po stronie serwera z JWT. Handler

        odrzuca start_date > end_date, ale dopuszcza równość dat; zalecany poprawny pobyt ma start_date

        < end_date.

      required:

        - bnb_id

        - start_date

        - end_date

      properties:

        bnb_id:

          $ref: '#/components/schemas/MongoId'

        start_date:

          type: string

          format: date

          example: '2026-12-10'

        end_date:

          type: string

          format: date

          example: '2026-12-12'

    ReservationUpdateRequest:

      type: object

      description: Daty są opcjonalne. Handler nie przenosi rezerwacji do innego noclegu i ignoruje bnb_id.

      required:

        - id

      properties:

        id:

          type: integer

          format: int32

          example: 81

        start_date:

          type: string

          format: date

          example: '2026-12-10'

        end_date:

          type: string

          format: date

          example: '2026-12-14'

    MessageError:

      type: object

      required:

        - message

      properties:

        message:

          type: string

    BnbError:

      type: object

      required:

        - error

      properties:

        error:

          type: string

    ValidationIssue:

      type: object

      description: Pojedynczy błąd express-validator 7.x; backend nie ukrywa wartości wejściowych.

      required:

        - type

        - msg

        - path

        - location

      properties:

        type:

          type: string

          enum:

            - field

          example: field

        value:

          description: Odrzucona wartość; pomijana, gdy wejściowa wartość była undefined.

        msg:

          type: string

          example: Invalid value

        path:

          type: string

          example: bnb_id

        location:

          type: string

          enum:

            - body

            - cookies

            - headers

            - params

            - query

    ValidationError:

      type: object

      required:

        - errors

      properties:

        errors:

          type: array

          items:

            $ref: '#/components/schemas/ValidationIssue'

    UserCreatedResponse:

      type: object

      required:

        - message

        - user

      properties:

        message:

          type: string

        user:

          $ref: '#/components/schemas/User'

    UserUpdatedResponse:

      type: object

      required:

        - message

        - user

        - token

      properties:

        message:

          type: string

        user:

          $ref: '#/components/schemas/User'

        token:

          type: string

          description: Nowy JWT po zmianie konta; należy zastąpić nim token używany przez klienta.

    UserDeletedResponse:

      type: object

      required:

        - message

        - user

      properties:

        message:

          type: string

        user:

          $ref: '#/components/schemas/DeletedUser'

    BnbCreatedResponse:

      type: object

      required:

        - message

        - newBnB

      properties:

        message:

          type: string

        newBnB:

          $ref: '#/components/schemas/Bnb'

    BnbDetailResponse:

      type: object

      required:

        - bnb

      properties:

        bnb:

          $ref: '#/components/schemas/Bnb'

    BnbUpdatedResponse:

      type: object

      required:

        - message

        - bnb

      properties:

        message:

          type: string

        bnb:

          $ref: '#/components/schemas/NullableBnb'

    BnbDeletedResponse:

      type: object

      required:

        - message

        - deletedBnB

      properties:

        message:

          type: string

        deletedBnB:

          $ref: '#/components/schemas/Bnb'

    ReservationMutationResponse:

      type: object

      required:

        - message

        - reservation

      properties:

        message:

          type: string

        reservation:

          $ref: '#/components/schemas/Reservation'

    ReservationDetailResponse:

      type: object

      required:

        - data

      properties:

        data:

          $ref: '#/components/schemas/Reservation'

    ReservationListResponse:

      type: object

      required:

        - data

      properties:

        data:

          type: array

          items:

            $ref: '#/components/schemas/Reservation'

    UserReservationListResponse:

      type: object

      required:

        - data

      properties:

        data:

          type: array

          items:

            $ref: '#/components/schemas/ReservationWithBnb'

x-source-repositories:

  - url: https://github.com/trak2025zz/firebnb

    ref: 848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3

    path: api/express

    verified-on: '2026-10-24'

x-documentation-version: 2026-10-24 / rewizja 2

x-known-issues:

  - id: K-01

    operations:

      - POST /bnb/create

      - PUT /bnb/update

      - DELETE /bnb/delete/{id}

    observed: Brak weryfikacji właściciela noclegu; user_id tworzonego dokumentu pochodzi z body.

    recommended-fix: Wyznaczać user_id z JWT po stronie serwera i sprawdzać właściciela przy zapisie/usuwaniu.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-02

    operations:

      - DELETE /user/delete

      - GET /reservation/index/{id}

      - GET /reservation/list

    observed: Usuwanie konta wskazanego w body i publiczny odczyt rezerwacji nie mają kontroli uprawnień

      do wskazanego obiektu.

    recommended-fix: Usuwać własne konto z kontekstu uwierzytelnienia i jawnie określić dostęp do danych

      rezerwacji.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-03

    operations:

      - PUT /user/update

    observed: Handler nie odczytuje validationResult; wymaga nowego email, a obecny email powoduje 409.

    recommended-fix: Egzekwować wynik walidacji, obsłużyć pola opcjonalne i wykluczyć własne id z kontroli

      unikalności.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-04

    operations:

      - DELETE /user/delete

      - POST /user/create

    observed: Usunięcie konta zwraca hash password; błąd walidacji może zawierać wejściowe hasło w value.

    recommended-fix: Zwracać DTO bez password i usuwać wartości wrażliwe z błędów walidacji.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-05

    operations:

      - GET /bnb/list

    observed: Handler filtruje min_space/max_space, ale walidator sprawdza space_min/space_max. address_like

      nie akceptuje spacji i polskich znaków.

    recommended-fix: Ujednolicić nazwy filtrów i jawnie określić dopuszczalny zakres znaków adresu.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-06

    operations:

      - POST /reservation/create

      - PUT /reservation/update

    observed: isConflicting nie obejmuje wszystkich nałożeń; brak atomowej ochrony przed podwójnym zapisem.

      Równe daty są akceptowane.

    recommended-fix: Poprawić warunek kolizji, wymusić start < end i zapewnić ochronę współbieżności w

      warstwie trwałego zapisu.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-07

    operations:

      - POST /bnb/create

    observed: Brak pełnej walidacji domenowej dodatniości wartości, jednostki space i waluty ceny.

    recommended-fix: Ustalić znaczenie i jednostki pól oraz egzekwować zakresy wartości.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-08

    operations:

      - PUT /bnb/update

    observed: Odpowiedź zawiera stan sprzed zmiany albo null z kodem 200.

    recommended-fix: Po stronie backendu rozważyć zwracanie aktualnej reprezentacji oraz 404 dla braku

      dokumentu.

    status: Niepoprawione w kodzie źródłowym tej wersji

  - id: K-09

    operations:

      - DELETE /bnb/delete/{id}

    observed: Usunięcie w MongoDB i MariaDB nie jest atomowe.

    recommended-fix: Zaprojektować obsługę częściowego błędu i mechanizm uzgadniania danych.

    status: Niepoprawione w kodzie źródłowym tej wersji

x-verification:

  scope: Walidacja OpenAPI, lokalnych odwołań, przykładów, linków operacji i zgodności ze wszystkimi routerami

    /api.

  source-revision: 848e46cdf44f0a2318997d1a55cf88c2c0a4e1f3

  integration-tests: Nie uruchamiano backendu z bazami MariaDB/MongoDB.

x-evidence:

  - path: api/express/routes

    purpose: Ścieżki, kody HTTP i reprezentacje odpowiedzi.

  - path: api/express/middleware/validator

    purpose: Egzekwowane i nieegzekwowane reguły wejścia.

  - path: api/express/models

    purpose: Nazwy i typy pól w odpowiedziach.

  - url: https://www.mongodb.com/docs/manual/reference/operator/query/regex/#pcre-versus-javascript

    purpose: Obsługa tekstowego wzorca (?i)…(?-i) w MongoDB.

  - url: https://github.com/Automattic/mongoose/blob/8.0.1/lib/schema/string.js

    purpose: Przekazanie tekstowego $regex przez typ String w Mongoose 8.0.1.


Posledná zmena: Sobota, 24 október 2026, 13:36