166 lines
6.2 KiB
Markdown
166 lines
6.2 KiB
Markdown
# FuelTrack
|
||
|
||
Aplikacja Flask do monitorowania paliwa, kosztów, VAT i firmowych kart paliwowych.
|
||
|
||
## Start w Dockerze
|
||
|
||
```bash
|
||
docker compose up --build
|
||
```
|
||
|
||
Aplikacja: `http://localhost:8000`
|
||
|
||
Pierwsze konto:
|
||
|
||
- e-mail: `admin@example.com`
|
||
- hasło: `admin123!`
|
||
|
||
Zmień hasło i `SECRET_KEY` przed wdrożeniem.
|
||
|
||
## WebSocket i Gunicorn
|
||
|
||
Projekt uruchamia jeden worker `gthread`, 8 wątków i wyłączony timeout dla długich połączeń Socket.IO:
|
||
|
||
```bash
|
||
gunicorn --worker-class gthread --workers 1 --threads 8 --timeout 0 --bind 0.0.0.0:8000 wsgi:app
|
||
```
|
||
|
||
Nie uruchamiaj aplikacji przez samo `gunicorn wsgi:app`, ponieważ domyślny worker `sync` i timeout 30 sekund mogą przerywać WebSocket błędem `SystemExit: 1`.
|
||
|
||
## Ceny Orlen
|
||
|
||
Zakładka **Ceny Orlen** pozwala:
|
||
|
||
- wybrać Pb95, Pb98, diesel lub LPG,
|
||
- pobrać dane za wskazany rok,
|
||
- zapisać lub zaktualizować dane w SQLite,
|
||
- wyświetlić wykres trendu i tabelę historyczną.
|
||
|
||
Dla Pb95, Pb98 i diesla wartość API za m³ jest dzielona przez 1000. Endpoint LPG zwraca regionalny zestaw dostępny w chwili pobrania.
|
||
|
||
## Testy
|
||
|
||
```bash
|
||
python -m pytest -q
|
||
```
|
||
|
||
## REST API i Swagger
|
||
|
||
Interfejs zapisuje i modyfikuje dane wyłącznie przez endpointy `/api/...`. Widoki HTML odpowiadają za prezentację, natomiast operacje biznesowe przechodzą przez REST API i zwracają JSON.
|
||
|
||
Dokumentacja po uruchomieniu:
|
||
|
||
- Swagger UI: `http://localhost:8000/docs`
|
||
- OpenAPI JSON: `http://localhost:8000/openapi.json`
|
||
|
||
Autoryzacja API korzysta z tej samej bezpiecznej sesji cookie co interfejs. Najważniejsze grupy endpointów:
|
||
|
||
- `/api/auth/*`
|
||
- `/api/users`
|
||
- `/api/settings`
|
||
- `/api/vehicles`
|
||
- `/api/fuel-entries`
|
||
- `/api/orlen/*`
|
||
- `/api/stations/*`
|
||
|
||
Stare endpointy formularzy pozostają chwilowo jako warstwa zgodności dla zakładek HTML, ale interfejs nie wysyła już do nich operacji zapisu.
|
||
|
||
|
||
Skopiuj i dostosuj konfigurację:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
docker compose up --build
|
||
```
|
||
|
||
## Wersja 9
|
||
|
||
- motyw przeniesiony do ustawień aplikacji,
|
||
- firmowy katalog kart paliwowych,
|
||
- karta przypisywana użytkownikowi lub pojazdowi,
|
||
- warunki rozliczenia definiowane per karta i stacja,
|
||
- blokada stacji, Orlen last price, rabat netto i dopłata netto za litr,
|
||
- wyszukiwanie stacji po nazwie firmy lub marki stacji.
|
||
|
||
## Administracja v10
|
||
|
||
Panel jest podzielony na:
|
||
|
||
- `/admin/companies` — firmy, ustawienia podatkowe, karty paliwowe i firmowe ulubione stacje,
|
||
- `/admin/application` — globalny motyw aplikacji,
|
||
- `/admin/users` — użytkownicy, firma, rola, karta i hasło.
|
||
|
||
Ulubione stacje są rozstrzygane kolejno: lista użytkownika, lista firmy, a następnie 10 największych sieci z katalogu URE.
|
||
|
||
## Ograniczenie historii LPG Orlen
|
||
|
||
Endpoint `https://tool.orlen.pl/api/autogasprices` zwraca wyłącznie bieżący snapshot cen dla 16 województw. Nie obsługuje parametrów daty. FuelTrack zapisuje każdy pobrany snapshot w bazie, dzięki czemu historia LPG narasta od momentu uruchomienia synchronizacji. Nie jest możliwe pobranie pełnej historii LPG wstecz z tego endpointu.
|
||
|
||
## Konfiguracja integracji
|
||
|
||
Adresy API Orlen/URE, timeouty, adresy bibliotek frontendowych i mapowanie nazw marek są konfigurowane w `.env`. Domyślne wartości znajdują się w `.env.example`.
|
||
|
||
Kod integracji został rozdzielony na:
|
||
|
||
- `app/integrations/orlen.py` – ceny Orlen,
|
||
- `app/integrations/ure.py` – pobieranie i agregacja rejestru URE,
|
||
- `app/integrations/http.py` – wspólna obsługa HTTP,
|
||
- `app/domain/costs.py` – obliczenia kosztów,
|
||
- `app/domain/invoices.py` – okresy faktur.
|
||
|
||
Frontend jest podzielony funkcjonalnie w `app/static/js/` i `app/static/css/`.
|
||
|
||
## Punkty stacji URE
|
||
Po imporcie katalogu URE kliknięcie nazwy firmy mającej więcej niż jeden punkt otwiera modal z listą placówek, adresami, województwem i dostępnymi paliwami.
|
||
|
||
## Poprawka importu punktów URE
|
||
|
||
Importer scala powtarzające się rekordy tego samego punktu po numerze DKN, aktualizuje istniejące punkty zamiast usuwać i dodawać je ponownie oraz usuwa punkty, których nie ma już w aktualnym imporcie. Zapobiega to błędowi unikalności `fuel_station_point.station_company_id, fuel_station_point.ure_dkn`.
|
||
|
||
## v12.2
|
||
- poprawione agregowanie sieci stacji po marce i adresie punktu
|
||
- poprawione wyszukiwanie live i sortowanie
|
||
- DKN traktowany jako identyfikator źródłowy, nie unikalny punkt
|
||
|
||
|
||
## Reset hasła administratora w Docker Compose
|
||
|
||
Bezpieczny wariant interaktywny (hasło nie jest wyświetlane):
|
||
|
||
```bash
|
||
docker compose exec web flask reset-admin-password --email admin@example.com
|
||
```
|
||
|
||
Polecenie poprosi dwukrotnie o nowe hasło. Konto musi już istnieć i mieć rolę `admin`.
|
||
|
||
Wariant nieinteraktywny, przydatny w skryptach (hasło może zostać zapisane w historii powłoki):
|
||
|
||
```bash
|
||
docker compose exec web flask reset-admin-password \
|
||
--email admin@example.com \
|
||
--password 'NoweBezpieczneHaslo123!'
|
||
```
|
||
|
||
Usunięcie użytkownika jest dostępne w panelu administracyjnym. System nie pozwala usunąć własnego konta, ostatniego aktywnego administratora ani użytkownika posiadającego pojazdy lub historię tankowań. Takie konto można dezaktywować po edycji.
|
||
|
||
## Zarządzanie wieloma firmami
|
||
|
||
Panel **Administracja → Firmy i karty** używa listy firm z wyszukiwaniem i paginacją. Po wybraniu firmy po prawej stronie wyświetlane są tylko jej ustawienia, karty paliwowe i ulubione stacje. Dzięki temu liczba formularzy w DOM nie rośnie wraz z liczbą firm.
|
||
|
||
W **Predefiniowanych stacjach paliw** administrator może wskazać firmę bezpośrednio w ustawieniach każdej pozycji. Zmiana firmy przeładowuje kontekst tabeli i pokazuje właściwe ulubione, dozwolone stacje oraz warunki kart.
|
||
|
||
## Uwierzytelnianie API bez cookie
|
||
|
||
Integracje zewnętrzne mogą pobrać czasowy token Bearer przez `POST /api/auth/token`.
|
||
Endpoint przyjmuje formularz OAuth2 (`username` = e-mail, `password`) lub JSON (`email`, `password`).
|
||
Następnie token należy wysyłać w nagłówku:
|
||
|
||
```text
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
Swagger UI pod `/docs` obsługuje ten mechanizm przez przycisk **Authorize** i schemat `oauth2Password`.
|
||
Domyślna ważność tokenu wynosi 8 godzin i może być zmieniona przez `API_TOKEN_MAX_AGE_SECONDS`.
|
||
Zmiana hasła użytkownika automatycznie unieważnia wcześniej wydane tokeny.
|
||
W środowisku produkcyjnym ustaw mocny, losowy `SECRET_KEY` i korzystaj wyłącznie z HTTPS.
|