Przejdź do treści

Notatki (Note)

Ostatnia aktualizacja dokumentacji: 26 lutego 2026 Stan synchronizacji z kodem: Zsynchronizowany


1. Opis ogolny

Domena Notatek zarzadza wewnetrznymi komentarzami pracownikow dodawanymi do roznych encji w systemie. To jak karteczki samoprzylepne na dokumentach — pracownicy moga dodawac uwagi do klientow, rezerwacji, obiektow, zajec i reklamacji, ktore sa widoczne tylko dla zespolu. System zapewnia pelna historie zmian kazdej notatki (audit trail), przypinanie waznych notatek oraz specjalne oznaczanie notatek do wyswietlenia w rezerwacji.


2. Architektura domeny

2.1 Modele danych

Model Note

Aspekt Szczegoly
Klasa Domain\Note\Model\Note
Tabela notes
Klucz glowny UUID (id)
Traity HasUuids, TraitSupport, TraitNote
Observer NoteObserver (via #[ObservedBy])

Pola fillable:

Pole Typ Opis
notable_id string UUID encji nadrzednej (polimorficzny)
notable_type string Typ klasy encji nadrzednej (polimorficzny)
user_id string UUID autora notatki
content string Tresc notatki
is_pinned boolean Czy notatka jest przypieta
show_in_reservation boolean Czy wyswietlac w szczegolach rezerwacji

Relacje:

Relacja Typ Model docelowy Opis
notable() MorphTo dowolny z 5 typow Encja, do ktorej przypisana jest notatka
user() BelongsTo User Autor notatki
logs() HasMany NoteLog Historia zmian notatki

Model NoteLog

Aspekt Szczegoly
Klasa Domain\Note\Model\NoteLog
Tabela note_logs
Klucz glowny UUID (id)
Traity HasUuids, TraitSupport, TraitNote

Pola fillable:

Pole Typ Opis
note_id string UUID notatki
user_id string UUID uzytkownika, ktory dokonal zmiany
event_type string Typ zdarzenia: created lub updated
changes array\|null JSON ze zmianami (stara i nowa wartosc)

Relacje:

Relacja Typ Model docelowy
note() BelongsTo Note
user() BelongsTo User

2.2 Diagram relacji

erDiagram
    Note ||--o{ NoteLog : "ma historie zmian"
    Note }o--|| User : "autor"
    NoteLog }o--|| User : "wykonawca zmiany"
    Note }o--|| Client : "notatka do klienta"
    Note }o--|| Reservation : "notatka do rezerwacji"
    Note }o--|| Item : "notatka do obiektu"
    Note }o--|| Activity : "notatka do zajec"
    Note }o--|| Complaint : "notatka do reklamacji"

2.3 Struktura tabel w bazie danych

Tabela notes

Kolumna Typ Nullable Default Indeks Opis
id UUID Nie - PRIMARY Identyfikator notatki
notable_type string Nie - INDEX (composite z notable_id) Typ klasy encji nadrzednej
notable_id UUID Nie - INDEX (composite z notable_type) UUID encji nadrzednej
user_id UUID Nie - INDEX UUID autora
content text Nie - - Tresc notatki
is_pinned boolean Nie false INDEX Czy przypieta
show_in_reservation boolean Nie false INDEX Czy pokazac w rezerwacji
created_at timestamp Tak - - Data utworzenia
updated_at timestamp Tak - - Data ostatniej aktualizacji

Polimorfizm

Pola notable_type i notable_id tworza relacje polimorficzna (uuidMorphs). notable_type przechowuje pelna nazwe klasy modelu (np. Domain\Client\Model\Client), a notable_id — UUID rekordu w danej tabeli.

Tabela note_logs

Kolumna Typ Nullable Default Indeks Opis
id UUID Nie - PRIMARY Identyfikator wpisu logu
note_id UUID Nie - INDEX (composite z created_at) FK do notes.id (CASCADE DELETE)
user_id UUID Tak - INDEX FK do users.id (NULL ON DELETE)
event_type string(50) Nie - - Typ zdarzenia: created / updated
changes JSON Tak - - Szczegoly zmian (old/new)
created_at timestamp Tak - INDEX (composite z note_id) Data zdarzenia
updated_at timestamp Tak - - Data aktualizacji rekordu

3. Endpointy API

Wszystkie endpointy wymagaja uwierzytelnienia (JWT) i roli: ADMIN, SUPERVISOR lub EMPLOYEE.

