diff --git a/students/Mihnovec_Stas/lab-01/analysis.md b/students/Mihnovec_Stas/lab-01/analysis.md new file mode 100644 index 00000000..b3fb194c --- /dev/null +++ b/students/Mihnovec_Stas/lab-01/analysis.md @@ -0,0 +1,39 @@ +# Анализ границ ответственности и обработка исключений + +## Транзакционные границы +Транзакция начинается в момент получения API-запроса от пользователя на создание жалобы. Она включает в себя проверку существования новости, проверку на дубликаты (идемпотентность) и запись в БД. Вызов внешнего сервиса модерации вынесен за рамки строгой БД-транзакции во избежание блокировок при таймаутах. + +| Операция | Тип (Sync/Async) | Откат при ошибке | Стратегия повтора (Retry) | Идемпотентность | +|----------|------------------|------------------|---------------------------|-----------------| +| Сохранение жалобы в БД | Синхронная | Да (БД транзакция ROLLBACK) | Нет | Да (Ключ: `user_id` + `news_id`) | +| Проверка через AI Moderation | Синхронная (с коротким таймаутом) | Нет (Переход в Async) | Отправка в очередь RabbitMQ с экспоненциальной задержкой | Да (Сервис ИИ кэширует хеш текста) | +| Уведомление модераторов (Email) | Асинхронная | Нет (best-effort) | 3 попытки (через брокер сообщений) | Да (дедупликация по `complaint_id`) | +| Скрытие новости (если 100% фейк)| Асинхронная | Нет | Retry до победного (Dead Letter Queue) | Да (Проверка текущего статуса новости) | + +--- + +## Обработка исключительных ситуаций + +### 1. Исключительная ситуация: Таймаут сервиса Автомодерации (AI Checker) + +**Условие**: Внешний сервис HTTP POST `/analyze` не отвечает более 3 секунд. +**Обнаружение**: HTTP-клиент (например, Axios или HttpClient) выбрасывает `TimeoutException`. +**Реакция**: +1. Система не прерывает процесс создания жалобы. +2. Жалоба фиксируется в БД со статусом `PENDING` (Ожидает обработки). +3. Событие отправляется в очередь (RabbitMQ/Kafka) для фоновой обработки. +**Компенсация**: Компенсация не требуется, так как транзакция в БД успешна. Задача будет выполнена позже воркером. +**Уведомление пользователя**: "Жалоба принята. Из-за высокой нагрузки проверка займет чуть больше времени." + +### 2. Исключительная ситуация: Нарушение уникальности (Race Condition / Double Click) + +**Условие**: Пользователь дважды нажимает кнопку "Отправить", генерируя два одновременных запроса. +**Обнаружение**: База данных выбрасывает `UniqueConstraintViolationException` (уникальный индекс на `user_id` + `news_id`). +**Реакция**: +1. Первый запрос проходит успешно. +2. Второй запрос перехватывает ошибку уникальности. +**Компенсация**: Откат транзакции второго запроса. +**Уведомление пользователя**: "Ваша жалоба уже была принята ранее." (возвращается успешный ответ, чтобы не пугать пользователя ошибкой 500). + +### 3. Бонус: Реализация паттерна Circuit Breaker +Для защиты системы от каскадных сбоев, если сервис AI-модерации лежит полностью (ошибки 5xx подряд), система открывает Circuit Breaker. Запросы перестают отправляться во внешний сервис и **сразу** складываются в RabbitMQ, что экономит 3 секунды ожидания таймаута на каждом запросе пользователя, сохраняя отзывчивость UI. \ No newline at end of file diff --git a/students/Mihnovec_Stas/lab-01/diagrams/sequence-error.png b/students/Mihnovec_Stas/lab-01/diagrams/sequence-error.png new file mode 100644 index 00000000..e911b7fb Binary files /dev/null and b/students/Mihnovec_Stas/lab-01/diagrams/sequence-error.png differ diff --git a/students/Mihnovec_Stas/lab-01/diagrams/sequence-error.puml b/students/Mihnovec_Stas/lab-01/diagrams/sequence-error.puml new file mode 100644 index 00000000..f21ccc75 --- /dev/null +++ b/students/Mihnovec_Stas/lab-01/diagrams/sequence-error.puml @@ -0,0 +1,35 @@ +@startuml +skinparam maxMessageSize 150 +actor "Читатель" as User +participant "Web UI" as UI +participant "Complaint Service" as CompAPI +database "PostgreSQL" as DB +participant "AI Moderation" as Moderation +participant "RabbitMQ (Broker)" as Broker + +User -> UI: Нажать "Отправить жалобу" +UI -> CompAPI: POST /api/complaints +activate CompAPI + +CompAPI -> DB: INSERT complaint (status: PENDING) +DB --> CompAPI: complaint_id + +CompAPI -> Moderation: POST /analyze {text} +activate Moderation +Moderation --x CompAPI: TimeoutException (3000ms) +deactivate Moderation + +note over CompAPI: Перехват ошибки.\nПереход в fallback режим. + +CompAPI -> Broker: Publish Event: ModerationRetryQueue {complaint_id} +activate Broker +Broker --> CompAPI: ACK +deactivate Broker + +note over DB: Статус остается PENDING + +CompAPI --> UI: 202 Accepted, "Принято в обработку с задержкой" +deactivate CompAPI + +UI --> User: Показать: "Жалоба сохранена, проверяем..." +@enduml \ No newline at end of file diff --git a/students/Mihnovec_Stas/lab-01/diagrams/sequence-happy.png b/students/Mihnovec_Stas/lab-01/diagrams/sequence-happy.png new file mode 100644 index 00000000..f24145eb Binary files /dev/null and b/students/Mihnovec_Stas/lab-01/diagrams/sequence-happy.png differ diff --git a/students/Mihnovec_Stas/lab-01/diagrams/sequence-happy.puml b/students/Mihnovec_Stas/lab-01/diagrams/sequence-happy.puml new file mode 100644 index 00000000..55d95e10 --- /dev/null +++ b/students/Mihnovec_Stas/lab-01/diagrams/sequence-happy.puml @@ -0,0 +1,42 @@ +@startuml +skinparam maxMessageSize 150 +actor "Читатель" as User +participant "Web UI" as UI +participant "API Gateway" as API +participant "Complaint Service" as CompAPI +database "PostgreSQL" as DB +participant "AI Moderation" as Moderation +participant "RabbitMQ (Broker)" as Broker + +User -> UI: Нажать "Отправить жалобу" +UI -> API: POST /api/complaints\n{news_id, reason} +activate API + +API -> CompAPI: CreateComplaint() +activate CompAPI + +CompAPI -> DB: Проверка дубликатов (user_id, news_id) +DB --> CompAPI: Not found (OK) + +CompAPI -> DB: INSERT complaint (status: PENDING) +DB --> CompAPI: complaint_id + +CompAPI -> Moderation: POST /analyze {text} +activate Moderation +Moderation --> CompAPI: status: REQUIRES_REVIEW +deactivate Moderation + +CompAPI -> DB: UPDATE status (REVIEW_PENDING) + +CompAPI -> Broker: Publish Event: ComplaintCreated +activate Broker +Broker --> CompAPI: ACK +deactivate Broker + +CompAPI --> API: 201 Created, complaint_id +deactivate CompAPI + +API --> UI: Успешный ответ +deactivate API +UI --> User: Показать уведомление "Жалоба принята" +@enduml \ No newline at end of file diff --git a/students/Mihnovec_Stas/lab-01/scenarios.feature b/students/Mihnovec_Stas/lab-01/scenarios.feature new file mode 100644 index 00000000..83cac695 --- /dev/null +++ b/students/Mihnovec_Stas/lab-01/scenarios.feature @@ -0,0 +1,37 @@ +Feature: Подача жалобы на фейковую новость + + Scenario: Успешная подача жалобы на новость + Given пользователь авторизован как "reader@example.com" + And новость "Инопланетяне приземлились" с ID "NEWS-123" существует + When пользователь отправляет жалобу на "NEWS-123" с причиной "Недостоверный источник" + And сервис авто-модерации работает корректно + Then система создает жалобу со статусом "REVIEW_PENDING" + And система публикует событие "ComplaintCreated" в брокер сообщений + And пользователь видит сообщение "Ваша жалоба отправлена на проверку модераторам" + + Scenario: Ошибка - Новость уже удалена (Not Found) + Given пользователь авторизован как "reader@example.com" + And новость с ID "NEWS-999" была удалена автором минуту назад + When пользователь отправляет жалобу на "NEWS-999" + Then система возвращает ошибку 404 "Новость не найдена" + And жалоба НЕ сохраняется в базу данных + And пользователь видит сообщение "Эта новость уже удалена" + + Scenario: Таймаут сервиса AI-модерации (Fallback) + Given пользователь авторизован как "reader@example.com" + And новость "Секретный заговор" с ID "NEWS-456" существует + When пользователь отправляет жалобу на "NEWS-456" + And сервис авто-модерации не отвечает в течение 3 секунд + Then система сохраняет жалобу со статусом "PENDING" + And система ставит задачу в очередь "ModerationRetryQueue" + And пользователь видит сообщение "Жалоба принята. Из-за высокой нагрузки проверка займет чуть больше времени." + + Scenario: Идемпотентность - Защита от двойного клика (Дубликат) + Given пользователь авторизован как "reader@example.com" + And новость "Шок контент" с ID "NEWS-777" существует + And пользователь уже подавал жалобу на "NEWS-777" 5 минут назад + When пользователь повторно отправляет жалобу на "NEWS-777" + Then система обнаруживает дубликат по ключу "reader@example.com:NEWS-777" + And система НЕ создает новую запись в БД + And система возвращает статус успешного выполнения + And пользователь видит сообщение "Вы уже пожаловались на эту новость ранее" \ No newline at end of file diff --git a/students/Mihnovec_Stas/lab-01/use-case.md b/students/Mihnovec_Stas/lab-01/use-case.md new file mode 100644 index 00000000..0b8632d7 --- /dev/null +++ b/students/Mihnovec_Stas/lab-01/use-case.md @@ -0,0 +1,43 @@ +## Use-case: Подача жалобы на фейковую новость + +**Первичный актор**: Авторизованный читатель + +**Цель**: Сообщить о недостоверной информации в новости для её последующей проверки и возможной блокировки. + +**Предусловия**: +- Пользователь авторизован в системе. +- Статья (новость) существует в системе и доступна для чтения. +- Пользователь ранее не подавал жалобу на эту же новость (проверка идемпотентности). + +**Основной поток** (Happy Path): +1. Пользователь нажимает кнопку "Пожаловаться на фейк" на странице новости. +2. Система запрашивает причину (например, "Недостоверный источник", "Сгенерировано ИИ", "Кликбейт"). +3. Пользователь выбирает причину и нажимает "Отправить". +4. Система (UI) отправляет API-запрос на создание жалобы. +5. Сервис жалоб сохраняет запись в БД со статусом "PENDING". +6. Сервис жалоб синхронно отправляет текст новости во внешний сервис Автомодерации (AI Checker). +7. Сервис Автомодерации возвращает статус "REQUIRES_HUMAN_REVIEW" (требуется ручная проверка). +8. Сервис жалоб обновляет статус жалобы в БД. +9. Система ставит задачу в очередь на асинхронную отправку email-уведомления модераторам. +10. Система возвращает пользователю сообщение об успешной отправке жалобы. + +**Постусловия**: +- Жалоба зафиксирована в БД. +- Новость получает пометку (внутреннюю) о наличии активной жалобы. +- Модераторы уведомлены. + +**Альтернативные потоки**: +- 7a. Сервис Автомодерации уверенно определяет 100% фейк (возвращает "FAKE_CONFIRMED"). + - 7a1. Сервис жалоб автоматически скрывает новость из Ленты. + - 7a2. Автору новости отправляется предупреждение. + - 7a3. Возврат к шагу 10. + +**Исключительные ситуации**: +- 6a. Сервис Автомодерации недоступен (Timeout). + - 6a1. Система ловит ошибку таймаута. + - 6a2. Жалоба остается в БД со статусом "PENDING". + - 6a3. Задача на проверку ставится в брокер сообщений (асинхронный retry). + - 6a4. Пользователь получает ответ: "Жалоба принята и ожидает проверки". +- 4a. Пользователь отправляет повторную жалобу на ту же новость (Double click). + - 4a1. Срабатывает проверка ключа идемпотентности (user_id + news_id). + - 4a2. Система возвращает статус 200 OK и ID уже существующей жалобы без дублирования в БД. \ No newline at end of file diff --git "a/students/Mihnovec_Stas/lab-01/\320\236\321\202\321\207\320\265\321\202.md" "b/students/Mihnovec_Stas/lab-01/\320\236\321\202\321\207\320\265\321\202.md" new file mode 100644 index 00000000..79815261 --- /dev/null +++ "b/students/Mihnovec_Stas/lab-01/\320\236\321\202\321\207\320\265\321\202.md" @@ -0,0 +1,231 @@ +

