Files
servicedesk/README.md
2025-10-29 21:09:27 +01:00

209 lines
11 KiB
Markdown
Raw 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.
# Routing MVC — Helpdesk
Dokument zawiera zaprojektowany routing dla systemu helpdesk w architekturze MVC. Zawiera: opis autoryzacji, middleware, nazwy tras, metody HTTP, kontrolery i akcje oraz dodatkowe propozycje (API, webhooki, testy integracji).
---
## Założenia ogólne
* System ma trzy główne role: `guest` (niezalogowany), `customer` (zalogowany klient), `agent` (wsparcie/operator), `admin` (pełne uprawnienia). Rolę `customer` i `agent` mogą być różne grupy/role w LDAP.
* Logowanie przez LDAP (endpoint do testu i konfiguracji w panelu admina).
* Tworzenie zgłoszeń możliwe bez logowania **tylko** dla osób, które posiadają już konto — weryfikacja po polu `email` (wysłanie jednorazowego linku/weryfikacja tokenem). Gość może utworzyć zgłoszenie po pozytywnej weryfikacji email.
* RESTful approach dla zasobów: `tickets`, `users`, `categories`, `groups`, `roles`, `custom_fields`, `integrations`, `comments`, `attachments`.
* Wszystkie wrażliwe akcje wymagają CSRF tokenów (formularze) i uwierzytelnienia.
---
## Middleware
* `Auth` — sprawdza zalogowanego użytkownika.
* `GuestOnly` — dostępne tylko dla niezalogowanych (np. formularz tworzenia zgłoszenia bez logowania + weryfikacja email).
* `Role:admin` — tylko admin.
* `Role:agent` — agent lub admin.
* `RateLimit` — ochrona endpointów publicznych (np. tworzenie zgłoszeń bez logowania, endpointy API publiczne).
* `VerifyEmailToken` — walidacja tokenu przy tworzeniu zgłoszenia przez gościa.
* `CanViewTicket` — sprawdza czy dany użytkownik/agent ma prawo przeglądać zgłoszenie.
---
## Schemat tras (ważniejsze)
> Notacja: [METODA] /ścieżka -> Kontroler@akcja (nazwa_trasy) — uprawnienia / uwagi
### Autoryzacja i sesje
* [GET] /login -> AuthController@showLoginForm (auth.login) — guest
* [POST] /login -> AuthController@login (auth.login.post) — guest (LDAP)
* [POST] /logout -> AuthController@logout (auth.logout) — auth
* [GET] /ldap/test -> Admin\IntegrationController@testLdap (admin.ldap.test) — role:admin
### Publiczne (gość) — tworzenie zgłoszeń z weryfikacją email
* [GET] /ticket/new -> PublicTicketController@showCreateForm (public.ticket.new) — guest
* [POST] /ticket/verify-email -> PublicTicketController@requestEmailVerification (public.ticket.verify-email) — guest
* body: { email }
* akcja: jeśli email istnieje w DB -> wyślij e-mail z jednorazowym tokenem; jeśli nie istnieje -> odrzuć
* [GET] /ticket/verify?token=... -> PublicTicketController@verifyToken (public.ticket.verify) — guest, VerifyEmailToken
* [POST] /ticket/create -> PublicTicketController@create (public.ticket.create) — guest (po VerifyEmailToken) lub auth
* [GET] /ticket/{id}/view-public -> PublicTicketController@publicView (public.ticket.view) — możliwe ograniczone, jeśli ticket jest publiczny lub token w URL
> Uwaga: Po weryfikacji email dla gościa powinna powstać tymczasowa sesja (może krótkotrwały cookie) pozwalająca na dokończenie zgłoszenia.
### Klient (Customer) panel klienta
* [GET] /client/dashboard -> Client\DashboardController@index (client.dashboard) — auth, role:customer
* [GET] /client/tickets -> Client\TicketController@index (client.tickets) — auth, filtr: open/closed
* [GET] /client/tickets?status=open -> Client\TicketController@index (client.tickets.open)
* [GET] /client/tickets/{id} -> Client\TicketController@show (client.ticket.show) — auth, CanViewTicket
* [GET] /client/tickets/new -> Client\TicketController@createForm (client.ticket.new) — auth
* [POST] /client/tickets -> Client\TicketController@store (client.ticket.store) — auth
* [POST] /client/tickets/{id}/comment -> Client\TicketController@addComment (client.ticket.comment) — auth, CanViewTicket
* [POST] /client/tickets/{id}/attachments -> Client\AttachmentController@upload (client.attachment.upload) — auth
### Agent (wsparcie)
* [GET] /agent/dashboard -> Agent\DashboardController@index (agent.dashboard) — role:agent
* [GET] /agent/tickets -> Agent\TicketController@index (agent.tickets) — role:agent (filtry: assigned, unassigned, priority)
* [GET] /agent/tickets/{id} -> Agent\TicketController@show (agent.ticket.show) — role:agent, CanViewTicket
* [POST] /agent/tickets/{id}/assign -> Agent\TicketController@assign (agent.ticket.assign) — role:agent
* [POST] /agent/tickets/{id}/status -> Agent\TicketController@changeStatus (agent.ticket.status) — role:agent
* [POST] /agent/tickets/{id}/comment -> Agent\TicketController@addComment (agent.ticket.comment) — role:agent
* [POST] /agent/tickets/{id}/private-note -> Agent\TicketController@addPrivateNote (agent.ticket.private_note) — role:agent
### Admin
* [GET] /admin -> Admin\DashboardController@index (admin.dashboard) — role:admin
**Zarządzanie użytkownikami**
* [GET] /admin/users -> Admin\UserController@index (admin.users)
* [GET] /admin/users/new -> Admin\UserController@createForm (admin.users.new)
* [POST] /admin/users -> Admin\UserController@store (admin.users.store)
* [GET] /admin/users/{id} -> Admin\UserController@show (admin.users.show)
* [PUT] /admin/users/{id} -> Admin\UserController@update (admin.users.update)
* [DELETE]/admin/users/{id} -> Admin\UserController@destroy (admin.users.delete)
* [POST] /admin/users/{id}/sync-ldap -> Admin\UserController@syncFromLdap (admin.users.sync) — test/merge
**Integracje (LDAP, SMTP)**
* [GET] /admin/integrations -> Admin\IntegrationController@index (admin.integrations)
* [GET] /admin/integrations/new -> Admin\IntegrationController@createForm (admin.integration.new)
* [POST] /admin/integrations -> Admin\IntegrationController@store (admin.integration.store)
* [GET] /admin/integrations/{id}/edit -> Admin\IntegrationController@edit (admin.integration.edit)
* [PUT] /admin/integrations/{id} -> Admin\IntegrationController@update (admin.integration.update)
* [POST] /admin/integrations/{id}/test -> Admin\IntegrationController@test (admin.integration.test) — np. test LDAP bind, test SMTP send
**Kategorie, Grupy, Role**
* RESTful routes: `/admin/categories`, `/admin/groups`, `/admin/roles` — CRUD (index,new,store,show,edit,update,destroy)
**Custom Fields (jak Zammad)**
* [GET] /admin/custom-fields -> Admin\CustomFieldController@index (admin.custom_fields)
* [GET] /admin/custom-fields/new -> Admin\CustomFieldController@createForm
* [POST] /admin/custom-fields -> Admin\CustomFieldController@store
* [GET] /admin/custom-fields/{id}/edit -> Admin\CustomFieldController@edit
* [PUT] /admin/custom-fields/{id} -> Admin\CustomFieldController@update
* [DELETE]/admin/custom-fields/{id} -> Admin\CustomFieldController@destroy
---
## API (REST) — przydatne dla integracji i frontend SPA
> Prefiks: `/api/v1` — zwraca JSON, zabezpieczone tokenem (OAuth2/JWT) lub kluczem API
* [POST] /api/v1/tickets -> Api\TicketController@create — public (z limitem) lub z tokenem
* [GET] /api/v1/tickets -> Api\TicketController@index — auth
* [GET] /api/v1/tickets/{id} -> Api\TicketController@show
* [POST] /api/v1/tickets/{id}/comments -> Api\CommentController@store
* [GET] /api/v1/users -> Api\UserController@index
* [POST] /api/v1/webhooks -> Api\WebhookController@receive — do obsługi zewnętrznych systemów
---
## Webhooky / powiadomienia
* [POST] /webhook/ticket-updated -> WebhookController@ticketUpdated — obsługa wysyłania powiadomień do zewnętrznych systemów (możliwość konfiguracji w integracjach).
* [POST] /webhook/email-reply -> WebhookController@emailReply — odbiór odpowiedzi z maila (parse i przypisz do ticketu)
---
## Proponowane dodatkowe trasy i funkcje użyteczne
* `/search` (GET) -> globalne wyszukiwanie ticketów, użytkowników, załączników.
* `/reports` (admin) -> eksport CSV/PDF statystyk (liczba zgłoszeń, SLA, średni czas odpowiedzi).
* `/settings` (admin) -> ogólne ustawienia aplikacji.
* `/attachments/{id}/download` -> bezpieczne pobieranie plików (signed URL lub autoryzacja).
* `/tickets/{id}/share` -> generowanie publicznego linku do ticketu (czasowy token).
* `/kb` -> baza wiedzy (opcjonalna) — artykuły, kategorie, tagi.
---
## Przykładowa implementacja (Laravel-like) — fragmenty
```php
// Public
Route::get('/ticket/new', 'PublicTicketController@showCreateForm')->name('public.ticket.new');
Route::post('/ticket/verify-email', 'PublicTicketController@requestEmailVerification')->name('public.ticket.verify-email');
Route::get('/ticket/verify', 'PublicTicketController@verifyToken')->name('public.ticket.verify');
Route::post('/ticket/create', 'PublicTicketController@create')->name('public.ticket.create');
// Auth
Route::get('/login', 'AuthController@showLoginForm')->middleware('guest')->name('auth.login');
Route::post('/login', 'AuthController@login')->middleware('guest');
Route::post('/logout', 'AuthController@logout')->middleware('auth')->name('auth.logout');
// Client
Route::group(['prefix'=>'client','middleware'=>['auth','role:customer']], function(){
Route::get('dashboard','Client\\DashboardController@index')->name('client.dashboard');
Route::resource('tickets','Client\\TicketController');
});
// Agent
Route::group(['prefix'=>'agent','middleware'=>['auth','role:agent']], function(){
Route::get('dashboard','Agent\\DashboardController@index')->name('agent.dashboard');
Route::resource('tickets','Agent\\TicketController');
});
// Admin
Route::group(['prefix'=>'admin','middleware'=>['auth','role:admin']], function(){
Route::get('/','Admin\\DashboardController@index')->name('admin.dashboard');
Route::resource('users','Admin\\UserController');
Route::resource('integrations','Admin\\IntegrationController');
Route::resource('categories','Admin\\CategoryController');
Route::resource('groups','Admin\\GroupController');
Route::resource('roles','Admin\\RoleController');
Route::resource('custom-fields','Admin\\CustomFieldController');
});
// API
Route::prefix('api/v1')->group(function(){
Route::post('tickets','Api\\TicketController@create');
Route::get('tickets','Api\\TicketController@index');
});
```
---
## Uwagi dotyczące bezpieczeństwa i UX
1. Formularze tworzenia zgłoszeń dla gości: wymuszaj CAPTCHA + rate-limiting + weryfikację email.
2. Token weryfikacyjny powinien być jednorazowy i krótko ważny (np. 1560 minut).
3. Przy publicznym przeglądaniu ticketu — nie ujawniaj danych wrażliwych bez autoryzacji.
4. Wszystkie pobierania załączników przez publiczne linki — używaj signed URLs z datą wygaśnięcia.
5. Dla API rozważ OAuth2 lub JWT + scope (np. `tickets.read`, `tickets.write`).
6. Loguj wszystkie akcje administracyjne (audyt).
---
## Co mogę zrobić dalej (opcjonalnie)
* Wygenerować gotowy plik routingu `routes/web.php` dla Laravel/Lumen.
* Przygotować specyfikację API (OpenAPI/Swagger) dla `api/v1`.
* Wygenerować przykładowe kontrolery i middleware skeletony.
---
Jeżeli chcesz, w następnym kroku wygeneruję konkretną implementację routingu dla wybranego frameworka (np. Laravel, Slim, Symfony).