- Configurable ticket numbering (Admin > Konfiguracja > Ogólne): admin-set prefix and minimum zero-padded length for the ticket number. - "Ukryj kolejność zgłoszeń": an opt-in mode that displays a stable, HMAC-derived checksum instead of the sequential ticket number, so it gives no indication of ticket volume or creation order. Ticket URLs switch to the same checksum when this is on, so a link and the number on the page it points to always match. The REST API is unaffected — pinned to `id` regardless of this setting. Search now also matches by checksum. - Fixed: attachments no longer show an inline image thumbnail in the message thread — every attachment (images included) shows as just its filename, opening in a new tab on click. - Docs: README/ARCHITECTURE/wiki updated for all of the above. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
15 KiB
15 KiB
Changelog
All notable changes to this project are documented in this file. Format loosely follows Keep a Changelog.
[1.1.4] - 2026-07-23
Added
- Configurable ticket numbering (Admin > Konfiguracja > Ogólne) — an
admin-set prefix (default
#) and a minimum zero-padded length for the ticket number. - "Ukryj kolejność zgłoszeń" — an opt-in mode that displays a stable,
HMAC-derived checksum instead of the sequential ticket number, so the
number shown gives no indication of ticket volume or creation order. Every
ticket gets its checksum assigned once, on creation, guaranteed unique.
When this mode is on, ticket URLs switch to the same checksum too (custom
Ticket::getRouteKey()/resolveRouteBinding()), so a link and the number on the page it points to always match — and a URL built under the other mode stops resolving. The REST API is unaffected; it's pinned toidregardless of this setting. Search (queue/dashboard) now also matches against the checksum. A live preview against a real ticket from the database shows exactly how the number will look before saving.
Changed
- Attachments: dropped the inline image thumbnail preview in the message thread — every attachment (images included) now shows as just its filename, opening in a new tab on click, consistent with how non-image attachments already worked.
[1.1.3] - 2026-07-22
Added
- Triggers (Admin > Wyzwalacze) — event-driven business rules that fire immediately on a ticket lifecycle event (created, any field updated, status/ priority/assignee/team/category changed, new public reply). AND-combined conditions gate a sequence of ordered actions (set status/priority/team/ assignee, or send an e-mail). Ships with its own dedicated, freely add/edit/delete-able trigger e-mail templates — kept separate from the fixed, per-event system templates, which stay exactly as fixed as before. Complements the time-based SLA automation rules rather than replacing them, guarded against runaway loops (a depth limit plus a same-value no-op check).
- Ticket watching — operators can star/"Obserwuj" any ticket to follow it regardless of assignment or team.
- Real-time notification bell — the bell now updates the instant a notification is created (broadcast on a new private per-user channel), with the existing 30s poll kept as a fallback for a dropped websocket. Optionally also raises a native in-tab browser push notification.
- Per-user notification preferences (
/settings/notifications) — each operator/admin chooses, per event category (new ticket, ticket update, escalation), which scope of tickets (mine, unassigned, watched, all) notifies them via the bell and whether that also sends an e-mail, plus an opt-in toggle for the browser push notifications above. - Admin > Integracje — new tab hosting LDAP/AD and BookStack configuration, split out of Konfiguracja so that tab is just general system settings (attachments, session, timezone).
- Operator queue: three more optional columns (off by default, toggle via "Kolumny") — Podkategoria, Zespół, Utworzono.
Changed
- The "Obserwuj" button on the operator ticket view moved next to the auto-refresh countdown badge, both now grouped on the right.
/settings/notifications: added a "← Wróć" link back to the operator/admin area, the browser-push card now spans the full page width, and the preferences table sits in a bordered card like the rest of the app.- Trigger conditions on Podkategoria/Zgłaszający now show a name dropdown instead of a raw ID field.
- The admin panel's active tab and the operator queue's active view now persist across a plain page refresh (bound to the URL query string), so reloading no longer bounces back to the first tab.
[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 30–60 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
TicketServicesetters 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:initevent entirely, silently skipping the operator-queue subscription. - The
mariadbcontainer'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 theroles/role_userpivot, not a plain column) needs therolestable seeded before assigning a role by key — now seeded automatically for every test inTests\TestCase. A handful of other tests were missingNotificationSetting/ReplyQuickActionseed 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 1–5 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
FULLTEXTsearch (portableLIKEfallback 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'sstage(viaStatus::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 withunauthorizedbecause Gitea's auto-injectedsecrets.GITHUB_TOKENisn't granted push access to its own container registry on this instance. Now uses a dedicatedREGISTRY_TOKENsecret (a Gitea access token withwrite:package/read:packagescope), and the workflow fails fast with a clear::error::message before attempting login if that secret isn't configured, instead of surfacing Docker's opaqueunauthorizederror. - 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) andLogin::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_changedandticket_closed) for the same event. Closing now only firesticket_closed; every other status transition still firesstatus_changedas 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 Laravelsrc/README.md. - Added
.gitea/workflows/build.yml: Gitea Actions now builds and pushes theservicedeskimage to the Gitea container registry wheneverDockerfilechanges onmain. compose.yamlnow pullsimage: gitea.kzbikowski.pl/kzbkowski/servicedesk:${IMAGE_TAG:-latest}instead of building locally;mariadbpinned tomariadb:12.3; added amariadbhealthcheck anddepends_on: condition: service_healthyforservicedesk.- Added tracked templates
compose.yaml.exampleand.env.example(root) for the previously-untrackedcompose.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.