v1.1.2
- Real-time updates (Laravel Reverb): live operator queue, live ticket chat/detail updates for operator and client, periodic fallback refresh with a visible countdown as a backstop for dropped websocket connections. - SLA automation rules (Admin > Automatyzacja SLA): act on a ticket after N minutes of customer silence (change priority/status/team/assignee), evaluated every 15 minutes, reusing TicketService's own setters so automated changes get the same history/notification/broadcast a manual change would. - New notification: every operator on a matching team gets notified when a new ticket lands in one of their subcategories. - BookStack knowledge-base sidebar now also shown on the client's own ticket view (previously operator-only); suggestions everywhere now load in after first paint instead of blocking it. - Client ticket view: shows assigned operator + team; page widened to match the operator's. - Notification bell shows unread only; read notifications disappear instead of just dimming. - Stats dashboard: sectioned layout, new breakdowns (by subcategory, CSAT by team/operator, top clients, client x subcategory cross-tab). - Mobile: nav dropdowns (theme/notifications/profile) now expand full width instead of overflowing off-screen below 640px. - Fixed two bugs that silently disabled all real-time updates (missing CSRF header on Echo's private-channel auth; a script-load-order race that could miss the livewire:init event) and the mariadb healthcheck (world-writable credentials file on this stack's NFS mount). - Assorted test-suite fixes (roles virtual attribute needs the roles table seeded; a few missing seeds/wrong assertions found along the way). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
98
install.md
98
install.md
@@ -74,7 +74,7 @@ APP_LOCALE=pl
|
||||
APP_FALLBACK_LOCALE=pl
|
||||
|
||||
AUTHOR_CONTACT=helpdesk@twoja-domena.pl # widoczne w Admin > O aplikacji
|
||||
VERSION=1.1.0 # rezerwa na przyszłość, jeszcze nigdzie nie wyświetlane
|
||||
VERSION=1.1.2 # widoczne w Admin > O aplikacji
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mariadb # nazwa serwisu z compose.yaml, NIE 127.0.0.1
|
||||
@@ -173,6 +173,70 @@ obrazu `servicedesk`) — poczekaj, aż workflow CI przejdzie choć raz (np. prz
|
||||
push/PR zmieniający `Dockerfile`, albo ręczne odpalenie z zakładki Actions w
|
||||
Gitea), zanim spróbujesz `docker compose pull` na serwerze.
|
||||
|
||||
### 1.3b. Real-time (Laravel Reverb)
|
||||
|
||||
Realtime (kolejka operatora, czat na żywo) wymaga trzeciej usługi w
|
||||
`compose.yaml`, `reverb` — tego samego obrazu `servicedesk`, tylko z innym
|
||||
`command: php artisan reverb:start --host=0.0.0.0 --port=8080`. Obraz musi
|
||||
mieć rozszerzenia PHP `pcntl`/`posix` (potrzebne serwerowi Reverb do obsługi
|
||||
sygnałów) — jeśli `Dockerfile` ich nie instaluje, `reverb` będzie się zapętlać
|
||||
w restartach z błędem `Undefined constant "...SIGINT"`; dodaj `pcntl posix` do
|
||||
listy w `docker-php-ext-install` i poczekaj na przebudowanie obrazu przez CI.
|
||||
|
||||
Traefik musi kierować ścieżkę websocketu (`/app*`) do `reverb`, a resztę do
|
||||
`servicedesk` — na tej samej domenie, więc bez dodatkowego wpisu DNS/certyfikatu:
|
||||
|
||||
```yaml
|
||||
reverb:
|
||||
image: gitea.kzbikowski.pl/kzbkowski/servicedesk:${IMAGE_TAG:-latest}
|
||||
command: php artisan reverb:start --host=0.0.0.0 --port=8080
|
||||
volumes:
|
||||
- ./src:/var/www/html
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
mariadb:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- internal
|
||||
- traefik_public
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik_public
|
||||
- traefik.http.routers.reverb.rule=Host(`${HOSTNAME}`) && PathPrefix(`/app`)
|
||||
- traefik.http.routers.reverb.priority=1000
|
||||
- traefik.http.routers.reverb.entrypoints=websecure
|
||||
- traefik.http.routers.reverb.tls=true
|
||||
- traefik.http.services.reverb.loadbalancer.server.port=8080
|
||||
```
|
||||
|
||||
`priority=1000` jest ważne — Traefik domyślnie liczy priorytet reguły na
|
||||
podstawie długości jej zapisu, co może dać samemu `Host(...)` z `servicedesk`
|
||||
wyższy priorytet niż oczekiwano, przez co ścieżkowa reguła `reverb` przegrywa i
|
||||
nic nie działa mimo poprawnej konfiguracji.
|
||||
|
||||
W `src/.env` — `BROADCAST_CONNECTION=reverb` plus:
|
||||
|
||||
```env
|
||||
REVERB_APP_ID=wygeneruj-losowy-id
|
||||
REVERB_APP_KEY=wygeneruj-losowy-klucz
|
||||
REVERB_APP_SECRET=wygeneruj-losowy-sekret
|
||||
REVERB_HOST=reverb # nazwa usługi compose — ruch serwer-serwer po sieci internal
|
||||
REVERB_PORT=8080
|
||||
REVERB_SCHEME=http
|
||||
|
||||
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
|
||||
VITE_REVERB_HOST=servicedesk.twoja-domena.pl # publiczna domena — to, z czym łączy się przeglądarka
|
||||
VITE_REVERB_PORT=443
|
||||
VITE_REVERB_SCHEME=https
|
||||
```
|
||||
|
||||
`REVERB_HOST` (serwer→serwer, wewnętrzna sieć Docker) i `VITE_REVERB_HOST`
|
||||
(przeglądarka→Traefik, publiczna domena) to celowo dwie różne wartości —
|
||||
pomylenie ich to najczęstszy błąd przy pierwszym wdrożeniu tej funkcji.
|
||||
|
||||
Po zmianie zmiennych `VITE_REVERB_*` trzeba przebudować front-end (krok 1.5) —
|
||||
te wartości są wypiekane w zbudowany bundle JS, nie czytane w runtime.
|
||||
|
||||
### 1.4. Instalacja aplikacji wewnątrz kontenera
|
||||
|
||||
```bash
|
||||
@@ -285,7 +349,7 @@ APP_LOCALE=pl
|
||||
APP_FALLBACK_LOCALE=pl
|
||||
|
||||
AUTHOR_CONTACT=helpdesk@twoja-domena.pl
|
||||
VERSION=1.1.0
|
||||
VERSION=1.1.2
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1 # albo adres IP/hostname prawdziwego serwera DB
|
||||
@@ -405,6 +469,36 @@ Jak w wersji Docker — kolejka (`php artisan queue:work`) nie jest obowiązkowa
|
||||
skoro powiadomienia wysyłają się synchronicznie; zostaw `QUEUE_CONNECTION=database`
|
||||
jako bezpieczny domyślny driver na przyszłość.
|
||||
|
||||
Realtime (patrz 1.3b) potrzebuje tu **długo działającego procesu**
|
||||
`php artisan reverb:start` — PHP musi mieć rozszerzenia `pcntl`/`posix`
|
||||
(standardowo dostępne, ale sprawdź `php -m`). Najprościej pod systemd:
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/servicedesk-reverb.service
|
||||
[Unit]
|
||||
Description=Servicedesk Reverb websocket server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=www-data
|
||||
WorkingDirectory=/var/www/servicedesk/src
|
||||
ExecStart=/usr/bin/php artisan reverb:start --host=0.0.0.0 --port=8080
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
systemctl enable --now servicedesk-reverb
|
||||
```
|
||||
|
||||
Ustaw też te same zmienne `.env` co w 1.3b (`BROADCAST_CONNECTION=reverb`,
|
||||
`REVERB_*`, `VITE_REVERB_*` — tu `REVERB_HOST` to po prostu `127.0.0.1`, nie
|
||||
nazwa usługi compose) i skieruj serwer WWW tak, by ścieżka `/app*` trafiała do
|
||||
portu 8080 zamiast do PHP-FPM/Apache (osobny `location`/`VirtualHost` dla tej
|
||||
jednej ścieżki, analogicznie do reguły Traefika w 1.3b).
|
||||
|
||||
### 2.7. Pierwsze logowanie i dalsza konfiguracja
|
||||
|
||||
Identycznie jak w kroku 1.6 — zaloguj się `admin@example.com` / `admin`, zmień
|
||||
|
||||
Reference in New Issue
Block a user