Prefix: /api/notes

3.1 Lista notatek

GET /api/notes

  • Opis: Zwraca paginowana liste notatek z relacjami
  • Autoryzacja: Role: ADMIN, SUPERVISOR, EMPLOYEE
  • Route name: notes.index
  • Query Parameters: Standardowe parametry paginacji (page, per_page, filtry Spatie Query Builder)
  • Request: IndexNoteControllerRequest
  • Walidacja:
Pole Reguly
(paginacja) Domyslne reguly z paginationDefaultRequestRules()
  • Response (sukces — 200):

    {
      "data": [
        {
          "id": "uuid-notatki",
          "notable_type": "Domain\\Client\\Model\\Client",
          "notable_id": "uuid-klienta",
          "user_id": "uuid-pracownika",
          "content": "Staly klient, rabat 10%",
          "is_pinned": true,
          "show_in_reservation": false,
          "created_at": "2026-02-26 10:30:00",
          "updated_at": "2026-02-26 10:30:00",
          "can": {
            "view": true,
            "create": true,
            "update": true
          },
          "user": { "..." : "dane autora" },
          "notable": { "..." : "dane encji nadrzednej" },
          "logs": []
        }
      ],
      "links": { "..." : "paginacja" },
      "meta": { "..." : "metadane" }
    }
    

  • Zaladowane relacje: user, notable


3.2 Szczegoly notatki

GET /api/notes/{noteId}

  • Opis: Zwraca pojedyncza notatke z pelna historia zmian
  • Autoryzacja: Role: ADMIN, SUPERVISOR, EMPLOYEE
  • Parametry URL:
Parametr Typ Opis
noteId string (UUID) Identyfikator notatki
  • Response (sukces — 200):

    {
      "data": {
        "id": "uuid-notatki",
        "notable_type": "Domain\\Reservation\\Model\\Reservation",
        "notable_id": "uuid-rezerwacji",
        "user_id": "uuid-pracownika",
        "content": "Klient prosi o przygotowanie 50 krzesel",
        "is_pinned": false,
        "show_in_reservation": true,
        "created_at": "2026-02-26 10:30:00",
        "updated_at": "2026-02-26 11:00:00",
        "can": {
          "view": true,
          "create": true,
          "update": true
        },
        "user": { "..." : "dane autora" },
        "notable": { "..." : "dane rezerwacji" },
        "logs": [
          {
            "id": "uuid-logu",
            "note_id": "uuid-notatki",
            "user_id": "uuid-pracownika",
            "event_type": "created",
            "event_type_lang": "utworzony",
            "changes": null,
            "created_at": "2026-02-26 10:30:00",
            "user": { "..." : "dane uzytkownika" }
          },
          {
            "id": "uuid-logu-2",
            "note_id": "uuid-notatki",
            "user_id": "uuid-innego-pracownika",
            "event_type": "updated",
            "event_type_lang": "zaktualizowany",
            "changes": {
              "content": {
                "old": "Klient prosi o krzesla",
                "new": "Klient prosi o przygotowanie 50 krzesel"
              }
            },
            "created_at": "2026-02-26 11:00:00",
            "user": { "..." : "dane uzytkownika" }
          }
        ]
      }
    }
    

  • Zaladowane relacje: user, notable, logs, logs.user

  • Bledy: 404 — notatka nie znaleziona

3.3 Tworzenie notatki

POST /api/notes

  • Opis: Tworzy nowa notatke dla wskazanej encji
  • Autoryzacja: Role: ADMIN, SUPERVISOR, EMPLOYEE + Policy NotePolicy::create (sprawdza przynaleznosc do organizacji)
  • Request: StoreNoteControllerRequest
  • Body:
