Files
servicedesk/README.md
Kacper 13a758779d
Some checks failed
Build and push image / build (push) Failing after 3m17s
v1.0.1
Documentation overhaul (TESTING/CONTRIBUTING/ARCHITECTURE/SECURITY/CLAUDE.md,
CHANGELOG.md, drop unmaintained src/README.md) plus CI-built Docker images:
Gitea Actions now builds and pushes the servicedesk image to the Gitea
container registry on Dockerfile changes, and compose.yaml pulls that image
instead of building locally. No application behavior changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 01:29:43 +02:00

6.5 KiB

Servicedesk

Helpdesk / ticketing system built with Laravel + Livewire (Polish UI). Clients submit support tickets, operators triage and resolve them inside team queues, and admins configure everything else — categories, SLA rules, templates, branding, LDAP/SMTP, and a REST API for external integrations.

Roles & areas

The app has three areas, gated by role (a user can hold more than one at once):

Area Route prefix Who What they do
Client /client client Submit tickets, track status, reply, see resolution
Operator /operator operator Work the ticket queue, reply/resolve, see team statistics
Admin /admin admin Configure categories, users, teams, SLA, templates, branding, LDAP/SMTP

Every account gets the client role by default (see AssignDefaultRole for LDAP-provisioned accounts), and always lands on /client first after login regardless of what other roles it also holds — staff switch into Operator/Admin via the role switcher in the header. See wiki/client, wiki/operator, and wiki/admin for role-specific how-to guides.

Feature overview

  • Tickets — number, subject, body, category/subcategory, status, priority, team, assignee, custom fields (per subcategory), attachments, full message thread (public replies + internal notes), history log, merge, delete.
  • SLA — per-priority response/resolution time targets; a scheduled command (tickets:check-sla-breaches, every 15 min) flags overdue tickets and can notify the assigned operator.
  • Categories & custom fields — admin-defined categories/subcategories, each with its own set of custom fields (text/textarea/select/checkbox/date/number) and an optional default priority.
  • Teams — subcategories auto-route to a team; operators only see their own team's queue (plus unrouted tickets and anything assigned to them) unless they're an admin.
  • Templates — canned response snippets for the reply box, admin-configurable "quick actions" (send + transition status in one click), and HTML e-mail templates for every ticket lifecycle event (created, status/priority/category/ team changed, closed, operator replied, SLA breached), each independently enable/disable-able.
  • Operator statistics (/operator/stats) — filterable dashboard (date range, team, priority, category, assignee) with KPI tiles (volume, SLA breach rate, average first-response/resolution time) and breakdowns by status, priority, category, team and operator workload, plus a daily created-vs-closed trend.
  • Branding & config — company name/logo/favicon/accent color, login notice, e-mail layout/footer, LDAP connection + user sync, SMTP connection, attachment limits, session lifetime, timezone — all editable from Admin > Konfiguracja.
  • LDAP auth — logins bind against an LDAP/LLDAP directory (config/auth.php, config/ldap.php); local accounts (e.g. the emergency admin account) fall back to e-mail + local password when the LDAP bind doesn't match.
  • REST API (/api/v1/..., Sanctum token auth, ability-scoped: tickets:read, tickets:write, dictionaries:read, users:read) for tickets/messages/users/ categories/statuses/priorities/teams — issued via admin-managed API clients. Interactive docs (L5-Swagger) at /admin/api-docs.
  • PWA — installable manifest + icons for the client-facing area.

Tech stack

  • Backend: Laravel, Livewire (server-driven UI, no SPA build beyond Tailwind/Vite for CSS), LdapRecord for directory auth, Sanctum for API tokens, L5-Swagger for API docs.
  • Frontend: Blade + Livewire + a little Alpine.js for local UI state; Tailwind v4 via Vite for resources/css/app.css. No JS charting library — the statistics dashboard is hand-rolled inline-styled bar/column charts, so it needs no client build step beyond the CSS bundle.
  • Database: MariaDB.
  • Deployment: compose.yamlservicedesk (source bind-mounted from ./src, no image rebuild needed for PHP/Blade/route changes) + mariadb, fronted by Traefik with a private-CA TLS cert. The servicedesk image itself is built and pushed by Gitea Actions (.gitea/workflows/build.yml) to the Gitea container registry whenever Dockerfile changes — compose.yaml just pulls a tag, it never builds locally.

See install.md for full step-by-step deployment instructions — both via Docker Compose (this stack) and directly on a server with Apache/Nginx, including which .env values to set (there are two separate .env files — Compose-level and Laravel-level) and the LDAP/SMTP gotcha after a fresh seed.

Local/dev notes

  • The app container mounts ./src directly — editing PHP/Blade/routes takes effect immediately, no rebuild or restart needed.
  • CSS/JS changes under resources/ do need a Vite build. Neither the host nor the app container has Node installed; rebuild with a throwaway container instead of rebuilding the app image:
    sudo docker run --rm -v "$(pwd)/src":/app -w /app node:22 npm run build
    
  • Fresh install / reset:
    sudo docker exec servicedesk-servicedesk-1 php artisan migrate:fresh --seed
    
    Seeds real reference data (categories, custom fields, statuses/priorities/SLA, teams, quick actions, response/e-mail templates, branding/config with example SMTP+LDAP placeholders) and a single local fallback account, admin@example.com / admin — replace its password and/or the SMTP/LDAP settings before relying on this in anything but a lab environment.

Project layout

src/                     Laravel application
  app/Livewire/          Client/Operator/Admin Livewire components
  app/Models/            Eloquent models
  app/Services/          TicketService (ticket lifecycle + notifications)
  app/Ldap/              LDAP user model + sync handlers
  database/migrations/   Schema (one file per table group, final shape)
  database/seeders/      DatabaseSeeder — reference data, no ticket data
  resources/css/         Tailwind entrypoint (needs `npm run build` after edits)
  resources/views/       Blade templates
  routes/web.php         Client/Operator/Admin routes (role-gated)
  routes/api.php         REST API (Sanctum, ability-gated)
wiki/
  client/                How-to guide for the Client role
  operator/               How-to guide for the Operator role
  admin/                  How-to guide for the Admin role