# Запуск(Без Docker): - cmake .. -DBOOST_ROOT=C:\Libs\boost_1_88_0 -Dmysql-concpp_DIR=C:\Libs\mysql_connector - cmake --build . # Запуск(С Docker): - $env:DOCKER_BUILDKIT=1; docker build --progress=plain -t up_and_down . - docker run --rm -p 8080:8080 docker ./dist:/project/dist up_and_down # TODO: - ~~Сделать реальные исполнители(executors) для регистрации, авторизации, логаута~~ - ~~Покрыть тестами класс User и AuthRegistrationExecutor~~ - ~~Добавить clang-format(через CLion)~~ - ~~Перевести GetByUUID GetByLogin на const ref/string_view в IUserDAO - также не vector, а span(погуглить)~~ - span не применим - ~~Привести к единому виду функции IUserDAO~~ - ~~Пройтись по коду и максимально наставить const~~ - ~~Указать возможные исключения в интерфейсах DAO - почему может выбросить исключение~~ - ~~Вынести User в структуру. Hashed Password структура должна изначально состоять в другой структуре~~ - ~~SharedPtr - передавать по константной ссылке.~~ - ~~Вынести обработку исключений в RootExecutor~~ - ~~Уменьшить дублирование кода в исключениях~~ - ~~Покрыть логами~~ - ~~Сделать один класс исключений, имеющих метод HTTP code - код и сообщение записывать уже в ловушке~~ - ~~Сделать интеграционный тест по ручкам~~ - ~~Заменить internal_server_error на bad_request и перепроверить коды ошибок~~ - ~~Создание и удаление вспомогательных классов должно быть вынесено в фикстуру~~ - ~~К следующему занятию сделать ручку из кейса 3 + восстановить фикстуры из тестов~~ - Посмотреть по поводу блокировок или тред пулла при использовании базы - Посмотреть пулл соединений(Object pool) при использовании базы данных(посмотреть api MySQL-Connector) - Посмотреть и подумать, что лучше - корутины или многопоточность? - UseCase'ы по работе с личным кабинетом - Найти слабые места в C++ -- std::forward, universal reference, просмотреть про decltype(почитать статьи) - ~~Разобрать decltype и auto по статье~~ - Подготовить резюме для тестовых собесов - DockerHosting.ru - купить аренду после того, как будет готов фронт и бэк До 27.01.2026 - ~~Подобрать сервер по параметрам. Использовать linux.~~ - ~~Перевести string на string_view~~ - ~~Попробовать nodiscard к executoru~~ - ~~Добить 2 ручки~~ До 10.02.2026 - Сделать 2-3 теста - Продвинуться по фронтенду(форма авторизации и логина) - Сделать Dockerfile & Docker-compose(очищать и заполнять базу после каждого тест-кейса) - Возможно, сделать тесты на CI/CD - приоритет - низкий - Научиться поднимать базы данных под каждый тест - научиться Docker - docker-compose - а если тест что-то должен заполнить, то он заполняет в самом начале - Проставить const на немутабельные объекты # План 1)Добить бэкенд(2 ручки) (до февраля) 2)Сделать деплой(до марта) 3)Сделать фронтенд для MVP 4)Делаем веб-чат и роль доктора 5)Читать книгу Мейерса "Эффективный и современный C++" до ??? # UseCase'ы приложения: # Up And Down - система для учета и отслеживания состояния для людей, больных БАР ## UseCase №1 ### 1.Название: Зарегистрировать пользователя ### 2.Актор: Пользователь-пациент ### 3.Цель: Внести данные о новом пользователе в систему ### 4.Предусловия: * Пользователь не авторизован в системе * Пользователь с данным login'ом отсутствует в системе ### 5.Основной поток: #### А1.Пользователь при входе в систему выбрасывается из системы * Пользователь заходит в приложение на любую страницу * Из-за отсутсвия авторизации приложение перенаправляет его на страницу авторизации и регистрации * Пользователь кликает по ссылке, ведущей на странице регистрации * На странице регистрации пользователь вводит логин и пароль * Пользователь нажимает кнопку "Зарегистрироваться" * Система выводит сообщение, что пользователь зарегистрирован в приложении ### 6.Потоки исключений: #### B1.Пользователь с таким логином уже есть в системе * Процедура регистрации проваливается * Выводится нотификация с сообщением об ошибке по причине наличия такого же логина в системе #### B2.Пользователь оставил пустым логин или пустой/неправильный пароль * При попытке регистрации подсвечиваются незаполненные поля, или поле пароля, если пароль неправильный * Выводится сообщение об ошибке ### 7.Постусловия * Пользователь с указанным логином сохранен в БД ### 8.API-Маршруты * `POST /api/v1/Auth/Register` - Регистрация пользователя ### 9.Контракт #### Register-Request ``` { "login": "ivan_89", "password": "S3cureP@ssw0rd" } ``` ##### Требования к валидации: * login: 3-50 символов, ^[A-Za-z0-9_]+$, уникальное значение * password: ≥ 5 символов ##### Response - 201 - Created ``` { "user": { "uuid": "51351bb1-7563-479d-a8e9-201d0ff934c2" "login": "ivan_89" } } ``` ##### Errors * `409 USER_EXISTS` — пользователь с таким логином уже есть(`B1`) * `422 VALIDATION_FAILED` — пустой логин/неправильный пароль(`B2`) * `400 BAD_REQUEST` — сервер не смог десереализовать JSON ### 10. Используемые сущности ДБ * users(uuid(PK), login(unique), hashed_password) ## UseCase №2 ### 1.Название: Авторизация пользователя ### 2.Актор: Пользователь-пациент ### 3.Цель: Предоставить пользователю возможность получить его данные в виде дневника болезни ### 4.Предусловия: * Пользователь должен быть зарегистрирован в системе * Пользователь должен быть не авторизован в системе ### 5.Основной поток: #### А1.Пользователь при входе в систему выбрасывается из системы * Пользователь заходит в приложение на любую страницу * Из-за отсутствия авторизации приложение перенаправляет его на страницу авторизации * Пользователь вводит свой логин и пароль * Пользователь получает токен, который открывает ему доступ к получению собственных данных #### А2.Пользователь осуществляет выход из системы * Пользователь кликает на кнопку логаута * На сервере происходил отзыв токена * Пользователь вновь считается неавторизованным ### 6.Альтернативные потоки: #### B1.Введен неправильный логин или неправильный пароль * Пользователь не получает токен, авторизация провалена * Выводится сообщение об ошибке #### B2.Поле логин или пароль оставлены пустыми * При попытке авторизации не происходит запрос токена. Авторизация провалена * Пустые поля подкрашиваются, как ошибочно заполненные * Выводится сообщение об ошибке #### B3.Пользователь не был зарегистрирован в приложении на момент логаута * Сервер не может отозвать токен и возвращает ошибку ### 7.Постусловия * Сессия пользователя в виде токена сохраняется на сервере * Пользователь перенаправлен на основную страницу, где выводится его дневник болезни ### 8.API-Маршруты * `POST /api/v1/Auth/Login` - Вход пользователя в систему и получение токена * `POST /api/v1/Auth/Logout` - Отозвать токен и выйти из системы. ### 9.Контракт #### Login-Request ``` { "login": "ivan_89", "password": "S3cureP@ssw0rd" } ``` ##### Response - 200 - OK ``` { "token": af32df3bas739f272bd109c823 } ``` ##### Errors * `401 BAD_CREDENTIALS` — неверный логин/пароль (B1) * `422 VALIDATION_FAILED` — пустые поля (B2) * `400 BAD_REQUEST` — сервер не смог десереализовать JSON #### Logout-Request ``` { "token": af32df3bas739f272bd109c823 } ``` ##### Response - 200 - OK ``` null ``` ##### Errors * `400 BAD_REQUEST` — Такого токена не существует(B3) ### 10. Используемые сущности ДБ * users(uuid(PK), login(unique), hashed_password) ## UseCase №3 ### 1.Название: Переход на главную страницу ### 2.Актор: Пользователь-пациент ### 3.Цель: Предоставить пользователю поверхностный вывод данных о нем и инструменты для глубокого просмотра данных и их модификации ### 4.Предусловия: * Пользователь имеет актуальный токен, подтверждающий его авторизацию в системе * Пользователь тем или иным способом перешел на главную страницу ### 5.Основной поток: #### A1.Записи в дневнике есть * Система перенаправляет пользователя на его основную страницу * Система запрашивает и выводит последние записи и схемы лечения его дневника * Система делает доступными операции с дневником #### A2.Записей в дневнике нет * Заместо вывода записей в дневнике, система выводит заглушку, информирующую пользователя, что дневник пуст * Система делает доступными операции с дневником ### 6.Потоки исключений: #### B1.Записи по какой-то причине не подгрузились * Система выводит нотификацию об ошибке и ее причине * Заместо вывода записей, система выводит на этом месте заглушку, информирующую о неправильной работе приложения и предоставляющей для нажатия кнопку перезагрузки страницы ### 7.Постусловия * Пользователь видит свои последние записи и может по ним кликнуть, чтобы увидеть подробную информацию * Пользователю доступны операции добавления, модификации и удаления записей, а также схем лечения ### 8.API-Маршруты * `GET /api/v1/User/Diaries` - получить кусок дневника пользователя (требует Authorization: Bearer ) query-параметры: from (int, по умолч. 0), count (int, по умолч. 20) * `GET /api/v1/UserTreatmentSchemes` - получить список схем пользователя (требует Authorization: Bearer ) query-параметры: from (int, по умолч. 0), count (int, по умолч. 20) ### 9.Контракт #### Diaries-Request ##### Response - 200 - OK ``` { diaries: [ { "uuid": "e89b6a0c-4b0f-4722-a410-1e0c1864bf8a", "time": "100000034", // в ms "mania_level": 1, "depression_level": 2, "mood_level": 3, "activity_level": 4, "appetite_level": 5, "dream_level": 6, "anxiety_level": 7, "comment": "Накрыл психоз. Выпил одну таблетку аминазина" "user_treatment_scheme_uuid": bf6d1555-39e9-4d73-8928-4763627f4dd5 } ] } ``` ##### Errors * `401 TOKEN_REQUIRED|TOKEN_EXPIRED` — токен недействителен, либо отсутствует * `500 DATA_LOAD_FAILED` — ошибка при загрузке данных (`B1`) #### UserTreatmentSchemes-Request ##### Response - 200 - OK ``` { "user_treatment_schemes": [ { "uuid": "248313cb-a75e-4331-8379-d3f2fc36b68d" "treatment_name": "Bipolar I Scheme Urgent", "instructions": "Схема для быстрого и жесткого купирования психозов. Аминазин пить каждый день.", "medications": [ "eda5a5f7-167a-44b9-900d-c5c6acfc249b" ] } ] } ``` ##### Errors * `401 TOKEN_REQUIRED|TOKEN_EXPIRED` — токен недействителен, либо отсутствует * `500 DATA_LOAD_FAILED` — ошибка при загрузке данных (B1) ### 10. Используемые сущности ДБ * diaries(uuid(PK), time , mania_level , depression_level , mood_level , activity_level , appetite_level , dream_level , anxiety_level, user_treatment_schemes_uuid) * mania(level(PK)) * depressions(level(PK)) * moods(level(PK)) * activities(level(PK)) * appetites(level(PK)) * dreams(level(PK)) * anxiety(level(PK)) * treatment_schemes(user_treatment_schemes_uuid(PK), medication_uuid(PK)) * user_treatment_schemes(uuid(PK), user_uuid, treatment_name, instructions) * medications(uuid(PK), name, dose, unit, is_urgent) ## UseCase №4 ### 1.Название: Добавление новой записи в дневник ### 2.Актор: Пользователь-пациент ### 3.Цель: Ведение дневника болезни для врача ### 4.Предусловия: * Пользователь авторизован в системе * Пользователь находится на главной странице ### 5.Основной поток: #### А1.Пользователь создает новую запись в дневнике * Если отсутствуют, то подключаются идентификаторы мании, депрессии, настроения, активности, аппетита, сна, тревоги * Пользователь кликает по соответствующей кнопке добавления записи в дневник * Вызывается меню с формой заполнения записи * Пользователь описывает свое текущее состояние на модальном окне и указывает используемую схему лечения ### 6.Потоки исключений: #### B1.Пользователь оставил пустым любое из полей, кроме comment * Запись о неполном состоянии нельзя создать. Кнопка создания записи заблокирована #### B2. Идентификаторы состояний не подгрузились * На поле вводаставится заглушка, делающая невозможным его заполнение. ### 7.Постусловия * Пользователь добавил запись с указанной датой и прочими состояниями в БД ### 8.API-Маршруты * `POST /api/v1/User/Diaries` - Создание записи в дневнике ### 9.Контракт #### Diaries-Request ``` { `user_uuid`: "51351bb1-7563-479d-a8e9-201d0ff934c2", `time`: "172493000", `mania_level`: "6", `depression_level`: "6", `mood_level`: "7", `activity_level`: "4", `appetite_level`: "5", `dream_level`: "5", `anxiety_level`: "9", `comment`: "Сильная тревога. Пришлось выпить аминазин", `user_treatment_schemes_uuid`: "51351bb1-7563-479d-a8e9-201d0ff934c2", } ``` ##### Требования к валидации: * Все поля, кроме `comment` обязательны к заполнению * `user_treatment_schemes_uuid` должен указывать на существующую схему лечения ##### Response - 201 - Created ``` { `uuid`: "61351bb1-7563-479d-a8e9-201d0ff934c2", `user_uuid`: "71351bb1-7563-479d-a8e9-201d0ff934c2", `time` "172493000", `mania_level`: "6", `depression_level`: "6", `mood_level`: "7", `activity_level`: "4", `appetite_level`: "5", `dream_level`: "5", `anxiety_level`: "9", `comment`: "Сильная тревога. Пришлось выпить аминазин", `user_treatment_scheme`: "51351bb1-7563-479d-a8e9-201d0ff934c2" } ``` ##### Errors * `400 BAD_REQUEST` — отсутствуют обязательные поля * `400 BAD_REQUEST` — сервер не смог десереализовать JSON * `422 UNPROCECCABLE_ENTITY` - Во `time` значение размерностей ниже, чем день, должно быть равно 0 * `422 TREATMENT_SCHEME_IS_NOT_EXISTS` - такой схемы лечения болезни не существует ### 10. Используемые сущности ДБ * diaries(uuid(PK), time , mania_level , depression_level , mood_level , activity_level , appetite_level , dream_level , anxiety_level, user_treatment_schemes_uuid) * mania(level(PK)) * depressions(level(PK)) * moods(level(PK)) * activities(level(PK)) * appetites(level(PK)) * dreams(level(PK)) * anxiety(level(PK)) * user_treatment_schemes(uuid(PK)) ## UseCase №5 ### 1.Название: Изменение существующей записи в дневнике ### 2.Актор: Пользователь-пациент ### 3.Цель: Внесение правок в ошибочно заполненный дневник ### 4.Предусловия: * Пользователь авторизован в системе * Пользователю доступно для использования окно создания/редактирования дневника ### 5.Основной поток: #### А1.Пользователь редактирует новую запись в дневнике * Если отсутствуют, то подключаются идентификаторы мании, депрессии, настроения, активности, аппетита, сна, тревоги * Пользователь кликает по кнопке редактирования уже существующей записи о своем состоянии в дневнике * В последующем меню пользователю предоставляется возможность изменить данные о своем состоянии, а также схему лечения ### 6.Потоки исключений: #### B1.В приложении отсутствуют схемы лечений * Выполнение добавления записи невозможно, поэтому кнопка вызова меню блокируется #### B2.Пользователь оставил пустым любое из полей, кроме comment * Запись о неполном состоянии нельзя создать. Кнопка создания записи заблокирована #### B3. Идентификаторы состояний не подгрузились * На поле вводаставится заглушка, делающая невозможным его заполнение. #### B4. Попытка изменения даты * Пользователь попытался сделать запрос с измененной датой ### 7.Постусловия * Пользователь изменил запись соглсано условиям выше в БД ### 8.API-Маршруты * `PUT /api/v1/User/Diaries/:diary_guid` - Изменение записи в дневнике ### 9.Контракт #### Diaries-Request ``` { `uuid`: "61351bb1-7563-479d-a8e9-201d0ff934c2", `user_uuid`: "51351bb1-7563-479d-a8e9-201d0ff934c2", `time`: "172493000", `mania_level`: "6", `depression_level`: "6", `mood_level`: "7", `activity_level`: "4", `appetite_level`: "5", `dream_level`: "5", `anxiety_level`: "9", `comment`: "Сильная тревога. Пришлось выпить аминазин", `user_treatment_schemes_uuid`: "51351bb1-7563-479d-a8e9-201d0ff934c2", } ``` ##### Требования к валидации: * Все поля, кроме `comment` обязательны к заполнению * `user_treatment_schemes_uuid` должен указывать на существующую схему лечения ##### Response - 201 - Updated ``` { `uuid`: "61351bb1-7563-479d-a8e9-201d0ff934c2", `user_uuid`: "71351bb1-7563-479d-a8e9-201d0ff934c2", `time` "172493000", `mania_level`: "6", `depression_level`: "6", `mood_level`: "7", `activity_level`: "4", `appetite_level`: "5", `dream_level`: "5", `anxiety_level`: "9", `comment`: "Сильная тревога. Пришлось выпить аминазин", `user_treatment_scheme`: { "uuid": "248313cb-a75e-4331-8379-d3f2fc36b68d" "treatment_name": "Bipolar I Scheme Urgent", "instructions": "Схема для быстрого и жесткого купирования психозов. Аминазин пить каждый день.", "medications": [ "eda5a5f7-167a-44b9-900d-c5c6acfc249b" ] }, } ``` ##### Errors * `400 BAD_REQUEST` — отсутствуют обязательные поля * `400 BAD_REQUEST` — сервер не смог десереализовать JSON * `422 UNPROCECCABLE_ENTITY` - `time` не должно быть изменено * `422 TREATMENT_SCHEME_IS_NOT_EXISTS` - такой схемы лечения болезни не существует ### 10. Используемые сущности ДБ * diaries(uuid(PK), time , mania_level , depression_level , mood_level , activity_level , appetite_level , dream_level , anxiety_level, user_treatment_schemes_uuid) * mania(level(PK)) * depressions(level(PK)) * moods(level(PK)) * activities(level(PK)) * appetites(level(PK)) * dreams(level(PK)) * anxiety(level(PK)) * user_treatment_schemes(uuid(PK)) ## UseCase №6 ### 1.Название: Удаление существующей записи в дневнике ### 2.Актор: Пользователь-пациент ### 3.Цель: Удаление ненужной записи в дневнике ### 4.Предусловия: * Пользователь авторизован в системе * Пользователю доступен вывод целевой записи, которую необходимо удалить ### 5.Основной поток: #### А1.Пользователь Удаляет существующую запись в дневнике * Пользователь нажимает на кнопку удаления записи * Системы просит подтвердить удаление * Пользователь подтверждает свое действие. Запись удалена ### 6.Потоки исключений: #### B1.Пользователь отказывается подтвердить действие * Запись не удаляется #### B2.Пользователь удаляет несуществующую запись * Выдается соответствующий ответ с ошибкой ### 7.Постусловия * Целевая запись отсутствует в БД ### 8.API-Маршруты * `DELETE /api/v1/User/Diaries/:diary_guid` - удаление записи в дневнике ### 9.Контракт #### Diaries-Request ##### Требования к валидации: * `:diary_guid` должен указывать на существующую страницу дневника ##### Response - 204 - Deleted ``` null ``` ##### Errors * `404 NOT_FOUND` - такой схемы лечения болезни никогда не существовало или она уже удалена ### 10. Используемые сущности ДБ * diaries(uuid(PK)) ## UseCase №7 ### 1.Название: Создание схемы лечения ### 2.Актор: Пользователь ### 3.Цель: Предоставление пользователю способа лечения ### 4.Предусловия: * Пользователь авторизован в системе * Пользователю доступен функционал создания схем лечения ### 5.Основной поток: #### А1.Пользователь создает схему лечения * Пользователь указывает название схемы * Пользователь пишет к схема инструкцию * Пользователь добавляет к схеме лекарства ### 6.Потоки исключений: #### B1.Пользователь отказался заполнять схему леккарствами * Схему нельзя создать в таком виде. На попытку создать схему выходит окно ошибок ### 7.Постусловия * Схема создана и доступна для выбора в качестве лечения ### 8.API-маршруты * `POST /api/v1/TreatmentScheme` - создание схемы лечения ### 9.Контракт #### Diaries-Request ``` { "treatment_name": "Bipolar I Scheme Urgent", "instructions": "Схема для быстрого и жесткого купирования психозов. Аминазин пить каждый день.", "medications": [ "eca5a5f7-167a-44b9-900d-c5c6acfc249b", "eda5a5f7-167a-44b9-900d-c5c6acfc249b" ] } ``` ##### Требования к валидации: * `treatment_name` обязателен к заполнению * `medications` должен содержать хотя бы одно лекарство ##### Response - 200 - Updated ``` { "uuid": "eda5a5f7-167a-44b9-900d-c5c6acfc249b" "treatment_name": "Bipolar I Scheme Urgent", "instructions": "Схема для быстрого и жесткого купирования психозов. Аминазин пить каждый день.", "medications": [ "eca5a5f7-167a-44b9-900d-c5c6acfc249b", "eda5a5f7-167a-44b9-900d-c5c6acfc249b" ] } ``` ##### Errors * `400 BAD_REQUEST` — сервер не смог десереализовать JSON * `400 BAD_REQUEST` — Обязательные поля заполнены неправильно ### 10. Используемые сущности ДБ * user_treatment_schemes(uuid, user_uuid, treatment_name, instructions) * medications(uuid, name, dose, unit, is_urgent) * treatment_schemes(user_treatment_schemes_uuid, medication_uuid)