Files
servicedesk/CHANGELOG.md
Kacper 0b06687ea1 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>
2026-07-22 20:43:05 +02:00

202 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to this project are documented in this file. Format loosely
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [1.1.2] - 2026-07-22
### Added
- **Real-time updates (Laravel Reverb)** — the operator ticket queue now
updates live: new tickets appear, status/priority/team/assignee changes
and new replies re-sort/refresh the affected row, and closed/deleted/
reassigned-away tickets disappear, all without a manual refresh. The
ticket message thread is now "live chat": a reply from either side
appears for the other party instantly. Clients also see status/priority/
team/assignee changes and new history entries on their own ticket live.
Backed by two private channels (`operator.queue`, `ticket.{id}`) and two
broadcast events (`TicketQueueChanged`, `TicketMessagePosted`), sent
synchronously (no queue worker needed, consistent with how e-mail
notifications already work in this app).
- **Periodic fallback refresh** — since a websocket connection can drop
silently (backgrounded tab, network blip), the operator queue and both
ticket-detail views also poll themselves every 3060 seconds regardless
of broadcasting, with a small visible countdown badge so it's clear the
page is still refreshing on its own.
- **SLA automation rules** (Admin > Automatyzacja SLA) — configurable rules
that act on a ticket after N minutes of customer silence (optionally
scoped to a priority/category/team): change priority, status, team, or
assignee. Reuses the same `TicketService` setters a manual operator
action would, so automated changes get the same history entry,
notification, and (now) live broadcast as a human doing it. A new
scheduled command (`automation:run-rules`, every 15 minutes) evaluates
all enabled rules; each rule only fires once per ticket until a fresh
reply or a close/reopen resets it.
- **New notification: ticket landed in your team** — every operator on a
team whose subcategories match a newly created ticket now gets notified
(enabled by default; toggle like any other trigger in Admin > Szablony
e-mail).
- **BookStack knowledge-base sidebar on the client's own ticket view** —
previously only shown to operators; clients now see the same
category/subcategory-matched suggestions on their ticket page that they
saw while creating it.
- **Operator ticket view / client ticket view now show the assigned
operator and team** in the "Status i priorytet" card (client side).
- **Stats dashboard**: new breakdowns — tickets by subcategory, CSAT
average by team and by operator, top 10 clients by ticket volume (+ one
"Goście" bucket for guest submissions), and a client × subcategory
cross-tab (top 10 clients × top 5 subcategories, rest folded into
"Inne"). The whole dashboard is now organized into labeled sections
(Podsumowanie / Rozkład zgłoszeń / Obciążenie / Klienci / Ocena obsługi /
Trend) instead of one flat wall of cards.
### Changed
- BookStack suggestions (ticket-creation wizards, guest landing page,
operator/client ticket views) now load in a beat after the page's first
paint (`wire:init`) instead of blocking the initial render on BookStack's
API response.
- The notification bell shows **unread notifications only** — reading one
(by clicking it or "mark all as read") now removes it from the list
instead of just dimming it.
- The client ticket-view page is now the same width as the operator's
(1180px, up from 920px) — the main message-thread column is unaffected.
- Mobile: the theme/notifications/profile-menu dropdowns in the top nav
now expand to the full screen width below 640px instead of a fixed
narrow width that could overflow off-screen.
### Fixed
- Two bugs that silently disabled all real-time updates from the moment
Reverb was first wired in: (1) the Echo client never sent a CSRF token
when authorizing private channels, so every subscription attempt was
rejected by the app's own CSRF middleware; (2) the Echo setup script
(loaded as a deferred ES module) raced against Livewire's own
synchronously-loaded bootstrap script and could miss the `livewire:init`
event entirely, silently skipping the operator-queue subscription.
- The `mariadb` container's healthcheck was failing (`Access denied ...
using password: NO`) because its auto-generated credentials file had
world-writable permissions (an artifact of this stack's NFS-backed bind
mount) and MariaDB's client refuses to read credentials from a file
anyone can modify — the healthcheck now passes.
- Several pre-existing test-suite gaps found while working in this area:
`User::roles` (a virtual attribute backed by the `roles`/`role_user`
pivot, not a plain column) needs the `roles` table seeded before
assigning a role by key — now seeded automatically for every test in
`Tests\TestCase`. A handful of other tests were missing
`NotificationSetting`/`ReplyQuickAction` seed data, asserting a stale set
of default-enabled notification triggers, or using the wrong Notification
Fake assertion for a real (non-guest) recipient.
## [1.1.0] - 2026-07-22
### Added
- **In-app notifications** — a bell in the top bar backed by Laravel's
database notification channel, alongside existing e-mail notifications
(same per-trigger toggle drives both; ticket links now correctly point into
the recipient's own area instead of always linking to the client view).
- **Drag-and-drop attachments** on every upload form (ticket creation, replies,
internal notes), plus inline image thumbnails in the message thread instead
of a plain download link.
- **Customer satisfaction (CSAT)** rating — clients rate a closed ticket 15
stars with an optional comment; shown read-only to operators, surfaced as a
KPI on the stats dashboard, and linked from the "ticket closed" e-mail.
- **Saved queue views** — operators can save/apply/delete named filter+sort+
column presets in the ticket queue and mark one as their default.
- **Full-text search** — MySQL/MariaDB `FULLTEXT` search (portable `LIKE`
fallback on sqlite) across ticket subject/body and reply message bodies, now
also available on the client's own ticket list (previously operator-only,
and previously subject/number/name/email only).
- **Stats CSV export** — exports the currently filtered ticket set from the
operator stats dashboard.
- **BookStack knowledge-base integration**, optional and off by default —
suggests relevant articles by category/subcategory while creating a ticket,
and in a separate sidebar on an existing ticket for operators (with a
copy-link button). Configurable from Admin > Konfiguracja: connection + API
token (encrypted), optional SSL-verification bypass for self-signed
instances, page/book search-type filter, and two independent per-shelf
allow-lists (nothing is ever searched until specific shelves are opted in,
separately for ticket-creation suggestions vs. the operator sidebar) with a
manual refresh button for the shelf list.
### Changed
- Closed tickets are no longer shown in the "Moje zgłoszenia" / "Nieprzypisane"
/ per-team queue tabs — they now only ever appear under "Zamknięte", matching
how the "Otwarte" tab already worked.
- The operator ticket-view sidebar is ~50% wider (to fit the BookStack
suggestions panel); the page itself grew to match, so the ticket
content/thread column keeps its previous width.
- The "Resetuj" work-timer button sits below the "Zgłoszenie zamknięte —
zliczanie wstrzymane" notice instead of beside it.
### Fixed
- `TicketService::setStatus()` now checks a status's `stage` (via
`Status::stageFor()`) rather than the literal key `'closed'` to decide
whether to fire the "ticket closed" notification/stop the timer — correct
even if an admin renames or replaces which key maps to the closed stage.
## [1.0.2] - 2026-07-22
- Fixed `.gitea/workflows/build.yml`: registry login was failing with
`unauthorized` because Gitea's auto-injected `secrets.GITHUB_TOKEN` isn't
granted push access to its own container registry on this instance. Now
uses a dedicated `REGISTRY_TOKEN` secret (a Gitea access token with
`write:package`/`read:package` scope), and the workflow fails fast with a
clear `::error::` message before attempting login if that secret isn't
configured, instead of surfacing Docker's opaque `unauthorized` error.
- Fixed: opening or manually resuming a **closed** ticket no longer starts its
work timer, and closing a ticket (via the status dropdown, a reply "quick
action" transition, the REST API, or merge) now checkpoints and stops any
running timer. Time tracking only ever accrues while a ticket is open.
- Fixed: the login form accepted an empty username/password, submitting them
straight to the auth provider. The form fields are now `required` (blocks
submission client-side) and `Login::submit()` also rejects blank/
whitespace-only credentials server-side before attempting authentication,
showing "Podaj nazwę użytkownika i hasło." instead.
- Fixed: closing a ticket sent two separate notification e-mails
(`status_changed` and `ticket_closed`) for the same event. Closing now only
fires `ticket_closed`; every other status transition still fires
`status_changed` as before.
## [1.0.1] - 2026-07-22
Documentation and deployment/CI overhaul — no application behavior changes.
- Added project docs: `TESTING.md`, `CONTRIBUTING.md`, `ARCHITECTURE.md`,
`SECURITY.md`, `CLAUDE.md`; removed the unmaintained stock Laravel
`src/README.md`.
- Added `.gitea/workflows/build.yml`: Gitea Actions now builds and pushes the
`servicedesk` image to the Gitea container registry whenever `Dockerfile`
changes on `main`.
- `compose.yaml` now pulls `image: gitea.kzbikowski.pl/kzbkowski/servicedesk:${IMAGE_TAG:-latest}`
instead of building locally; `mariadb` pinned to `mariadb:12.3`; added a
`mariadb` healthcheck and `depends_on: condition: service_healthy` for
`servicedesk`.
- Added tracked templates `compose.yaml.example` and `.env.example` (root) for
the previously-untracked `compose.yaml`/`.env`.
- Documented the new pull-based deploy flow and one-time registry login in
`install.md`.
## [1.0.0] - 2026-07-21
Initial release.
- Ticketing core: categories/subcategories with per-subcategory custom fields,
statuses, priorities, teams, attachments, message threads (public replies +
internal notes), history log, merge/delete.
- SLA rules per priority with a scheduled breach check (`tickets:check-sla-breaches`,
every 15 minutes).
- Response templates, quick actions, and per-event HTML email templates/
notification toggles.
- Operator statistics dashboard (`/operator/stats`) with KPI tiles and breakdowns.
- Branding/config panel: company identity, LDAP connection + user sync, SMTP,
attachment limits, session lifetime, timezone.
- LDAP authentication (LdapRecord) with local-account fallback.
- REST API (`/api/v1/...`) via Sanctum, ability-scoped (`tickets:read`,
`tickets:write`, `dictionaries:read`, `users:read`), with Swagger docs at
`/admin/api-docs`.
- Installable PWA manifest/icons for the client-facing area.