API do rejestracji oraz podsumowywania czasu pracy pracowników. Projekt oparty na frameworku Symfony.
- Utworzenie nowego pracownika
- Rejestrowanie czasu pracy z walidacją (kolejność dat, maks. 12h, jedna rejestracja / dzień)
- Podsumowanie godzin i wynagrodzenia z konkretnego dnia
- Podsumowanie godzin i wynagrodzenia z całego miesiąca (w tym nadgodziny)
- Obsługa walidacji i wyjątków z tłumaczeniami
- REST API w formacie JSON z odpowiednimi statusami kodu
- Gotowa konfiguracja Docker Compose z bazą danych MariaDB i Adminerem
- PHP 8.2.12 lub nowszy
- Symfony 7.2.6
- Composer
- Baza danych MariaDB 11.7.2
- Docker (opcjonalnie)
- Sklonuj repozytorium:
git clone https://github.com/mateusz-przybyla/WorkTimeSystemAPI.git
cd WorkTimeSystemAPI- Zainstaluj zależności:
composer install- Skonfiguruj .env
Domyślnie dane:
DATABASE_URL="mysql://mateusz:mateusz@127.0.0.1:3306/work_time_system_api_db?serverVersion=mariadb-11.7.2&charset=utf8mb4"- Uruchom bazę danych z Dockerem:
Możesz skorzystać z gotowego pliku compose.yaml, który uruchamia kontener bazy danych oraz Adminera.
docker compose up -d- MariaDB 11.7.2 (na porcie
3306) - Adminer (GUI do zarządzania DB – dostępny na
http://localhost:8080)
- Utwórz schemat bazy danych:
symfony console doctrine:migrations:migrate- Uruchom lokalny serwer Symfony:
symfony server:start- Przetestuj:
Przetestuj funkcjonalność API np. za pomoca platformy Postman: https://www.postman.com/
GET /
- Odpowiedź:
{
"response": "Witaj w WorkTimeSystem API."
}Status kodu: 200 OK
POST /api/employee
- Przykładowe żądanie:
{
"firstname": "Jan",
"surname": "Kowalski"
}- Przykładowa odpowiedź:
{
"response": {
"uuid": "a29078ae-7f68-403c-9b1f-bd9b3e02f4d7"
}
}Status kodu: 201 Created
- Możliwe błędy:
{
"error": "Nieprawidłowy format JSON."
}Status kodu: 400 Bad Request
{
"error": {
"firstname": [
"Imię jest wymagane."
],
"surname": [
"Nazwisko jest wymagane."
]
}
}Status kodu: 422 Unprocessable Entity
POST /api/work-time
- Przykładowe żądanie:
{
"uuid": "a29078ae-7f68-403c-9b1f-bd9b3e02f4d7",
"startTime": "20.05.2024 08:00",
"endTime": "20.05.2024 16:00"
}- Przykładowa odpowiedź:
{
"response": [
"Czas pracy został dodany."
]
}Status kodu: 201 Created
- Możliwe błędy:
{
"error": "Nieprawidłowy format JSON."
}Status kodu: 400 Bad Request
{
"error": [
"Nie znaleziono pracownika."
]
}Status kodu: 404 Not Found
{
"error": [
"Pracownik już posiada zarejestrowany czas pracy w tym dniu."
]
}Status kodu: 409 Conflict
{
"error": {
"uuid": [
"To pole nie może być puste."
],
"startTime": [
"To pole nie może być puste."
],
"endTime": [
"To pole nie może być puste."
]
}
}
{
"error": [
"Data zakończenia musi być po dacie rozpoczęcia.",
"Czas pracy nie może przekraczać 12 godzin."
]
}Status kodu: 422 Unprocessable Entity
POST /api/summary/day
- Przykładowe żądanie:
{
"uuid": "a29078ae-7f68-403c-9b1f-bd9b3e02f4d7",
"date": "20.05.2024"
}- Przykładowa odpowiedź:
{
"response": {
"total_after_conversion": "160 PLN",
"hours_for_given_day": 8,
"rate": "20 PLN"
}
}Status kodu: 200 OK
- Możliwe błędy:
{
"error": "Nieprawidłowy format JSON."
}Status kodu: 400 Bad Request
{
"error": [
"Nie znaleziono pracownika."
]
}Status kodu: 404 Not Found
{
"error": {
"uuid": [
"To pole nie może być puste."
],
"date": [
"To pole nie może być puste."
],
}
}Status kodu: 422 Unprocessable Entity
POST /api/summary/month
- Przykładowe żądanie:
{
"uuid": "a29078ae-7f68-403c-9b1f-bd9b3e02f4d7",
"date": "05.2024"
}- Przykładowa odpowiedź:
{
"response": {
"regular_hours_in_given_month": 40,
"rate": "20 PLN",
"overtime_hours_in_given_month": 5,
"overtime_rate": "40 PLN",
"total_after_conversion": "1000 PLN"
}
}Status kodu: 200 OK
- Możliwe błędy:
{
"error": "Nieprawidłowy format JSON."
}Status kodu: 400 Bad Request
{
"error": [
"Nie znaleziono pracownika."
]
}Status kodu: 404 Not Found
{
"error": {
"uuid": [
"To pole nie może być puste."
],
"date": [
"To pole nie może być puste."
],
}
}Status kodu: 422 Unprocessable Entity
Błędy walidacyjne i biznesowe są tłumaczone za pomocą komponentu translatora. Przykład błędu:
{
"error": [
"Czas pracy nie może przekraczać 12 godzin."
]
}Wszystkie wyjątki HTTP (np. NotFoundHttpException, ConflictHttpException) są przechwytywane przez ApiExceptionListener, który zwraca odpowiedź w formacie JSON.
Testy jednostkowe uruchomisz za pomocą PHPUnit:
php bin/phpunitTestowany jest m.in. serwis WorkTimeService, jego logika rozliczania i podsumowania czasu pracy.