Pole Reguly walidacji Opis
notable_type required\|string\|in:Client,Activity,Complaint,Item,Reservation Pelna klasa modelu (np. Domain\Client\Model\Client)
notable_id required\|string\|NotableExistsRule UUID encji, do ktorej dodajemy notatke
content required\|string\|min:5\|max:5000 Tresc notatki (5-5000 znakow)
is_pinned sometimes\|boolean Czy przypieta (domyslnie false)
show_in_reservation sometimes\|boolean Czy wyswietlic w rezerwacji (domyslnie false)
  • Przyklad request:

    {
      "notable_type": "Domain\\Client\\Model\\Client",
      "notable_id": "550e8400-e29b-41d4-a716-446655440000",
      "content": "Staly klient, ustalono rabat 10% na wynajem sali A",
      "is_pinned": true,
      "show_in_reservation": false
    }
    

  • Response (sukces — 200):

    {
      "message": "The Note has been successfully added",
      "status": 200
    }
    

  • Reguly biznesowe:

    • Pole user_id ustawiane automatycznie na zalogowanego uzytkownika (observer creating)
    • Jesli show_in_reservation = true, inne notatki tej samej encji z show_in_reservation = true zostaja automatycznie odznaczone
    • Wpis w note_logs tworzony automatycznie (event_type: created)
  • Custom validation rule NotableExistsRule:

    • Sprawdza czy notable_type jest na liscie dozwolonych typow
    • Sprawdza czy klasa modelu istnieje
    • Sprawdza czy rekord o podanym notable_id istnieje w bazie
  • Bledy walidacji (422):

Pole Blad Komunikat
notable_type required Typ encji jest wymagany
notable_type in Nieprawidlowy typ encji
notable_id required ID encji jest wymagane
notable_id NotableExistsRule Wybrana encja nie istnieje
content required Tresc jest wymagana
content min:5 Tresc musi miec co najmniej 5 znakow
content max:5000 Tresc moze miec maksymalnie 5000 znakow

3.4 Aktualizacja notatki

PATCH /api/notes/{noteId}

  • Opis: Aktualizuje istniejaca notatke (tresc, przypinanie, widocznosc w rezerwacji)
  • Autoryzacja: Role: ADMIN, SUPERVISOR, EMPLOYEE + Policy NotePolicy::update
  • Parametry URL:
Parametr Typ Opis
noteId string (UUID) Identyfikator notatki
  • Request: UpdateNoteControllerRequest
  • Body:
Pole Reguly walidacji Opis
content sometimes\|string\|min:5\|max:5000 Nowa tresc notatki
is_pinned sometimes\|boolean Zmiana statusu przypiecia
show_in_reservation sometimes\|boolean Zmiana widocznosci w rezerwacji
  • Przyklad request:

    {
      "content": "Staly klient, ustalono rabat 15% od stycznia 2026",
      "is_pinned": true
    }
    

  • Response (sukces — 200):

    {
      "message": "The Note has been successfully updated",
      "status": 200
    }
    

  • Reguly biznesowe:

    • Jesli zmieniono show_in_reservation na true, inne notatki tej samej encji zostaja automatycznie odznaczone
    • Zmiany w polach content, is_pinned, show_in_reservation sa logowane w note_logs z porownaniem starych i nowych wartosci
    • Jesli nie zmieniono zadnego ze sledzonych pol, wpis w logu NIE jest tworzony
  • Bledy: 404 — notatka nie znaleziona (NotFoundModelException)


4. Logika biznesowa

4.1 Glowne procesy

Proces tworzenia notatki

flowchart TD
    A[Pracownik wysyla POST /api/notes] --> B[Walidacja danych]
    B --> C{Walidacja OK?}
    C -->|Nie| D[422 - Bledy walidacji]
    C -->|Tak| E[Sprawdzenie NotableExistsRule]
    E --> F{Encja istnieje?}
    F -->|Nie| D
    F -->|Tak| G[Policy: create]
    G --> H{Autoryzacja OK?}
    H -->|Nie| I[403 - Brak dostepu]
    H -->|Tak| J[Observer: creating - ustawia user_id]
    J --> K[Zapis notatki do bazy]
    K --> L[Observer: created]
    L --> M{show_in_reservation?}
    M -->|Tak| N[Odznacz inne notatki tej encji]
    M -->|Nie| O[Pomijaj]
    N --> P[Tworzenie wpisu w note_logs]
    O --> P
    P --> Q[200 - Sukces]

Proces aktualizacji notatki

flowchart TD
    A[Pracownik wysyla PATCH /api/notes/noteId] --> B[Walidacja danych]
    B --> C{Walidacja OK?}
    C -->|Nie| D[422 - Bledy walidacji]
    C -->|Tak| E[Szukanie notatki]
    E --> F{Notatka istnieje?}
    F -->|Nie| G[404 - Nie znaleziono]
    F -->|Tak| H[Policy: update]
    H --> I{Autoryzacja OK?}
    I -->|Nie| J[403 - Brak dostepu]
    I -->|Tak| K[Aktualizacja notatki]
    K --> L[Observer: updated]
    L --> M{show_in_reservation zmieniono na true?}
    M -->|Tak| N[Odznacz inne notatki tej encji]
    M -->|Nie| O[Pomijaj]
    N --> P[Ekstrakcja zmian - ExtractChanges]
    O --> P
    P --> Q{Sa zmiany do zalogowania?}
    Q -->|Tak| R[Tworzenie wpisu w note_logs]
    Q -->|Nie| S[Pomijaj log]
    R --> T[200 - Sukces]
    S --> T

