docs: reorganize project documentation
This commit is contained in:
66
docs/api.md
Normal file
66
docs/api.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Wewnętrzne Endpointy API
|
||||
|
||||
Wszystkie zewnętrzne źródła danych są wywoływane przez route handlery Next.js w `app/api`. Dzięki temu aplikacja ma jedno miejsce na walidację parametrów, cache, normalizację błędów i obsługę ograniczeń przeglądarki.
|
||||
|
||||
## Dane Pogodowe i Lokalizacje
|
||||
|
||||
| Metoda | Endpoint | Przeznaczenie |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/forecast?latitude={lat}&longitude={lon}` | Zwraca 7-dniową prognozę modelową dla współrzędnych. Łączy IMGW ALARO z Open-Meteo. Niepoprawne współrzędne zwracają `400`, awaria źródła `502`. |
|
||||
| `GET` | `/api/imgw-current?latitude={lat}&longitude={lon}` | Pobiera surową lokalną analizę IMGW Hybrid dla współrzędnych. Niepoprawne współrzędne zwracają `400`, awaria źródła `502`. |
|
||||
| `GET` | `/api/imgw/{path}` | Proxy allowlistowanych endpointów IMGW `danepubliczne.imgw.pl`. Obsługuje kolekcje `synop`, `hydro`, `meteo`, `warningsmeteo`, `warningshydro`, `product` oraz szczegół `synop/id/{id}`. Nieobsługiwana ścieżka zwraca `404`. |
|
||||
| `GET` | `/api/locations/search?query={query}&language={pl\|en}` | Wyszukuje miejscowości w Polsce przez Open-Meteo Geocoding. Zapytania krótsze niż 2 znaki albo dłuższe niż 80 znaków zwracają pustą listę. |
|
||||
| `GET` | `/api/locations/reverse?latitude={lat}&longitude={lon}&language={pl\|en}` | Ustala nazwę miejsca dla pozycji GPS przez Nominatim / OpenStreetMap. Współrzędne są zaokrąglane do trzech miejsc po przecinku. |
|
||||
|
||||
## Powiadomienia
|
||||
|
||||
Endpointy powiadomień działają w runtime Node.js, bo korzystają z `web-push` i pamięciowego magazynu subskrypcji.
|
||||
|
||||
| Metoda | Endpoint | Przeznaczenie |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/api/notifications/vapid-key` | Zwraca publiczny klucz VAPID oraz informację, czy Web Push jest skonfigurowany. |
|
||||
| `POST` | `/api/notifications/subscriptions` | Zapisuje lub aktualizuje subskrypcję Web Push dla urządzenia. Przyjmuje preferencje ostrzeżeń, briefu porannego, briefu wieczornego, lokalizację, język, województwo i opcjonalny powiat TERYT. |
|
||||
| `DELETE` | `/api/notifications/subscriptions` | Usuwa subskrypcję Web Push po jej endpointcie. |
|
||||
| `POST` | `/api/notifications/test` | Wysyła powiadomienie testowe na wskazany endpoint subskrypcji. |
|
||||
| `GET` | `/api/notifications/check` | Endpoint harmonogramu sprawdzający nowe ostrzeżenia meteorologiczne IMGW i wysyłający Web Push do pasujących subskrypcji. |
|
||||
| `GET` | `/api/notifications/daily-brief` | Endpoint harmonogramu wysyłający raz dziennie poranny brief dla subskrypcji z włączoną opcją i zapisaną lokalizacją. |
|
||||
| `GET` | `/api/notifications/tomorrow-brief` | Endpoint harmonogramu wysyłający wieczorny brief z prognozą na kolejny dzień. |
|
||||
|
||||
## Autoryzacja Harmonogramu
|
||||
|
||||
Endpointy harmonogramu:
|
||||
|
||||
- `/api/notifications/check`
|
||||
- `/api/notifications/daily-brief`
|
||||
- `/api/notifications/tomorrow-brief`
|
||||
|
||||
w produkcji wymagają sekretu `NOTIFICATIONS_CRON_SECRET` przekazanego jednym z nagłówków:
|
||||
|
||||
```http
|
||||
Authorization: Bearer <NOTIFICATIONS_CRON_SECRET>
|
||||
x-cron-secret: <NOTIFICATIONS_CRON_SECRET>
|
||||
```
|
||||
|
||||
Jeśli `NOTIFICATIONS_CRON_SECRET` nie jest ustawiony, endpointy harmonogramu są dostępne tylko poza `NODE_ENV=production`.
|
||||
|
||||
## Cache i Odpowiedzi
|
||||
|
||||
| Endpoint | Cache |
|
||||
| --- | --- |
|
||||
| `/api/forecast` | `s-maxage=900`, `stale-while-revalidate=1800` |
|
||||
| `/api/imgw-current` | `s-maxage=120`, `stale-while-revalidate=300` |
|
||||
| `/api/imgw/{path}` | `s-maxage=300`, `stale-while-revalidate=600` |
|
||||
| `/api/locations/search` | `s-maxage=86400`, `stale-while-revalidate=604800` |
|
||||
| `/api/locations/reverse` | `s-maxage=86400`, `stale-while-revalidate=604800` |
|
||||
|
||||
Route handlery zwracają kontrolowane odpowiedzi JSON. Błędy zewnętrznych usług są mapowane na czytelne statusy HTTP, zwykle `400`, `404`, `502` albo `503`.
|
||||
|
||||
## Szczególny Przypadek IMGW
|
||||
|
||||
Publiczne endpointy ostrzeżeń IMGW potrafią zwrócić HTTP `404` z treścią:
|
||||
|
||||
```json
|
||||
{"status":false,"message":"No products were found"}
|
||||
```
|
||||
|
||||
Dla `warningsmeteo` i `warningshydro` aplikacja traktuje ten wariant jako poprawną pustą listę ostrzeżeń, a nie awarię źródła danych.
|
||||
71
docs/architecture.md
Normal file
71
docs/architecture.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Architektura i Przepływ Danych
|
||||
|
||||
`wtr.` jest aplikacją Next.js App Router z komponentami React, cache'owaniem przez TanStack Query i stanem preferencji w Zustand.
|
||||
|
||||
## Struktura
|
||||
|
||||
```text
|
||||
app/ routing, layout, route handlery i strony
|
||||
components/ komponenty widoków, UI, stanów, prognozy, hydro i ostrzeżeń
|
||||
hooks/ hooki TanStack Query
|
||||
lib/ fetchery, normalizacja danych, Web Push, i18n, store i helpery
|
||||
types/ typy danych IMGW, prognozy, lokalizacji i powiadomień
|
||||
public/ manifest, service worker i ikony PWA
|
||||
scripts/ worker powiadomień dla self-hostingu
|
||||
docs/ dokumentacja techniczna
|
||||
```
|
||||
|
||||
## Routing
|
||||
|
||||
Najważniejsze widoki:
|
||||
|
||||
- `/` - dashboard pogody, wyszukiwarka lokalizacji, hero, prognoza, briefy i ostrzeżenia regionalne,
|
||||
- `/warnings` - pełny widok ostrzeżeń meteo i hydro,
|
||||
- `/hydro` - stacje hydrologiczne,
|
||||
- `/settings` - język, motyw, lokalizacja powiadomień i Web Push,
|
||||
- `/station/[id]` - szczegóły stacji,
|
||||
- `/offline` - fallback offline.
|
||||
|
||||
## Przepływ Danych
|
||||
|
||||
1. Komponenty UI wywołują hooki z `hooks/`.
|
||||
2. Hooki używają TanStack Query i fetcherów z `lib/`.
|
||||
3. Fetchery pobierają dane przez route handlery w `app/api/`.
|
||||
4. Route handlery walidują parametry, odpytują zewnętrzne usługi, ustawiają cache i normalizują błędy.
|
||||
5. Moduły w `lib/` normalizują odpowiedzi do typów z `types/`.
|
||||
6. Komponenty prezentują loading, error, retry oraz empty states.
|
||||
|
||||
## Stan Aplikacji
|
||||
|
||||
Zustand w `lib/store.ts` przechowuje trwałe preferencje użytkownika w `localStorage`, m.in.:
|
||||
|
||||
- ulubione stacje,
|
||||
- wybraną stację albo lokalizację,
|
||||
- ustawienia powiadomień,
|
||||
- tryb wyboru województwa dla alertów.
|
||||
|
||||
Język interfejsu jest przechowywany osobno w `localStorage` pod kluczem `wtr:language`.
|
||||
|
||||
## PWA i Offline
|
||||
|
||||
Manifest znajduje się w `public/manifest.json`, a service worker w `public/sw.js`.
|
||||
|
||||
Service worker:
|
||||
|
||||
- cache'uje powłokę aplikacji,
|
||||
- obsługuje fallback `/offline` dla nawigacji,
|
||||
- cache'uje wybrane odpowiedzi API: `/api/imgw/*`, `/api/imgw-current`, `/api/forecast`,
|
||||
- obsługuje zdarzenia `push` i kliknięcia w powiadomienia.
|
||||
|
||||
Rejestracja service workera działa w buildzie produkcyjnym.
|
||||
|
||||
## i18n
|
||||
|
||||
Interfejs jest dostępny po polsku i angielsku. Teksty są w `lib/i18n.tsx`. Nazwy stacji i oryginalne treści IMGW nie są automatycznie tłumaczone.
|
||||
|
||||
## Zasady Integracji
|
||||
|
||||
- Dane zewnętrzne przechodzą przez route handlery Next.js.
|
||||
- IMGW pozostaje źródłem bieżących pomiarów, hydro i ostrzeżeń.
|
||||
- Prognoza modelowa jest opisana oddzielnie i nie jest przedstawiana jako pomiar IMGW.
|
||||
- Braki danych są pokazywane jawnie, bez generowania fikcyjnych wartości.
|
||||
58
docs/data-sources.md
Normal file
58
docs/data-sources.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Źródła Danych i Cache
|
||||
|
||||
`wtr.` korzysta z publicznych źródeł danych pogodowych i lokalizacyjnych. Dane zewnętrzne są pobierane przez route handlery Next.js, a UI pokazuje brak danych jawnie zamiast uzupełniać je estymacją.
|
||||
|
||||
## IMGW
|
||||
|
||||
| Dane | Źródło |
|
||||
| --- | --- |
|
||||
| Bieżąca analiza IMGW Hybrid | `https://meteo.imgw.pl/api/v1/forecast/fcapi` |
|
||||
| Prognoza godzinowa IMGW ALARO | `https://meteo.imgw.pl/api/v1/forecast/fcapi?m=alaro` |
|
||||
| Dane synoptyczne | `https://danepubliczne.imgw.pl/api/data/synop` |
|
||||
| Pojedyncza stacja synoptyczna | `https://danepubliczne.imgw.pl/api/data/synop/id/{id}` |
|
||||
| Dane hydrologiczne | `https://danepubliczne.imgw.pl/api/data/hydro/` |
|
||||
| Ostrzeżenia meteorologiczne | `https://danepubliczne.imgw.pl/api/data/warningsmeteo` |
|
||||
| Ostrzeżenia hydrologiczne | `https://danepubliczne.imgw.pl/api/data/warningshydro` |
|
||||
| Dane meteorologiczne | `https://danepubliczne.imgw.pl/api/data/meteo/` |
|
||||
| Lista produktów | `https://danepubliczne.imgw.pl/api/data/product` |
|
||||
|
||||
IMGW jest traktowane jako źródło bieżących pomiarów, hydro i ostrzeżeń. Prognoza modelowa jest w interfejsie rozdzielona od pomiarów.
|
||||
|
||||
## Open-Meteo
|
||||
|
||||
Open-Meteo Forecast API (`https://api.open-meteo.com/v1/forecast`) dostarcza pełny 7-dniowy horyzont prognozy, prawdopodobieństwo opadu i fallback, jeśli IMGW ALARO nie odpowiada.
|
||||
|
||||
Open-Meteo Geocoding API (`https://geocoding-api.open-meteo.com/v1/search`) służy do wyszukiwania miejscowości w Polsce.
|
||||
|
||||
Przed większym lub komercyjnym wdrożeniem należy sprawdzić aktualne warunki korzystania z Open-Meteo albo zastąpić usługę własnym dostawcą.
|
||||
|
||||
## Nominatim / OpenStreetMap
|
||||
|
||||
Opcjonalny reverse geocoding GPS korzysta z publicznego endpointu:
|
||||
|
||||
```text
|
||||
https://nominatim.openstreetmap.org/reverse
|
||||
```
|
||||
|
||||
Wywołanie następuje wyłącznie po zgodzie użytkownika. Interfejs pokazuje atrybucję OpenStreetMap. Pozycja GPS jest zaokrąglana do trzech miejsc po przecinku, czyli około 100 metrów.
|
||||
|
||||
Przed wdrożeniem o większym ruchu należy sprawdzić aktualną politykę użycia publicznej instancji Nominatim albo użyć własnej usługi.
|
||||
|
||||
## Cache
|
||||
|
||||
| Dane | Cache |
|
||||
| --- | --- |
|
||||
| IMGW Hybrid | 120 sekund, `stale-while-revalidate=300` |
|
||||
| Prognoza modelowa | 900 sekund, `stale-while-revalidate=1800` |
|
||||
| Proxy IMGW `danepubliczne.imgw.pl` | 300 sekund, `stale-while-revalidate=600` |
|
||||
| Wyszukiwanie miejscowości | 24 godziny, `stale-while-revalidate=7 dni` |
|
||||
| Reverse geocoding | 24 godziny, `stale-while-revalidate=7 dni` |
|
||||
|
||||
Service worker dodatkowo może cache'ować odpowiedzi `GET` dla `/api/imgw/*`, `/api/imgw-current` i `/api/forecast`, aby ostatnio pobrane dane były dostępne przy problemach z siecią.
|
||||
|
||||
## Ograniczenia Źródeł
|
||||
|
||||
- Endpoint IMGW Hybrid jest częścią publicznego frontendu `meteo.imgw.pl`, ale nie jest opisany w stabilnej dokumentacji `danepubliczne.imgw.pl`.
|
||||
- Publiczny endpoint synoptyczny IMGW zwraca najnowszy pomiar, a nie historię odczytów.
|
||||
- IMGW ALARO zwykle dostarcza krótszy horyzont godzinowy niż 7 dni; Open-Meteo uzupełnia dalszy zakres.
|
||||
- `wtr.` nie generuje fikcyjnych danych pogodowych.
|
||||
83
docs/deployment.md
Normal file
83
docs/deployment.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Wdrożenie i Uruchamianie
|
||||
|
||||
## Lokalnie
|
||||
|
||||
Wymagany jest Node.js 20.9 lub nowszy.
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Domyślny adres lokalny:
|
||||
|
||||
```text
|
||||
http://localhost:3000
|
||||
```
|
||||
|
||||
## Build Produkcyjny
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npm run start
|
||||
```
|
||||
|
||||
`npm run build` uruchamia build Next.js oraz kontrolę TypeScript wykonywaną przez Next.js.
|
||||
|
||||
## Self-Hosting z Workerem Powiadomień
|
||||
|
||||
Worker powiadomień musi działać obok uruchomionej aplikacji:
|
||||
|
||||
```bash
|
||||
npm run start
|
||||
npm run notifications:worker
|
||||
```
|
||||
|
||||
Jeśli aplikacja działa na innym porcie, ustaw `WTR_APP_URL`:
|
||||
|
||||
```bash
|
||||
WTR_APP_URL=http://127.0.0.1:4000 npm run notifications:worker
|
||||
```
|
||||
|
||||
Worker sam wczytuje `.env` i `.env.local`, ale zmienne ustawione w shellu mają pierwszeństwo.
|
||||
|
||||
## Vercel
|
||||
|
||||
1. Umieść repozytorium w serwisie Git.
|
||||
2. Importuj projekt do Vercel jako aplikację Next.js.
|
||||
3. Nie dodawaj kluczy API dla danych pogodowych: publiczne endpointy IMGW, Open-Meteo i Nominatim nie wymagają ich w obecnej integracji.
|
||||
4. Wdróż standardowym buildem `npm run build`.
|
||||
|
||||
Proxy IMGW działa jako route handler Next.js i jest zgodne z hostingiem Vercel.
|
||||
|
||||
Jeśli używasz powiadomień na Vercel, endpointy harmonogramu muszą być wywoływane zewnętrznym cronem albo innym schedulerem. Sam route handler nie uruchamia się cyklicznie bez zewnętrznego wywołania.
|
||||
|
||||
## Zmienne Środowiskowe
|
||||
|
||||
```bash
|
||||
WEB_PUSH_VAPID_PUBLIC_KEY=
|
||||
WEB_PUSH_VAPID_PRIVATE_KEY=
|
||||
WEB_PUSH_VAPID_SUBJECT=mailto:admin@example.com
|
||||
NOTIFICATIONS_CRON_SECRET=
|
||||
WTR_APP_URL=http://127.0.0.1:3000
|
||||
NOTIFICATIONS_WARNING_INTERVAL_MINUTES=5
|
||||
NOTIFICATIONS_MORNING_BRIEF_TIME=07:00
|
||||
NOTIFICATIONS_TOMORROW_BRIEF_TIME=18:00
|
||||
```
|
||||
|
||||
Do zwykłego uruchomienia aplikacji pogodowej zmienne Web Push nie są wymagane. Są potrzebne dopiero dla powiadomień.
|
||||
|
||||
## Jakość
|
||||
|
||||
Przed zakończeniem zmian uruchamiaj:
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
npm run build
|
||||
```
|
||||
|
||||
Repozytorium nie ma obecnie osobnego skryptu testów, osobnego skryptu type-check ani formattera.
|
||||
|
||||
## Bezpieczeństwo Zależności
|
||||
|
||||
Projekt używa Next.js `16.2.6`. Znany status zależności obejmuje umiarkowane zgłoszenie `GHSA-qx2v-qp2m-jg93` dla PostCSS `8.4.31` bundlowanego bezpośrednio przez Next.js. Główna konfiguracja projektu korzysta z PostCSS `8.4.49`. Po publikacji poprawki upstream należy zaktualizować Next.js i ponownie uruchomić audyt.
|
||||
117
docs/notifications.md
Normal file
117
docs/notifications.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Powiadomienia Web Push
|
||||
|
||||
Powiadomienia obejmują:
|
||||
|
||||
- nowe ostrzeżenia meteorologiczne IMGW,
|
||||
- poranny brief dnia,
|
||||
- wieczorny brief z prognozą na jutro,
|
||||
- testowe powiadomienie wysyłane z `/settings`.
|
||||
|
||||
Konfiguracja użytkownika znajduje się w widoku `/settings`.
|
||||
|
||||
## Wymagania
|
||||
|
||||
Do wysyłki Web Push potrzebne są klucze VAPID:
|
||||
|
||||
```bash
|
||||
WEB_PUSH_VAPID_PUBLIC_KEY=
|
||||
WEB_PUSH_VAPID_PRIVATE_KEY=
|
||||
WEB_PUSH_VAPID_SUBJECT=mailto:admin@example.com
|
||||
```
|
||||
|
||||
Klucze można wygenerować poleceniem:
|
||||
|
||||
```bash
|
||||
npx web-push generate-vapid-keys
|
||||
```
|
||||
|
||||
Endpointy harmonogramu wymagają też sekretu crona w produkcji:
|
||||
|
||||
```bash
|
||||
NOTIFICATIONS_CRON_SECRET=
|
||||
```
|
||||
|
||||
## Preferencje Subskrypcji
|
||||
|
||||
Subskrypcja Web Push zapisuje:
|
||||
|
||||
- endpoint subskrypcji przeglądarki,
|
||||
- województwo,
|
||||
- język interfejsu,
|
||||
- czy ostrzeżenia są aktywne,
|
||||
- czy aktywny jest brief poranny,
|
||||
- czy aktywny jest brief na jutro,
|
||||
- współrzędne i nazwę lokalizacji,
|
||||
- opcjonalny powiat TERYT.
|
||||
|
||||
Ostrzeżenia meteo są filtrowane po powiecie TERYT, jeśli lokalizacja go dostarcza. W przeciwnym razie używany jest fallback wojewódzki.
|
||||
|
||||
## Worker Self-Hosted
|
||||
|
||||
Worker powiadomień uruchamia się osobno od aplikacji:
|
||||
|
||||
```bash
|
||||
npm run notifications:worker
|
||||
```
|
||||
|
||||
Wymaga równolegle działającej aplikacji Next.js. Domyślnie odpytuje:
|
||||
|
||||
```bash
|
||||
http://127.0.0.1:3000
|
||||
```
|
||||
|
||||
Jeśli aplikacja działa pod innym adresem albo portem, ustaw:
|
||||
|
||||
```bash
|
||||
WTR_APP_URL=http://127.0.0.1:4000
|
||||
```
|
||||
|
||||
Worker wczytuje `.env` i `.env.local`. Zmienne ustawione bezpośrednio w shellu mają pierwszeństwo.
|
||||
|
||||
## Harmonogram
|
||||
|
||||
Domyślna konfiguracja:
|
||||
|
||||
```bash
|
||||
NOTIFICATIONS_WARNING_INTERVAL_MINUTES=5
|
||||
NOTIFICATIONS_MORNING_BRIEF_TIME=07:00
|
||||
NOTIFICATIONS_TOMORROW_BRIEF_TIME=18:00
|
||||
```
|
||||
|
||||
Worker:
|
||||
|
||||
- sprawdza nowe ostrzeżenia co 5 minut,
|
||||
- po 07:00 czasu `Europe/Warsaw` wywołuje `/api/notifications/daily-brief`,
|
||||
- po 18:00 czasu `Europe/Warsaw` wywołuje `/api/notifications/tomorrow-brief`,
|
||||
- nie blokuje jednego harmonogramu błędem drugiego.
|
||||
|
||||
Endpointy harmonogramu nie uruchamiają się same bez workera albo zewnętrznego crona.
|
||||
|
||||
## Zewnętrzny Cron
|
||||
|
||||
Jeśli nie używasz `npm run notifications:worker`, zewnętrzny cron powinien wywoływać:
|
||||
|
||||
```text
|
||||
GET /api/notifications/check
|
||||
GET /api/notifications/daily-brief
|
||||
GET /api/notifications/tomorrow-brief
|
||||
```
|
||||
|
||||
W produkcji dodaj jeden z nagłówków:
|
||||
|
||||
```http
|
||||
Authorization: Bearer <NOTIFICATIONS_CRON_SECRET>
|
||||
x-cron-secret: <NOTIFICATIONS_CRON_SECRET>
|
||||
```
|
||||
|
||||
## Platformy
|
||||
|
||||
- iOS/iPadOS wymaga dodania PWA do ekranu początkowego i uruchomienia aplikacji z ikony.
|
||||
- Android i desktop nie są blokowane wymogiem `standalone`, jeśli przeglądarka obsługuje Web Push.
|
||||
- GPS i powiadomienia wymagają bezpiecznego kontekstu HTTPS poza wyjątkami typu `localhost`.
|
||||
|
||||
## Ograniczenia
|
||||
|
||||
Obecny `lib/push-store.ts` przechowuje subskrypcje i historię wysyłek w pamięci procesu. Po restarcie procesu te dane znikają. Produkcja wymaga trwałego magazynu, np. bazy danych albo KV.
|
||||
|
||||
Powiadomienie testowe jest wysyłane na konkretny endpoint subskrypcji przekazany z `/settings`, a nie broadcastowane do wszystkich urządzeń.
|
||||
95
docs/weather-logic.md
Normal file
95
docs/weather-logic.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# Logika Pogody i Fallbacki
|
||||
|
||||
`wtr.` rozdziela bieżące pomiary, lokalną analizę IMGW Hybrid, prognozę modelową i ostrzeżenia. Prognoza nie jest przedstawiana jako pomiar IMGW.
|
||||
|
||||
## Bieżące Warunki
|
||||
|
||||
Dashboard hero korzysta z publicznego endpointu IMGW Hybrid oficjalnego portalu `meteo.imgw.pl` przez `/api/imgw-current`.
|
||||
|
||||
Normalizacja w `lib/imgw-current-api.ts`:
|
||||
|
||||
- bierze pod uwagę tylko rekordy `Type_Ten_Minutes` i `Type_Hour`,
|
||||
- wymaga realnych wartości liczbowych dla pełnego rekordu pogodowego,
|
||||
- nie traktuje `null` jako kompletnej wartości,
|
||||
- preferuje pełny rekord 10-minutowy,
|
||||
- jeśli pełny rekord 10-minutowy jest o ponad 2 godziny starszy od pełnego rekordu godzinowego, wybiera świeższy rekord godzinowy,
|
||||
- zachowuje lokalny opad MERGE jako częściową analizę, jeśli nie ma pełnych parametrów.
|
||||
|
||||
Jeśli Hybrid nie dostarcza pełnych danych, UI jawnie korzysta z fallbacku `synop`. Gdy najbliższa stacja jest oddalona o co najmniej 30 km, aplikacja ostrzega, że lokalne warunki mogą się różnić.
|
||||
|
||||
## Prognoza Modelowa
|
||||
|
||||
Route handler `/api/forecast` pobiera równolegle:
|
||||
|
||||
- pełne 7 dni Open-Meteo,
|
||||
- godzinowe IMGW ALARO.
|
||||
|
||||
W godzinach pokrytych przez ALARO parametry IMGW mają pierwszeństwo. Open-Meteo dostarcza prawdopodobieństwo opadu i dalszy horyzont do 7 dni. Awaria ALARO pozostawia działający fallback Open-Meteo.
|
||||
|
||||
Dashboard pokazuje:
|
||||
|
||||
- regułowy brief dnia,
|
||||
- najbliższe 24 przyszłe godziny,
|
||||
- wykresy pełnego bieżącego dnia.
|
||||
|
||||
Widok szczegółowy dnia korzysta z pełnego zestawu godzin dla wybranej daty.
|
||||
|
||||
## Ostrzeżenia
|
||||
|
||||
Ostrzeżenia meteorologiczne IMGW zawierają kody powiatów TERYT. Ostrzeżenia hydrologiczne zawierają jawne województwa. Normalizacja odbywa się przez `lib/provinces.ts` i `lib/warning-regions.ts`.
|
||||
|
||||
Zasady UI:
|
||||
|
||||
- lokalny obszar jest priorytetyzowany,
|
||||
- ostrzeżenia meteo są pokazywane przed hydrologicznymi,
|
||||
- jeśli lokalizacja ma powiat TERYT, meteo jest filtrowane po powiecie,
|
||||
- jeśli powiat nie jest znany, stosowany jest fallback wojewódzki,
|
||||
- dashboard pokazuje kompaktowo tylko aktywne i nadchodzące ostrzeżenia meteo dla wybranego obszaru,
|
||||
- wygasłe ostrzeżenia są filtrowane po `validTo` względem czasu przeglądarki.
|
||||
|
||||
## Briefy
|
||||
|
||||
Brief dnia i brief na jutro są generowane deterministycznie w `lib/weather-brief.ts`. Nie są odpowiedzią modelu AI i nie wymagają klucza OpenAI API.
|
||||
|
||||
Brief dnia analizuje najbliższe 24 godziny prognozy modelowej oraz aktywne i nadchodzące ostrzeżenia meteo dla obszaru użytkownika.
|
||||
|
||||
Brief na jutro analizuje pełny jutrzejszy dzień prognozy. Może informować o burzach na podstawie kodów pogodowych modelu nawet wtedy, gdy IMGW nie opublikowało oficjalnego ostrzeżenia.
|
||||
|
||||
## Opad i Pomiary Synoptyczne
|
||||
|
||||
Pole `synop.suma_opadu` jest akumulowaną sumą opadu. Nie oznacza, że pada w tej chwili, i nie steruje animacją deszczu.
|
||||
|
||||
IMGW Hybrid dostarcza m.in. opad 10-minutowy. Ten parametr jest prezentowany oddzielnie od akumulowanej sumy opadu stacji.
|
||||
|
||||
## Stany Pogody
|
||||
|
||||
Prognoza godzinowa i dzienna rozpoznaje:
|
||||
|
||||
| Stan | Opis w interfejsie |
|
||||
| --- | --- |
|
||||
| `clear` | Bezchmurnie |
|
||||
| `partlyCloudy` | Częściowe zachmurzenie |
|
||||
| `cloudy` | Pochmurno |
|
||||
| `fog` | Mgła |
|
||||
| `drizzle` | Mżawka |
|
||||
| `rain` | Opady deszczu |
|
||||
| `snow` | Opady śniegu |
|
||||
| `thunderstorm` | Burza |
|
||||
| `unknown` | Brak opisu |
|
||||
|
||||
Bieżąca analiza IMGW Hybrid rozpoznaje bezpośrednio opad deszczu, śnieg i burzę. Gdy żadne z tych zjawisk nie występuje, hero może pokazać pomocniczy opis: `Silny wiatr`, `Wilgotne warunki` albo `Spokojne warunki`.
|
||||
|
||||
## Mood i Efekty Wizualne
|
||||
|
||||
Hero aktualnej pogody używa uproszczonego moodu do wyboru ikony, tekstu i małego akcentu stanu.
|
||||
|
||||
| Mood | Reguła |
|
||||
| --- | --- |
|
||||
| `night` | godzina przed `06:00` lub od `21:00` |
|
||||
| `wind` | wiatr od `8 m/s` |
|
||||
| `cold` | temperatura do `3°C` |
|
||||
| `cloudy` | wilgotność od `80%` |
|
||||
| `warm` | temperatura od `20°C` |
|
||||
| `mild` | pozostałe przypadki |
|
||||
|
||||
Warstwa efektów wizualnych jest ograniczona do subtelnych efektów informacyjnych: kropli przy lokalnym opadzie oraz błysku przy burzy. Mood hero jest heurystyką, a nie pełną klasyfikacją sterowaną kodem warunków IMGW Hybrid.
|
||||
Reference in New Issue
Block a user