Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions DDD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Zadanie 1 – Domain Driven Design

## **System powiadomień i alertów**

###
Wysyłanie *alertów* o zdarzeniach bankowych do użytkownika różnymi kanałami, takimi jak: e-mail, SMS lub powiadomienie push.

Wyróżnione zostały dwa *bounded contexts*:
- **Powiadomienia** – tworzenie alertów.
- **Komunikacja** – techniczna wysyłka.

Zastosowano 6 elementów:
- 2 *encje*
- 2 *value objects (VO)*
- 1 *aggregate root*
- 1 *zdarzenie domenowe*

### Kluczowe komponenty
- **Walidacja treści**
- sprawdzanie jej długości, poprawności oraz usunięcie niebezpiecznych fragmentów np. HTML, skryptów.
- **Preferencje użytkownika**
- określanie, w jaki sposób i kiedy użytkownik chce otrzymywać wiadomości.
- **Śledzenie statusu**
- zapisanie, czy wiadomość została wysłana, czy wystąpił błąd i czy próbowano ponownie.

### Diagram DDD
![alt text](DDD.png)

### Założenia i walidacje

| Element | Typ | Kluczowe atrybuty (format) | Walidacje / Reguły |
|---|---|---|---|
| **Alert** | Aggregate Root | `alertId: UUID`, `uzytkownikId: UUID`, `kanal: Kanal`, `tresc: Tresc`, `status: StatusAlertu`, `czasWysylki: ISO-8601` | `zaplanuj()` sprawdza preferencje; status mozna zmienić tylko przez metody domenowe np. `oznaczWysłany()` zeby nikt spoza domeny nie mógł zmienić statusu |
| **PreferencjePowiadomien** | Encja | `uzytkownikId: UUID`, `dozwoloneKanaly: Set<KanalTyp>` | `czyDozwolone(kanal)` zwraca true/false; jeśli false - odrzuć/zaplanuj na później (jeśli występuje preferencja quiet hours) |
| **Tresc** | Value Object | `tytul: 1..120`, `tekst: 1..1000`, `szablonId: string` | Bezpieczeństwo, brak wrazliwych danych np. cały IBAN, usuwanie niebezpiecznych znaczników (`<script>` itp.) |
| **Kanal** | Value Object | `typ: KanalTyp`, `adresDocelowy: string` | EMAIL - RFC 5322; SMS (MSISDN) - E.164; PUSH - token <= 512 znaków |
| **Wiadomosc** | Encja (Komunikacja) | `id: UUID`, `kanal: Kanal`, `tresc: Tresc`, `status: StatusDostarczenia`, `znacznikCzasu: ISO-8601` | Powtórzenie wysłania w razie niepowodzenia; logi błędów i rezultatów |

### Podsumowanie

Celem jest zapobiec wstrzyknięciu złośliwego kodu np. XSS, HTML injection.
- Alerty przechodzą czyszczenie przez usuwanie znaczników np. `<script>` dlatego nie zostaną przesłane w powiadomieniu.
- Jśli schemat jest niepoprawny zostaje odrzucony.
- Weryfikacja czy ządanie pochodzi z uprawnionego źródła. Walidowanie formatu adresów np. token length.
- Przed zapisem lub wysłaniem usuwanie są niebezpieczne tagi i atrubuty.
- Nie mozna zmienic statusów w bazie danych bez przejścia przez logikę ze w wględu na metody domenowe.
Binary file added DDD.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions Python/Flask_Book_Library/project/books/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from project import db
from project.books.models import Book
from project.books.forms import CreateBook
from markupsafe import escape


# Blueprint for books
Expand Down Expand Up @@ -30,9 +31,15 @@ def list_books_json():
# Route to create a new book
@books.route('/create', methods=['POST', 'GET'])
def create_book():
data = request.get_json()
# Read form fields and escape HTML/JS
name = escape(request.form.get('name', ''))
author = escape(request.form.get('author', ''))
year_published = escape(request.form.get('year_published', ''))
book_type = escape(request.form.get('book_type', ''))

#data = request.get_json()

new_book = Book(name=data['name'], author=data['author'], year_published=data['year_published'], book_type=data['book_type'])
new_book = Book(name=name['name'], author=author['author'], year_published=year_published['year_published'], book_type=book_type['book_type'])

try:
# Add the new book to the session and commit to save to the database
Expand Down