4.2 Reguly biznesowe

  1. Autor automatyczny — pole user_id jest automatycznie ustawiane na zalogowanego uzytkownika w momencie tworzenia notatki (observer creating)
  2. Wylacznosc show_in_reservation — dla kazdej encji (tej samej pary notable_type + notable_id) tylko jedna notatka moze miec show_in_reservation = true. Oznaczenie nowej automatycznie odznacza poprzednia
  3. Sledzenie zmian — zmiany w polach content, is_pinned, show_in_reservation sa automatycznie logowane w tabeli note_logs z porownaniem starych i nowych wartosci
  4. Pomijanie systemowych pol — pola updated_at, created_at, notable_type, notable_id, user_id sa pomijane przy ekstrakcji zmian
  5. Brak usuwania notatek — w obecnej implementacji nie istnieje endpoint DELETE — notatki nie moga byc usuwane
  6. Zachowanie autora logu po usunieciu uzytkownika — pole user_id w note_logs jest ustawiane na NULL gdy uzytkownik zostanie usuniety (nullOnDelete)

4.3 Walidacje

Store (tworzenie)

Pole Reguly Opis
notable_type required\|string\|in:[5 klas modeli] Musi byc jedna z dozwolonych klas: Client, Activity, Complaint, Item, Reservation
notable_id required\|string\|NotableExistsRule UUID encji musi istniec w bazie
content required\|string\|min:5\|max:5000 Tresc: 5-5000 znakow
is_pinned sometimes\|boolean Opcjonalne, domyslnie false
show_in_reservation sometimes\|boolean Opcjonalne, domyslnie false

Update (aktualizacja)

Pole Reguly Opis
content sometimes\|string\|min:5\|max:5000 Opcjonalne, 5-5000 znakow
is_pinned sometimes\|boolean Opcjonalne
show_in_reservation sometimes\|boolean Opcjonalne

Roznica miedzy store a update

Przy tworzeniu (store) pola notable_type, notable_id i content sa wymagane. Przy aktualizacji (update) wszystkie pola sa opcjonalne (sometimes) — mozna zmieniac dowolne z nich niezaleznie.


5. Autoryzacja i uprawnienia

5.1 Middleware (kontroler)

Wszystkie akcje kontrolera (index, show, store, update) wymagaja jednej z rol:

  • ADMIN
  • SUPERVISOR
  • EMPLOYEE

5.2 Policy (NotePolicy)

Policy dziedziczy z BasePolicy, ktora w metodzie before() automatycznie przyznaje pelny dostep administratorom.

Akcja Admin Supervisor Employee Warunek dodatkowy
view Zawsze Warunkowo Warunkowo Musi nalezec do organizacji encji nadrzednej. Jesli encja nie ma organizacji — dostep przyznany
create Zawsze Warunkowo Warunkowo Encja nadrzedna musi istniec. Jesli ma organization_id — uzytkownik musi nalezec do tej organizacji. Jesli nie ma — tylko supervisor
update Zawsze Warunkowo Warunkowo Jak view, ale jesli encja nie ma organizacji — tylko supervisor
flowchart TD
    A[Sprawdz uprawnienia] --> B{Rola ADMIN?}
    B -->|Tak| C[Dostep przyznany - before]
    B -->|Nie| D{Akcja?}
    D -->|view / update| E[Rozwiaz organization_id encji]
    D -->|create| F{Encja nadrzedna istnieje?}
    F -->|Nie| G[Dostep odrzucony]
    F -->|Tak| H[Pobierz organization_id encji]
    E --> I{Ma organization_id?}
    H --> I
    I -->|Tak| J{Uzytkownik nalezy do organizacji?}
    I -->|Nie - view| K[Dostep przyznany]
    I -->|Nie - create/update| L{Jest supervisorem?}
    J -->|Tak| K
    J -->|Nie| G
    L -->|Tak| K
    L -->|Nie| G