Министерство образования Республики Беларусь

+

Учреждение образования

+

"Брестский Государственный технический университет"

+

Кафедра ИИТ

+





+

Лабораторная работа №1

+

По дисциплине: "Проектирование интернет-систем"

+

Тема: "Сценарий транзакции: моделирование use-case и границ ответственности"

+





+

Выполнил:

+

Студент 3 курса

+

Группы ПО-12

+

Михновец С. Э.

+

Проверил:

+

Несюк А.Н.

+




+

Брест 2026

+ +--- + +## Цель работы + +Научиться анализировать бизнес-процессы интернет-системы, выявлять границы ответственности компонентов и моделировать транзакционные сценарии с учётом возможных сбоев. + +--- + +## Вариант №37 - Новости «Без фейков» 📰 + +**Питч:** Читаем умно, делимся быстро. + +**Ядро домена:** Источники, Лента, Теги, Избранное, Жалобы. + +--- + +## Ход выполнения работы + +### 1. Структура проекта + +```text +lab-01/ +├── Отчет.md # Основной отчёт (этот документ) +├── use-case.md # Текстовое описание use-case +├── diagrams/ +│ ├── sequence-happy.puml # PlantUML для успешного сценария +│ ├── sequence-happy.png # Экспорт диаграммы +│ ├── sequence-error.puml # PlantUML для сценария с ошибкой +│ └── sequence-error.png # Экспорт диаграммы +├── scenarios.feature # Gherkin-сценарии +└── analysis.md # Анализ границ ответственности +``` + +--- + +### 2. Use-case описание + +👉 **Ссылка на файл:** [use-case.md](use-case.md) + +**Основной сценарий:** Подача жалобы на фейковую новость с автоматической проверкой + +**Первичный актор:** Авторизованный читатель + +**Цель:** Сообщить о недостоверной информации в новости для её последующей проверки и возможной блокировки. + +**Краткое описание основного потока:** +1. Пользователь нажимает "Пожаловаться на фейк" и выбирает причину. +2. Система отправляет API-запрос на создание жалобы. +3. Сервис сохраняет жалобу в БД со статусом "PENDING". +4. Система синхронно запрашивает внешний сервис AI-модерации для анализа текста. +5. AI-модерация возвращает статус "REQUIRES_HUMAN_REVIEW". +6. Статус жалобы в БД обновляется. +7. В очередь ставится задача на отправку уведомления модераторам. + +**Альтернативные потоки:** +- AI-модерация на 100% уверена, что это фейк -> Автоматическое скрытие новости из ленты. + +**Исключительные ситуации:** +- Таймаут сервиса AI-модерации (переход в асинхронный режим). +- Пользователь отправляет повторную жалобу на ту же новость (защита от дубликатов). +- Новость была удалена до момента отправки жалобы (404 Not Found). + +--- + +### 3. Диаграммы последовательности (Sequence Diagrams) + +#### 3.1. Happy Path (успешный сценарий) + +👉 **PlantUML исходник:** [sequence-happy.puml](diagrams/sequence-happy.puml) + +![Диаграмма успешного сценария](diagrams/sequence-happy.png) + +**Описание потока:** +- Пользователь отправляет жалобу. `Complaint Service` проверяет БД на дубликаты и сохраняет запись. Затем синхронно вызывается внешний сервис `AI Moderation`. После получения ответа статус обновляется, и публикуется событие в `RabbitMQ` для асинхронного уведомления модераторов. + +**Участники:** +- Читатель (User) +- Web UI / API Gateway +- Complaint Service (Сервис жалоб) +- PostgreSQL (База данных) +- AI Moderation (Внешний сервис проверки ИИ) +- RabbitMQ (Брокер сообщений) + +#### 3.2. Error Case (сценарий с ошибкой) + +👉 **PlantUML исходник:** [sequence-error.puml](diagrams/sequence-error.puml) + +![Диаграмма сценария с ошибкой](diagrams/sequence-error.png) + +**Описание потока:** +- Во время вызова `AI Moderation` происходит таймаут (сервис недоступен или перегружен). `Complaint Service` перехватывает исключение. Вместо того чтобы выдавать ошибку пользователю, жалоба остается в БД в статусе `PENDING`, а задача на проверку отправляется в очередь `RabbitMQ` (Fallback). Пользователь получает статус 202 Accepted. + +--- + +### 4. Gherkin-сценарии + +👉 **Ссылка на файл:** [scenarios.feature](scenarios.feature) + +**Реализовано сценариев:** 4 + +**Список сценариев:** +1. ✅ **Успешный сценарий:** Успешная подача жалобы на новость. +2. ✅ **Ошибка:** Новость уже удалена (Not Found). +3. ✅ **Ошибка:** Таймаут сервиса AI-модерации (Fallback в асинхронный режим). +4. ✅ **Ошибка:** Идемпотентность - Защита от двойного клика (Дубликат). + +**Пример сценария (Успешный путь):** +```gherkin +Feature: Подача жалобы на фейковую новость + +Scenario: Успешная подача жалобы на новость + Given пользователь авторизован как "reader@example.com" + And новость "Инопланетяне приземлились" с ID "NEWS-123" существует + When пользователь отправляет жалобу на "NEWS-123" с причиной "Недостоверный источник" + And сервис авто-модерации работает корректно + Then система создает жалобу со статусом "REVIEW_PENDING" + And система публикует событие "ComplaintCreated" в брокер сообщений + And пользователь видит сообщение "Ваша жалоба отправлена на проверку модераторам" +``` + +--- + +### 5. Анализ границ ответственности + +👉 **Ссылка на файл:** [analysis.md](analysis.md) + +#### 5.1. Транзакционные границы + +| Операция | Синхронная/Асинхронная | Откат при ошибке | Retry-стратегия | Идемпотентность | +|----------|------------------------|------------------|-----------------|-----------------| +| Сохранение жалобы в БД | Синхронная | Да (ROLLBACK) | Нет (контролируется UI) | Да (составной ключ user_id + news_id) | +| Проверка через AI Moderation | Синхронная | Нет (Переход в Async) | Отправка в очередь RabbitMQ с задержкой | Да (Сервис ИИ кэширует хеш текста) | +| Уведомление модераторов (Email)| Асинхронная | Нет (best-effort) | 3 попытки (через брокер сообщений) | Да (дедупликация по complaint_id) | + +#### 5.2. Обработка исключительных ситуаций + +**Реализовано стратегий обработки:** 2 + +##### Исключительная ситуация 1: Таймаут сервиса Автомодерации + +- **Условие возникновения:** HTTP POST запрос к внешнему сервису ИИ не отвечает более 3 секунд. +- **Обнаружение:** HTTP-клиент (например, Axios) выбрасывает `TimeoutException`. +- **Реакция:** Система ловит ошибку, не откатывает БД. Публикует событие `ModerationRetryQueue` в RabbitMQ для фоновой обработки. +- **Компенсация:** Не требуется откат. Жалоба остается в статусе "PENDING" до успешной асинхронной обработки воркером. +- **Уведомление пользователя:** "Жалоба принята. Из-за высокой нагрузки проверка займет чуть больше времени." (HTTP 202 Accepted). + +##### Исключительная ситуация 2: Нарушение уникальности (Double click) + +- **Условие возникновения:** Пользователь дважды нажал кнопку "Отправить", сгенерировав два параллельных запроса. +- **Обнаружение:** База данных PostgreSQL выбрасывает `UniqueConstraintViolationException` на составной индекс `(user_id, news_id)`. +- **Реакция:** Транзакция второго запроса прерывается. Система перехватывает ошибку БД. +- **Компенсация:** Откат (ROLLBACK) транзакции второго (дублирующего) запроса. +- **Уведомление пользователя:** Возвращается успешный ответ (HTTP 200) с сообщением: "Вы уже пожаловались на эту новость ранее." + +--- + +## Таблица критериев оценки + +| Критерий | Баллы | Выполнено | +|----------|-------|-----------| +| Use-case описание (полнота: акторы, предусловия, основной поток, альтернативы, исключения) | 15 | ✅ | +| Sequence diagram (happy path) - корректность нотации UML, включение всех ключевых компонентов | 20 | ✅ | +| Sequence diagram (error case) - моделирование хотя бы одной исключительной ситуации | 15 | ✅ | +| Gherkin-сценарии - минимум 4 сценария (1 успешный + 3 ошибочных) | 20 | ✅ | +| Анализ границ ответственности - таблица транзакционных границ, обоснование выбора синхронных/асинхронных операций | 15 | ✅ | +| Обработка исключений - описание стратегий retry, компенсации, уведомлений | 10 | ✅ | +| Качество документации - оформление, читаемость, грамотность | 5 | ✅ | +| **ИТОГО** | **100** | | + +--- + +## Контрольные вопросы + +**Подготовка к защите:** + +1. **Что такое транзакционная граница? Где она проходит в вашем сценарии?** + - Транзакционная граница — это область системы, в пределах которой набор операций выполняется атомарно (все или ничего). В моем сценарии граница проходит на уровне базы данных Complaint Service: проверка дубликатов и сохранение жалобы со статусом `PENDING` выполняются в одной транзакции. Вызов внешнего сервиса AI вынесен за эту границу, чтобы долгий ответ сети не блокировал подключение к БД. + +2. **Почему операция X выбрана синхронной, а Y - асинхронной?** + - **Синхронная (Запись в БД):** Система должна гарантированно сохранить данные жалобы и вернуть пользователю ответ с ID операции, чтобы он понимал, что запрос не потерян. + - **Асинхронная (Уведомление модераторов):** Отправка Email может занимать время. Пользователю не нужно ждать на сайте, пока письмо дойдет до модератора. Это можно сделать в фоне. + +3. **Как обеспечить идемпотентность при повторных запросах?** + - Идемпотентность обеспечивается созданием составного уникального индекса в базе данных по полям `user_id` и `news_id`. Если один и тот же пользователь попытается отправить жалобу на одну и ту же новость дважды, БД выбросит ошибку уникальности, которую сервис перехватит и вернет информацию о уже существующей жалобе без создания дубликата. + +4. **Что произойдёт, если внешний сервис вернёт ошибку после частичного выполнения операции?** + - Если сервис AI-модерации упадет после того, как жалоба была записана в БД, система не будет делать откат (rollback) жалобы. Вместо этого сработает паттерн Fallback: жалоба будет помещена в очередь брокера сообщений (RabbitMQ) для повторной попытки (Retry) проверки в фоновом режиме, когда внешний сервис снова станет доступен. + +5. **Как система обнаружит, что внешний сервис недоступен?** + - Через `TimeoutException` (если сервис не ответил за заданное время, например 3 секунды) или при получении HTTP-статусов ошибок из серии `5xx` (Internal Server Error, Bad Gateway). Также может использоваться паттерн Circuit Breaker для мониторинга процента отказов. + +6. **Какие данные нужно логировать для диагностики сбоев?** + - Нужно логировать: `timestamp` (время сбоя), `user_id`, `news_id`, `complaint_id`, текст ошибки (`Exception message` и `Stack Trace`), HTTP-статус ответа от внешнего сервиса, а также время выполнения запроса до падения (duration), чтобы диагностировать проблемы с производительностью сети. + +--- + +## Ссылка на репозиторий + +👉 **GitHub:** [[Cсылку на репозиторий]](https://github.com/dizmorall/PIS-2026) + +--- + +## Вывод + +✍️ В ходе выполнения лабораторной работы был проанализирован бизнес-процесс платформы "Новости «Без фейков»" на примере сценария модерации контента. Были разработаны текстовые use-case описания и визуальные модели взаимодействия компонентов с использованием инструмента PlantUML. Сформированы Gherkin-сценарии для автоматизированного BDD-тестирования, покрывающие как успешный путь, так и нештатные ситуации. Были определены границы транзакций: выделена критическая секция (запись в БД) и вынесены за её пределы нестабильные внешние вызовы (AI-проверка). Освоены паттерны обеспечения отказоустойчивости интернет-систем, такие как асинхронный Fallback через очереди сообщений и обеспечение идемпотентности API. + +--- + +**Дата выполнения:** 05.03.2026 + +**Оценка:** _____________ + +**Подпись преподавателя:** _____________ diff --git a/students/students.csv b/students/students.csv index 2e7c4e24..d34a08e8 100644 --- a/students/students.csv +++ b/students/students.csv @@ -1 +1,2 @@ Вариант,Group,№,sub,Name,NameLatin,Directory,Github Username,#1,#2,#3,#4,#5,#6,#7,#8,#9,Rating +37,ПО-12,15,2,Михновец Станислав Эдуардович,Mihnovec Stas,Mihnovec_Stas,dizmorall,,,,,,,,,, \ No newline at end of file diff --git a/tasks/01_transaction_scenario/examples/diagrams/sequence-happy.puml b/tasks/01_transaction_scenario/examples/diagrams/sequence-happy.puml index f9eb1287..3a9cae7b 100644 --- a/tasks/01_transaction_scenario/examples/diagrams/sequence-happy.puml +++ b/tasks/01_transaction_scenario/examples/diagrams/sequence-happy.puml @@ -1,4 +1,4 @@ -@startuml +@startuml happy title Успешный сценарий: Создание заявки и формирование группы actor "Координатор" as Coord