node
This commit is contained in:
@@ -0,0 +1,609 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: REST API
|
||||
version: 1.0.0
|
||||
description: API użytkowników, klientów i samochodów. Wszystkie endpointy wymagają HTTP Basic Auth; w Swagger UI wybierz Authorize i podaj login oraz hasło.
|
||||
servers:
|
||||
- url: /
|
||||
security:
|
||||
- basicAuth: []
|
||||
tags:
|
||||
- name: Auth
|
||||
- name: Users
|
||||
- name: Customers
|
||||
- name: Cars
|
||||
paths:
|
||||
/api/auth/login:
|
||||
post:
|
||||
tags: [Auth]
|
||||
summary: Potwierdź logowanie i zaktualizuj ostatnie logowanie
|
||||
responses:
|
||||
'200':
|
||||
description: Uwierzytelniony użytkownik
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'401': { $ref: '#/components/responses/Unauthorized' }
|
||||
/api/auth/me:
|
||||
get:
|
||||
tags: [Auth]
|
||||
summary: Pobierz własny profil
|
||||
responses:
|
||||
'200':
|
||||
description: Profil użytkownika
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
put:
|
||||
tags: [Auth]
|
||||
summary: Zaktualizuj własny profil
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/ProfileInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
patch:
|
||||
tags: [Auth]
|
||||
summary: Częściowo zaktualizuj własny profil
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/ProfileInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
/api/users:
|
||||
get:
|
||||
tags: [Users]
|
||||
summary: Lista użytkowników (admin)
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/page'
|
||||
- $ref: '#/components/parameters/limit'
|
||||
- name: q
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: role
|
||||
in: query
|
||||
schema: { type: string, enum: [admin, user] }
|
||||
- name: active
|
||||
in: query
|
||||
schema: { type: boolean }
|
||||
responses:
|
||||
'200':
|
||||
description: Lista użytkowników
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserList' }
|
||||
'403': { $ref: '#/components/responses/Forbidden' }
|
||||
post:
|
||||
tags: [Users]
|
||||
summary: Dodaj użytkownika (admin)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserCreate' }
|
||||
responses:
|
||||
'201':
|
||||
description: Utworzono
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
/api/users/{id}:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/id'
|
||||
get:
|
||||
tags: [Users]
|
||||
summary: Pobierz użytkownika (admin)
|
||||
responses:
|
||||
'200':
|
||||
description: Użytkownik
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
put:
|
||||
tags: [Users]
|
||||
summary: Zaktualizuj użytkownika (admin)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
patch:
|
||||
tags: [Users]
|
||||
summary: Częściowo zaktualizuj użytkownika (admin)
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/UserResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
delete:
|
||||
tags: [Users]
|
||||
summary: Usuń użytkownika (admin)
|
||||
responses:
|
||||
'204': { description: Usunięto }
|
||||
'400': { $ref: '#/components/responses/BadRequest' }
|
||||
/api/customers:
|
||||
get:
|
||||
tags: [Customers]
|
||||
summary: Lista klientów
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/page'
|
||||
- $ref: '#/components/parameters/limit'
|
||||
- name: q
|
||||
in: query
|
||||
schema: { type: string, description: Szukanie po danych klienta }
|
||||
- name: type
|
||||
in: query
|
||||
schema: { type: string, enum: [individual, company] }
|
||||
- name: city
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: country
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: with_cars
|
||||
in: query
|
||||
schema: { type: boolean }
|
||||
responses:
|
||||
'200':
|
||||
description: Lista klientów
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerList' }
|
||||
post:
|
||||
tags: [Customers]
|
||||
summary: Dodaj klienta
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerCreate' }
|
||||
responses:
|
||||
'201':
|
||||
description: Utworzono
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
/api/customers/{id}:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/id'
|
||||
get:
|
||||
tags: [Customers]
|
||||
summary: Szczegóły klienta wraz z samochodami
|
||||
responses:
|
||||
'200':
|
||||
description: Klient
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerResponse' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
put:
|
||||
tags: [Customers]
|
||||
summary: Zaktualizuj klienta
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
patch:
|
||||
tags: [Customers]
|
||||
summary: Częściowo zaktualizuj klienta
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CustomerResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
delete:
|
||||
tags: [Customers]
|
||||
summary: Usuń klienta i jego samochody
|
||||
responses:
|
||||
'204': { description: Usunięto }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
/api/customers/{customer_id}/cars:
|
||||
parameters:
|
||||
- name: customer_id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer }
|
||||
- $ref: '#/components/parameters/page'
|
||||
- $ref: '#/components/parameters/limit'
|
||||
get:
|
||||
tags: [Cars]
|
||||
summary: Lista samochodów klienta
|
||||
responses:
|
||||
'200':
|
||||
description: Samochody klienta
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarList' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
post:
|
||||
tags: [Cars]
|
||||
summary: Dodaj samochód klientowi
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/NestedCarInput' }
|
||||
responses:
|
||||
'201':
|
||||
description: Utworzono
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
/api/cars:
|
||||
get:
|
||||
tags: [Cars]
|
||||
summary: Lista samochodów
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/page'
|
||||
- $ref: '#/components/parameters/limit'
|
||||
- name: q
|
||||
in: query
|
||||
schema: { type: string, description: Szukanie po marce, modelu i numerach auta }
|
||||
- name: customer_id
|
||||
in: query
|
||||
schema: { type: integer }
|
||||
- name: make
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: fuel_type
|
||||
in: query
|
||||
schema: { type: string, enum: [petrol, diesel, lpg, hybrid, electric] }
|
||||
- name: transmission
|
||||
in: query
|
||||
schema: { type: string, enum: [manual, automatic] }
|
||||
- name: year_from
|
||||
in: query
|
||||
schema: { type: integer }
|
||||
- name: year_to
|
||||
in: query
|
||||
schema: { type: integer }
|
||||
- name: with_customer
|
||||
in: query
|
||||
schema: { type: boolean }
|
||||
responses:
|
||||
'200':
|
||||
description: Lista samochodów
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarList' }
|
||||
post:
|
||||
tags: [Cars]
|
||||
summary: Dodaj samochód
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarCreate' }
|
||||
responses:
|
||||
'201':
|
||||
description: Utworzono
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
/api/cars/{id}:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/id'
|
||||
get:
|
||||
tags: [Cars]
|
||||
summary: Szczegóły samochodu z właścicielem
|
||||
responses:
|
||||
'200':
|
||||
description: Samochód
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarResponse' }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
put:
|
||||
tags: [Cars]
|
||||
summary: Zaktualizuj samochód
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
patch:
|
||||
tags: [Cars]
|
||||
summary: Częściowo zaktualizuj samochód
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarInput' }
|
||||
responses:
|
||||
'200':
|
||||
description: Zaktualizowano
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CarResponse' }
|
||||
'422': { $ref: '#/components/responses/ValidationError' }
|
||||
delete:
|
||||
tags: [Cars]
|
||||
summary: Usuń samochód
|
||||
responses:
|
||||
'204': { description: Usunięto }
|
||||
'404': { $ref: '#/components/responses/NotFound' }
|
||||
components:
|
||||
securitySchemes:
|
||||
basicAuth:
|
||||
type: http
|
||||
scheme: basic
|
||||
parameters:
|
||||
id:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: integer }
|
||||
page:
|
||||
name: page
|
||||
in: query
|
||||
schema: { type: integer, minimum: 1, default: 1 }
|
||||
limit:
|
||||
name: limit
|
||||
in: query
|
||||
schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
|
||||
responses:
|
||||
Unauthorized:
|
||||
description: Brak lub nieprawidłowe dane HTTP Basic Auth
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
Forbidden:
|
||||
description: Wymagana rola admin
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
NotFound:
|
||||
description: Nie znaleziono rekordu
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
BadRequest:
|
||||
description: Niedozwolona operacja
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
ValidationError:
|
||||
description: Błędy walidacji
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/Error' }
|
||||
schemas:
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean, example: false }
|
||||
error:
|
||||
type: object
|
||||
properties:
|
||||
code: { type: integer }
|
||||
message: { type: string }
|
||||
fields:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
Pagination:
|
||||
type: object
|
||||
properties:
|
||||
page: { type: integer }
|
||||
limit: { type: integer }
|
||||
total: { type: integer }
|
||||
pages: { type: integer }
|
||||
has_next_page: { type: boolean }
|
||||
has_prev_page: { type: boolean }
|
||||
sort: { type: string }
|
||||
direction: { type: string }
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: integer }
|
||||
login: { type: string }
|
||||
email: { type: string, format: email }
|
||||
first_name: { type: string }
|
||||
last_name: { type: string }
|
||||
role: { type: string, enum: [admin, user] }
|
||||
active: { type: boolean }
|
||||
last_login: { type: string, format: date-time, nullable: true }
|
||||
created: { type: string, format: date-time }
|
||||
modified: { type: string, format: date-time }
|
||||
UserInput:
|
||||
type: object
|
||||
properties:
|
||||
login: { type: string, maxLength: 255 }
|
||||
email: { type: string, format: email }
|
||||
password: { type: string, format: password, minLength: 8, maxLength: 72 }
|
||||
first_name: { type: string, maxLength: 100 }
|
||||
last_name: { type: string, maxLength: 100 }
|
||||
role: { type: string, enum: [admin, user] }
|
||||
active: { type: boolean }
|
||||
UserCreate:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/UserInput'
|
||||
- type: object
|
||||
required: [login, email, password, first_name, last_name]
|
||||
ProfileInput:
|
||||
type: object
|
||||
properties:
|
||||
email: { type: string, format: email }
|
||||
password: { type: string, format: password, minLength: 8 }
|
||||
first_name: { type: string }
|
||||
last_name: { type: string }
|
||||
UserResponse:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
data: { $ref: '#/components/schemas/User' }
|
||||
UserList:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/User' }
|
||||
meta: { $ref: '#/components/schemas/Pagination' }
|
||||
CustomerInput:
|
||||
type: object
|
||||
properties:
|
||||
type: { type: string, enum: [individual, company], default: individual }
|
||||
first_name: { type: string, maxLength: 100 }
|
||||
last_name: { type: string, maxLength: 100 }
|
||||
email: { type: string, format: email }
|
||||
phone: { type: string, maxLength: 30 }
|
||||
company_name: { type: string, nullable: true }
|
||||
tax_id: { type: string, nullable: true }
|
||||
street: { type: string, nullable: true }
|
||||
city: { type: string, nullable: true }
|
||||
postal_code: { type: string, nullable: true }
|
||||
country: { type: string, default: PL }
|
||||
birth_date: { type: string, format: date, nullable: true }
|
||||
notes: { type: string, nullable: true }
|
||||
CustomerCreate:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CustomerInput'
|
||||
- type: object
|
||||
required: [first_name, last_name, email, phone]
|
||||
Customer:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CustomerInput'
|
||||
- type: object
|
||||
properties:
|
||||
id: { type: integer }
|
||||
created_by: { type: integer, nullable: true }
|
||||
created: { type: string, format: date-time }
|
||||
modified: { type: string, format: date-time }
|
||||
CustomerResponse:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
data:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Customer'
|
||||
- type: object
|
||||
properties:
|
||||
cars:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/Car' }
|
||||
CustomerList:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/Customer' }
|
||||
meta: { $ref: '#/components/schemas/Pagination' }
|
||||
CarInput:
|
||||
type: object
|
||||
properties:
|
||||
customer_id: { type: integer }
|
||||
make: { type: string }
|
||||
model: { type: string }
|
||||
production_year: { type: integer }
|
||||
vin: { type: string, minLength: 17, maxLength: 17 }
|
||||
registration_number: { type: string }
|
||||
fuel_type: { type: string, enum: [petrol, diesel, lpg, hybrid, electric] }
|
||||
color: { type: string, nullable: true }
|
||||
engine_capacity: { type: integer, nullable: true }
|
||||
power_hp: { type: integer, nullable: true }
|
||||
transmission: { type: string, enum: [manual, automatic], nullable: true }
|
||||
mileage: { type: integer, nullable: true }
|
||||
notes: { type: string, nullable: true }
|
||||
CarCreate:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CarInput'
|
||||
- type: object
|
||||
required: [customer_id, make, model, production_year, vin, registration_number, fuel_type]
|
||||
Car:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CarInput'
|
||||
- type: object
|
||||
properties:
|
||||
id: { type: integer }
|
||||
created: { type: string, format: date-time }
|
||||
modified: { type: string, format: date-time }
|
||||
NestedCarInput:
|
||||
type: object
|
||||
required: [make, model, production_year, vin, registration_number, fuel_type]
|
||||
properties:
|
||||
make: { type: string }
|
||||
model: { type: string }
|
||||
production_year: { type: integer }
|
||||
vin: { type: string, minLength: 17, maxLength: 17 }
|
||||
registration_number: { type: string }
|
||||
fuel_type: { type: string, enum: [petrol, diesel, lpg, hybrid, electric] }
|
||||
color: { type: string, nullable: true }
|
||||
engine_capacity: { type: integer, nullable: true }
|
||||
power_hp: { type: integer, nullable: true }
|
||||
transmission: { type: string, enum: [manual, automatic], nullable: true }
|
||||
mileage: { type: integer, nullable: true }
|
||||
notes: { type: string, nullable: true }
|
||||
CarResponse:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
data:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Car'
|
||||
- type: object
|
||||
properties:
|
||||
customer: { $ref: '#/components/schemas/Customer' }
|
||||
CarList:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean }
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/Car' }
|
||||
meta: { $ref: '#/components/schemas/Pagination' }
|
||||
Reference in New Issue
Block a user