6. Eventy i efekty uboczne

6.1 Observer NoteObserver

Hook Akcja Efekt uboczny
creating CreatingNoteObserver Automatyczne ustawienie user_id na ID zalogowanego uzytkownika
created CreatedNoteObserver Wywolanie EnsureExclusiveShowInReservation — odznaczenie innych notatek jesli nowa ma show_in_reservation = true
created CreateLog Utworzenie wpisu w note_logs z event_type = "created"
updated UpdatedNoteObserver Jesli zmieniono show_in_reservation na true — odznaczenie innych notatek
updated ExtractChanges + CreateLog Ekstrakcja zmian w polach content, is_pinned, show_in_reservation i zapis do note_logs (jesli sa zmiany)

6.2 Mechanizm EnsureExclusiveShowInReservation

Dla danej pary (notable_type, notable_id) moze byc tylko jedna notatka z show_in_reservation = true. Mechanizm:

  1. Sprawdza czy nowa/zaktualizowana notatka ma show_in_reservation = true
  2. Jesli tak — wyszukuje inne notatki tej samej encji z show_in_reservation = true
  3. Dla kazdej znalezionej ustawia show_in_reservation = false i zapisuje
  4. Zapis kazdej z odznaczanych notatek triggeruje observer updated, ktory loguje zmiane

7. Notyfikacje

W domenie Notatek nie sa wysylane zadne notyfikacje. Notatki sa wewnetrznym narzedziem zespolu i nie generuja powiadomien email ani in-app.


8. Powiazania z innymi domenami

8.1 Encje z mozliwoscia dodawania notatek

Domena Model Przyklady notatek
Klienci (Client) Domain\Client\Model\Client "Staly klient, rabat 10%", "Preferencja: sala z klimatyzacja"
Rezerwacje (Reservation) Domain\Reservation\Model\Reservation "Prosba o 50 krzesel", "Dostep od 8:00 na przygotowanie"
Zasoby (Item) Domain\Item\Model\Item "Uszkodzona podloga przy wejsciu", "Klucz u woznego"
Aktywnosci (Activity) Domain\Activity\Model\Activity "Wymagany sprzet audio", "Trener prosi o wode"
Reklamacje (Complaint) Domain\Complaint\Model\Complaint "Rozmowa z klientem 15.02", "Czekamy na odpowiedz"

8.2 Zaleznosci

graph LR
    Note -->|morphTo| Client
    Note -->|morphTo| Reservation
    Note -->|morphTo| Item
    Note -->|morphTo| Activity
    Note -->|morphTo| Complaint
    Note -->|belongsTo| User
    NoteLog -->|belongsTo| Note
    NoteLog -->|belongsTo| User
Domena Kierunek Opis
User Note zalezy od User Kazda notatka i wpis logu ma autora (uzytkownika)
Client Note rozszerza Client Notatki wewnetrzne przy kliencie
Reservation Note rozszerza Reservation Notatki do rezerwacji, mozliwosc wyswietlenia w szczegolach
Item Note rozszerza Item Notatki o obiekcie
Activity Note rozszerza Activity Notatki o zajeciach
Complaint Note rozszerza Complaint Wewnetrzne komentarze do reklamacji

9. Konfiguracja

Domena Notatek nie posiada dedykowanych parametrow konfiguracyjnych. Dziala w oparciu o stale wartosci:

Parametr Wartosc Zrodlo
Dozwolone typy encji Client, Activity, Complaint, Item, Reservation NoteEnumService::getAllowedNotableTypes()
Typy zdarzen created, updated NoteEnumService::getEvents()
Min. dlg. tresci 5 znakow StoreNoteControllerRequest / UpdateNoteControllerRequest
Max. dlg. tresci 5000 znakow StoreNoteControllerRequest / UpdateNoteControllerRequest
Sledzone pola content, is_pinned, show_in_reservation ExtractChanges

10. Znane ograniczenia i TODO

Nr Opis Typ
1 Brak endpointu DELETE — notatek nie mozna usuwac Ograniczenie
2 Brak filtrowania notatek po notable_type / notable_id w endpoincie index (poza Spatie Query Builder) Do weryfikacji
3 Brak limitu liczby notatek na encje Ograniczenie
4 EnsureExclusiveShowInReservation przy created triggeruje sie zawsze (nawet gdy show_in_reservation = false) — wczesne wyjscie w metodzie chroni przed niepotrzebna praca Optymalizacja