Agent Host changes for agents/nodejs-express-rest-api-orm-swagger

This commit is contained in:
2026-10-27 19:13:51 +01:00
parent 1456606e39
commit cac3b0c27f
17 changed files with 3548 additions and 626 deletions
+51 -56
View File
@@ -1,73 +1,68 @@
# Test REST API (CakePHP 5)
# REST API: Express, Sequelize i MySQL
Testowy serwis REST API: klienci (`customers`), ich auta (`cars`) i użytkownicy (`users`),
uwierzytelnianie tokenem JWT, dokumentacja Swagger UI.
Serwis REST dla użytkowników, klientów i samochodów. Aplikacja Node.js korzysta z istniejących tabel `users`, `customers` i `cars`; aplikacja nie tworzy ani nie synchronizuje ich automatycznie przy uruchomieniu.
## Uruchomienie
## Wymagania i uruchomienie
- Node.js 20 lub nowszy
- MySQL z tabelami używanymi przez dotychczasową aplikację
```bash
composer install
bin/cake migrations migrate # tworzy tabele users, customers, cars
bin/cake seeds run DatabaseSeed # 2 konta, 100 klientów, 1-5 aut na klienta (czyści tabele!)
bin/cake server -p 8765
npm install
cp .env.example .env
```
Dokumentacja i konsola testowa: **http://localhost:8765/docs** (specyfikacja: `webroot/openapi.yaml`).
Ustaw w `.env` połączenie do tej samej bazy MySQL co dotychczasowa aplikacja. Następnie wykonaj migrację dodającą unikalne pole `login` do tabeli `users` (dotychczasowym użytkownikom ustawi `login = email`):
Konfiguracja bazy i sekretu JWT: `config/app_local.php` (`Datasources.default`, `Jwt.secret`, `Jwt.ttl`).
Sekret można też podać zmienną środowiskową `JWT_SECRET`.
```bash
npm run db:migrate
npm start
```
## Konta testowe
API działa domyślnie na `http://localhost:8765`, dokumentacja Swagger UI na `http://localhost:8765/docs`, a specyfikacja OpenAPI na `http://localhost:8765/openapi.yaml`. Port można zmienić przez `PORT`.
| Rola | E-mail | Hasło |
|-------|-------------------|-----------|
| admin | admin@example.com | Admin123! |
| user | user@example.com | User1234! |
Migrację można cofnąć przez `npx sequelize-cli db:migrate:undo`. Start serwera nigdy nie uruchamia migracji ani `sequelize.sync()`.
* **admin** – wszystko, w tym CRUD użytkowników.
* **user** – logowanie, własny profil, CRUD klientów i aut.
## Uwierzytelnianie i uprawnienia
API używa HTTP Basic Auth: podaj `login` i hasło w nagłówku `Authorization: Basic ...` albo skorzystaj z przycisku **Authorize** w Swagger UI. Loginem jest pole `users.login`; użytkownicy istniejący przed migracją zachowają dotychczasowe dane logowania, bo ich login zostanie ustawiony na adres e-mail.
HTTP Basic przesyła hasło w każdym żądaniu; w środowisku produkcyjnym wystawiaj API wyłącznie przez HTTPS.
Konta dodawane przez dotychczasowy seeder, o ile istnieją w bazie:
| Rola | Login po migracji | Hasło |
|---|---|---|
| admin | `admin@example.com` | `Admin123!` |
| user | `user@example.com` | `User1234!` |
Hasła nadal są przechowywane jako bcrypt. Nieaktywne konta nie mogą się uwierzytelniać. Dostęp do `/api/users` wymaga roli `admin`; klienci i samochody są dostępne dla każdego uwierzytelnionego użytkownika.
```bash
curl -u 'admin@example.com:Admin123!' http://localhost:8765/api/auth/me
curl -u 'user@example.com:User1234!' 'http://localhost:8765/api/customers?q=nowak&with_cars=1'
```
## Endpointy
| Metoda | Ścieżka | Opis |
|----------------------|--------------------------------------|---------------------------------------|
| POST | `/api/auth/login` | logowanie, zwraca token JWT |
| GET / PUT / PATCH | `/api/auth/me` | własny profil |
| GET / POST | `/api/customers` | lista (filtry, paginacja) / dodanie |
| GET / PUT / PATCH / DELETE | `/api/customers/{id}` | klient (GET zwraca też auta) |
| GET / POST | `/api/customers/{id}/cars` | auta klienta / dodanie auta klientowi |
| GET / POST | `/api/cars` | lista aut / dodanie |
| GET / PUT / PATCH / DELETE | `/api/cars/{id}` | auto (GET zwraca też właściciela) |
| GET / POST | `/api/users` | użytkownicy (tylko admin) |
| GET / PUT / PATCH / DELETE | `/api/users/{id}` | użytkownik (tylko admin) |
| Metody | Ścieżka | Opis |
|---|---|---|
| POST | `/api/auth/login` | Potwierdzenie logowania Basic Auth i aktualizacja `last_login` |
| GET / PUT / PATCH | `/api/auth/me` | Odczyt i edycja własnego profilu |
| GET / POST | `/api/users` | Lista i dodawanie użytkowników (admin) |
| GET / PUT / PATCH / DELETE | `/api/users/{id}` | Odczyt, edycja i usuwanie użytkownika (admin) |
| GET / POST | `/api/customers` | Lista klientów i dodawanie |
| GET / PUT / PATCH / DELETE | `/api/customers/{id}` | Szczegóły klienta z samochodami, edycja i usuwanie |
| GET / POST | `/api/customers/{customer_id}/cars` | Samochody klienta i dodawanie samochodu |
| GET / POST | `/api/cars` | Lista samochodów i dodawanie |
| GET / PUT / PATCH / DELETE | `/api/cars/{id}` | Szczegóły samochodu z właścicielem, edycja i usuwanie |
Przykład:
```bash
TOKEN=$(curl -s -X POST http://localhost:8765/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"User1234!"}' | jq -r .data.token)
curl -s "http://localhost:8765/api/customers?q=nowak&with_cars=1" -H "Authorization: Bearer $TOKEN"
```
## Pola
**Klient** – wymagane: `first_name`, `last_name`, `email` (unikalny), `phone`;
opcjonalne: `type` (`individual`/`company`, dla `company` wymagane `company_name`), `company_name`,
`tax_id` (NIP, 10 cyfr), `street`, `city`, `postal_code` (`00-000`), `country` (ISO, domyślnie `PL`),
`birth_date` (`YYYY-MM-DD`), `notes`.
**Auto** – wymagane: `customer_id`, `make`, `model`, `production_year`, `vin` (17 znaków, unikalny),
`registration_number` (unikalny), `fuel_type` (`petrol`/`diesel`/`lpg`/`hybrid`/`electric`);
opcjonalne: `color`, `engine_capacity` (cm³), `power_hp`, `transmission` (`manual`/`automatic`),
`mileage` (km), `notes`.
**Użytkownik** – wymagane: `email` (unikalny), `password` (min. 8 znaków), `first_name`, `last_name`;
opcjonalne: `role` (`admin`/`user`, domyślnie `user`), `active` (nieaktywny nie może się zalogować).
Listy obsługują `page`, `limit` (domyślnie 20, maksymalnie 100), `sort` i `direction` (`asc`/`desc`). Endpointy obsługują wyszukiwanie i filtry opisane w Swagger UI; liczba wyników jest zwracana w `X-Total-Count`.
## Format odpowiedzi
* sukces: `{"success": true, "data": ..., "meta": {...paginacja}}`
* błąd: `{"success": false, "error": {"code": 422, "message": "Validation failed.", "fields": {...}}}`
* kody: `200`, `201` (+ nagłówek `Location`), `204` (DELETE), `400`, `401`, `403`, `404`, `405`, `422`
- Sukces: `{"success": true, "data": ...}`; odpowiedź z listą zawiera także `meta`.
- Błąd walidacji: `{"success": false, "error": {"code": 422, "message": "Validation failed.", "fields": {...}}}`.
- Usunięcie: `204 No Content`.
Migracja nie modyfikuje plików PHP; można je usunąć osobno po przełączeniu i sprawdzeniu wdrożenia Node.js.