Оглавление
Веб-приложение для учета и фиксации сбоев в бизнес-процессах управляющей компании инвестиционных фондов, включая менеджер задач, а также модуль учета и управления рисками* (*в разработке).
Приложение позволяет фиксировать сбои в бизнес-процессах НФО (участника фондового рынка), в соответствии с требованиями Положения Банка России от 15.11.2021 N 779-П "Об установлении обязательных для некредитных финансовых организаций требований к операционной надежности ..., в целях обеспечения непрерывности оказания финансовых услуг".
Приложение автоматически фиксирует в базе данных отсутствие доступа в интернет, позволяет пользователям создавать случаи простоя, вносить в них изменения, получать различную аналитику.
Пользователи также могут ставить задачи другим пользователям, изменять и дополнять их по мере реализации.
Все случаи простоя и задачи можно дополнить уточняющими файлами. Реализована возможность их выгрузки, редактирования, удаления и т.п.
- Ведение защищенного реестра случаев простоя в тех. процессах в целях выявления, регистрации и предупреждения инцидентов защиты информации;
- Автоматическая фиксация и запись в базу данных случаев простоя;
- Совместный одновременный доступ нескольких пользователей к базе данных простоев с различным уровнем логического доступа;
- Взаимодействие с базой данных на чтение, запись, редактирование, удаление, получение требуемой аналитики с помощью удобного вэб-интерфейса;
- Соответствие требованиям N 779-П по защите и разграничению прав доступа;
- Доступ только из локальной сети Организации и отсутствие доступа из вне;
- Прикрепление к случаям простоя дополнительных материалав, управление файлами, их удаление.-
- Учет (логирование) всех действий пользователей в приложении, а также автоматическое резервное копирование базы данных;
- Возможность гибкой настройки под изменившиеся задачи, модульную структуру, расширяемость под возможную интеграцию с системой управления рисками, реестром рисков, базой данных о риск событиях, журналом нарушений, обращениями клиентов и акционеров, запросами и ответами на предписания регулирующих органов и т.п.
- Пользователи могут ставить друг другу задачи и сроки их реализации;
- Прикрепление к задачам дополнительных материалав, управление файлами, их удаление.
- Контроль сроков реализации задач и дедлайнов;
- Централизованное хранение задач и прикрепленных файлов в базе данных;
- Получение аналитики по выставленным и полученным задачам по каждому пользователю.
- Автоматический бэкап базы данных;
- Загрузка файлов в каталог с файлами, анализ "бесхозных" файлов и их удаление.
Приложение построено на принципах чистой архитектуры
Приложение строится на принципах чистой архитектуры.
Чистая архитектура имеет множество разновидностей,
но любая из них включает в себя 3 слоя (уровня):
- представления (API router, bot handlers)
- бизнес-логики (services)
- данных (repository).
Это позволяет упростить внесение изменений в код, поскольку сразу понятно в каком слое, какие изменения нужно производить.
Функции отдельных слоев в разрабатываемом приложении:
-
Слой представления занимается:
- Получением входных данных.
- Передачей их в слой бизнес-логики и преобразованием в нужный формат при формировании ответа.
- Валидацией данных только на наличие значений и правильный их формат (с помощью - Pydantic).
- Форматированием выходных данных и определением в каком виде отдать данные получателю, (например, json для API или html для стандартной страницы, или какие кнопки прикрепить к сообщению в боте).
-
Слой бизнес-логики (services) отвечает за:
-
Исполнение требований диктуемых заказчиком.
-
Валидацию бизнес правил.
Note
Разница между валидацией представления и валидацией бизнес-логики в том, что первая отвечает за наличие данных, а вторая за валидность их в той или иной ситуации.
-
Получение данных из слоя данных.
-
Формирование необходимых выходных данных. -
Для получения или сохранения данных (из базы данных, стороннего сервиса, API, ..) из бизнес-уровня, необходимо использовать репозитории.
-
-
Слой данных (repository) отвечает за:
- получение и сохранение данных в базе данных или сторонних сервисах.
Note
Делать это за пределами уровня данных запрещено!
Для получения данных из БД используется паттерн Репозиторий.
Он содержит как стандартные методы для получения данных по id, так и специализированные, для получения сложных сущностей.
- получение и сохранение данных в базе данных или сторонних сервисах.
Разделение логики приложения на несколько слоёв позволяет отделить бизнес-правила от логики и способа хранения данных или отображения их пользователям.
-
Создать и заполнить файл
.env
:# Общие настройки приложения APP_TITLE=Учет фактов простоя ИС APP_DESCRIPTION=Журнал учета фактов простоя информационной системы УК ПИФ CONNECTION_TEST_URL_BASE=https://www.agidel-am.ru # Базовый url теста доступа в интернет CONNECTION_TEST_URL_2=https://www.ya.ru # Дополнительный url теста доступа в интернет FILES_DOWNLOAD_DIR=uploaded_files # Каталог для хранения дополнительных файлов, прикрепленных к задачам и простоям FILE_TYPE_DOWNLOAD=("doc", "docx", "xls", "xlsx", "img", "png", "txt", "pdf", "jpeg") MAX_FILE_SIZE_DOWNLOAD=10000 # Максимальный допустимый к загрузке размер файла в кб SLEEP_TEST_CONNECTION=20 # Интервал тестирования доступа к Интернет в секундах TIMEZONE_OFFSET=5 # Часовой пояс TOKEN_AUTH_LIFETIME_SEC=432000 # Срок жизни токена авторизации в секундах (60*60*24*5) # Переменные приложения SECRET_KEY= # Cекретный ключ для генерации jwt-токенов # Переменные базы данных DB_BACKUP=False # Включение(True) | Выключение(False) режим авто архивирования БД DB_BACKUP_DIR=db_backups # Название каталога для хранения архивов БД MAX_DB_BACKUP_FILES=50 # Максимальное количество файлов бэкапа БД SLEEP_DB_BACKUP=43200 # Интервал архивирования БД в сек (12 ч.) DATABASE_NAME=tech_accident_db_local.db # Имя БД DATABASE_URL=sqlite+aiosqlite:///./tech_accident_db_local.db # Настройки логирования FILE_NAME_IN_LOG=False # If true: structlog.get_logger().bind(file_name=__file__) JSON_LOGS=True # true: logs in json with JSONRenderer | false: colored logs with ConsoleRenderer LOG_LEVEL=INFO # Уровень логирования LOG_DIR=logs # Директория для сохранения логов. По умолчанию - logs в корневой директории LOG_FILE=app.log # Название файла с логами LOG_FILE_SIZE=10485760 # Максимальный размер файла с логами, в байтах LOG_FILES_TO_KEEP=5 # Количество сохраняемых файлов с логами # Настройки используемых тех.процессов INTERNET_ACCESS_TECH_PROCESS=25 # Наиболее критический к отсутствию доступа в Интернет ТП в Организации TECH_PROCESS={"DU_25": "25", "SPEC_DEP_26": "26", "CLIENTS_27": "27"} # Настройки угроз RISK_SOURCE="{\"ROUTER\": \"Риск инцидент: сбой в работе рутера.\", \"EQUIPMENT\": \"Риск инцидент: отказ оборудования.\", \"BROKER\": \"Риск инцидент: на стороне брокер.\", \"PO\": \"Риск инцидент: ПО.\", \"PROVAIDER\": \"Риск инцидент: сбой на стороне провайдер.\", \"ANOTHER\": \"Иное\"}" # Настройки персонала для постановки задач # (вставить строку из эндпоинта /api/users и разбить по указанному примеру) BOT_USER=2 # "id" бота, от имени которого фиксируются простои в автоматическом режиме STAFF="{\"1\": \"[email protected]\", \"2\": \"[email protected]\", \"3\": \"[email protected]\", \"4\": \"[email protected]\", \"5\": \"[email protected]\", \"6\": \"[email protected]\"}"
Note
Note
Для наполнения переменной
STAFF
в файле.env
спискомe-mail
пользователей необходимо:- выбрать эндпоинт GET/api/users под правами админа
- Скопировать строковое представление пользователей и вставить его в переменную
STAFF
в файле.env
:
STAFF="{\"1\": \"[email protected]\", \"2\": \"[email protected]\", \"3\": \"[email protected]\"}"
Note
Кастомизировать настройки проекта можно также в файле
src/api/constants.py
-
Перед запуском контейнеров убедиться, что в проекте
"рабочие миграции"
:Note
- Если возникает ошибка миграций, необходимо удостовериться, что директория с миграциями пуста!!!;
C:\...\tech_accidents\src\core\db\migrations\versions
- Если миграции в ней есть - очистить директорию от миграций.
- Если миграций нет, необходимо запустить
автогенерацию миграций
:alembic revision --autogenerate -m "first_migration"
- Если возникает ошибка миграций, необходимо удостовериться, что директория с миграциями пуста!!!;
-
При наличии "рабочих миграций" - можно собрать и запустить контейнеры из файла
infra/docker-compose.local.yml
. Эта команда создаст и запустит контейнер бэкэнда.Note
Перед запуском контейнеров необходимо убедиться, что нет ранее запущенного контейнера
tech_accidents_backend
.Если же он имеется - необходимо перед запуском сборки контейнера удалить прежний контейнер
tech_accidents_backend
и его образ!docker compose -f infra/docker-compose.local.yml up
Note
После успешного запуска контейнера, можно проверить работу приложения на тестовом эндпоинте:
- Выбрать тестовый эндпоинт проверки доступа к сети интернет: GET/api/test_get_url
- Нажать кнопку
Try it out
. - Нажать кнопку
Execute
. - Убедиться, что получен ответ
200
в теле ответаResponse body
.
-
После успешного запуска контейнеров, выполните следующую команду, которая войдет в контейнер и выполнит миграции:
Note
Перед выполнением следующей команды необходимо убедиться, что контейнер запущен. Остановить работу контейнеров в терминале можно сочетанием клавиш
CTRL + C
Команду необходимо выполнять либо в новом терминале, либо запускать контейнер в "десктопной версии" Доккер.docker exec -it tech_accidents_backend sh -c "alembic upgrade head"
Для запуска приложения в локальной сети необходимо выполнить следующие шаги.
-
Запустить приложение локально в контейнере Docker: Запуск приложения локально
Note
В приложении используется следующий проброс портов в Docker-контейнере:
ports: "8001:8001"
Изменить проброс портов Docker-контейнера можно в файле:
infra/docker-compose.local.yml
. -
Узнать
ip-адрес
"машины", на котором развернуто приложение в контейнере Docker:
сеть и Интернет > Ethernet > IPv4-адрес
вида:192.168.???.??
, например:192.192.192.92
- тогда - адрес в браузере для доступа к приложению в локальной сети будет:
192.192.192.92:8001/docs#
Запуск приложения в режиме для разработки.
-
Клонировать репозиторий.
git clone [email protected]:ArtemBalandin81/tech_accidents.git cd tech_accidents
-
Установить зависимости и активировать виртуальное окружение.
poetry env use python3.11 poetry shell poetry install
-
или указать путь до требуемой версии Python311, например:
poetry env use /C/Users/79129/AppData/Local/Programs/Python/Python311/python.exe poetry shell poetry install
Note
Note
You can get the path to your Python version by running
which python3.11
on Linux- or
py -0p
on Windows.
Note
Посмотреть установленные зависимости:
poetry show
Note
- Удостовериться, что директория с миграциями пуста!!!;
C:\...\tech_accidents\src\core\db\migrations\versions
- Если миграции в ней есть - очистить директорию от миграций.
-
Применить миграции базы данных.
alembic revision --autogenerate -m "first_migration" alembic upgrade head
-
Запустить сервер приложения.
uvicorn src:app --port 8001 --reload
-
Зарегистрировать первого пользователя, например:
email: [email protected] password: string_string
Note
- Выбрать эндпоинт регистрации: POST/api/auth/register
- Нажать кнопку
Try it out
.- Заполнить
"email"
и"password"
.- Нажать кнопку
Execute
.- Удостовериться что получен ответ 200:
"Успешная регистрация"
.
-
Создать
пользователя-бота
сid=2
в БД для автоматической фиксации простоев:- email: [email protected] - password: string_string - id=2
Note
При отсутствии пользователя-бота
[email protected]
сid=2
в БД возможны ошибки в работе приложения при автоматической фиксации простоев!!!
- Удостовериться, что зарегистрированные пользователи появились в БД (например с помощью
dbeaver
).
-
Установить права администратора одному из пользователей в столбце таблицы
is_superuser
и применить изменения, нажав кнопкуобновить
вdbeaver
. -
Далее можно работать с приложением, изучив примеры: Использование
Note
! Настройки приложения в первую очередь зависят от настроек переменных окружения.
!!! Если при изменеии каких-либо переменных в
settings
приложение не реагирует должным образом проверьте настройки.env
Изменения в
.env
применяются лишь после перезапуска приложения.
В этом разделе представлены наиболее часто используемые команды.
- Активировать среду: poetry shell
- Деактивировать: exit
- Установить зависимости из файла: poetry install
- Обновление пакетов: poetry update (poetry update ABC=1.3.2 BCD=1.2.3)
- Добавить новую библиотеку: poetry add --dev <package name>
(poetry add "pygame>=2" или poetry add pygame@^2)
- Удалить библиотеку: poetry remove <package name>
- Посмотреть зависимости: poetry show
- Generating requirements.txt: poetry export --without-hashes > requirements.txt
Подробнее: https://python-poetry.org/docs/cli/
Установку необходимо выполнять через curl, как в документации.
poetry env use python3.11; poetry install
-
Активировать виртуальное окружение
poetry shell
-
Добавить зависимость
poetry add <package_name>
Note Использование флага
--dev (-D)
позволяет установить зависимость, необходимую только для разработки. Это полезно для разделения develop и prod зависимостей.
poetry run <script_name>.py
В этом разделе представлены наиболее часто используемые команды.
- Запуск всех тестов:
pytest -vs
- Запуск всех тестов в 1 файле:
pytest -k test_filename.py -vs
- Запуск 1 теста:
pytest -k test_unauthorized_tries_suspension_urls -vs
Note
Тесты запускаются в основном каталоге приложения.
Конфигурационный файл для тестов:
tests/conftest.py
.Для отладки можно использовать:
- print(f'response_dir: {dir(response)}')
- print(f'RESPONSE__dict__: {response.dict}')
Для игнорирования предупреждений:
pytest -s -W ignore::DeprecationWarning
После выполнения инструкций, описанных в разделе Для разработки, будет запущен FastAPI-сервер по адресу: http://localhost:8001.
Полная документация API: http://localhost:8001/docs#.
Данный раздел содержит примеры использования Приложения.
Note
- Выбрать эндпоинт регистрации: POST/api/auth/register
- Нажать кнопку
Try it out
. - Заполнить
"email"
и"password"
. - Нажать кнопку
Execute
. - Удостовериться что получен ответ 200:
"Успешная регистрация"
.
- Войти на главную страницу, или выбрать любой эндпоинт с авторизацией: http://localhost:8001/docs#
- Нажать кнопку
Autorize
илизамочек
авторизации справа. - Ввести
username
иpassword
.
Note
Правами на изменение пароля обладают пользователь в эндпоинте: PATCH/api/users/me а также администратор: PATCH/api/users/{id}
- Выбрать эндпоинт редактирования текущего пользователя:
PATCH/api/users/me
- Нажать кнопку
Try it out
. - Заполнить
"email"
и"password"
. - Нажать кнопку
Execute
. - Удостовериться что получен ответ
200
.
Note
Изменить пароль также может пользователь с правами администратора в эндпоинте: PATCH/api/users/{id}
Note
Пароли хранятся в БД в хешированном виде и не доступны для считывания
Note
Приложение с заданным интервалом в секундах (SLEEP_TEST_CONNECTION) автоматически проверяет наличие доступа к двум адресам в сети интернет и при отсутствии доступа к обоим адресам - заносит простой в БД:
Зарегистрированный пользователь может занести случай простоя в БД
- Пройти авторизацию.
- Выбрать эндпоинт создания простоя:
POST/api/suspensions/form - Нажать кнопку
Try it out
. - Заполнить поля формы:
Note
Для изменения источника угроз в форме выбора необходимо:
- изменить переменную
RISK_SOURCE
в файле.env
списком требуемых названий угроз вида:
RISK_SOURCE="{\"ROUTER\": \"Риск инцидент: сбой в работе рутера.\", \"ANOTHER\": \"Иное\"}"
Note
Для изменения тех-процессов в в форме выбора необходимо:
- изменить переменную
TECH_PROCESS
в файле.env
списком требуемых названий техпроцессов вида:
TECH_PROCESS={"DU_25": "25", "SPEC_DEP_26": "26", "CLIENTS_27": "27"}
Note
- Ответ содержит описание нового случая простоя в формате
json
.- Имеется возможность скопировать данные в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).
Зарегистрированный пользователь - как автор простоя - может его редактировать.
Note
- Редактирвоание простоя также доступно админу.
- Созданный автоматически простой может редактировать только админ.
- *** Редактирование простоя через поля формы в разработке.
- Пройти авторизацию.
- Выбрать эндпоинт редактирования простоя: PATCH/api/suspensions/{suspension_id}
- Нажать кнопку
Try it out
. - Ввести уникальный номер простоя в БД, который необходимо отредактировать (доступ лишь у автора простоя и админа).
- Заполнить json, или поля формы*** (доступ лишь у автора и админа):
- Нажать кнопку
Execute
.
Получение случаев простоя, зафиксированных пользователем:
- Пройти авторизацию.
- Выбрать эндпоинт простоев текущего пользователя: GET/api/suspensions/my_suspensions
- Нажать кнопку
Try it out
. - Нажать кнопку
Execute
. - Удостовериться, что получен список простоев:
Note
- Ответ содержит список простоев текущего пользователя в формате
json
, отсортированный по дате добавления.- Позволяет получить все зафиксированные текущим пользователем простои и их
id
.- Имеется возможность скопировать список в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).
Анализ простоев за период по всем, или одному из пользователей:
- Авторизация не требуется.
- Выбрать эндпоинт аналитики простоев: GET/api/suspensions/analytics
- Нажать кнопку
Try it out
. - Задать период по предложенному шаблону ввода данных.
- Если оставить поле
«id пользователя»
пустым, будет получена аналитика по всем пользователям за выбранный период (или по конкретному пользователю, если указать «id»). - Нажать кнопку
Execute
. - В ответе содержится:
Note
- Ответ содержит аналитику и список простоев текущего пользователя (или всех) в формате
json
, отсортированный по дате добавления.- Позволяет получить все зафиксированные текущим пользователем простои и их
id
.- Имеется возможность скопировать список в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).
Note
Для получения списка
id
и
- выбрать эндпоинт GET/api/users под правами админа
- Нажать кнопку
Try it out
.- Нажать кнопку
Execute
и посмотреть список пользователей вида:"{\"1\": \"[email protected]\", \"2\": \"[email protected]\", \"3\": \"[email protected]\"}"
в ответе эндпоинта.
Постановка задачи пользователем (заказчиком задачи) исполнителю.
- Пройти авторизацию.
- Выбрать эндпоинт постановки задач: POST/api/tasks/post_task_form
- Нажать кнопку
Try it out
. - Заполнить поля формы:
Note
К задаче можно прикреплять
файлы
с уточняющей информацией. Допустимый формат и размер файлов задается в настройках проекта.Файлы можно добавить с использованием двух эндпоинтов:
- POST/api/tasks/post_task_form позволяет добавить задачу и 1
необязательный (опциональный)
файл, прикрепленный к ней.- POST/api/tasks/post_task_with_files_form позволяет добавить задачу и 1 или несколько
обязательных файлов
, прикрепленный к ней
Note
Для наполнения переменной
STAFF
в файле.env
списком
- выбрать эндпоинт GET/api/users под правами админа
- Скопировать строковое представление пользователей и вставить его в переменную
STAFF
в файле.env
:
STAFF="{\"1\": \"[email protected]\", \"2\": \"[email protected]\", \"3\": \"[email protected]\"}"
Note
Если новый исполнитель зарегистрировался в БД, но его еще нет в полях выбора формы можно задать его
Почта исполнителя не из списка
Note
Для изменения тех-процессов в форме выбора необходимо:
- изменить переменную
TECH_PROCESS
в файле.env
списком требуемых названий техпроцессов вида:
TECH_PROCESS={"DU_25": "25", "SPEC_DEP_26": "26", "CLIENTS_27": "27"}
- Нажать кнопку
Execute
. - Удостовериться, что задача была записана в БД
получен ответ 200
!
Note
- Ответ содержит описание новой задачи в формате
json
.- Имеется возможность скопировать данные в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).
Редактирование задачи пользователем (заказчиком задачи), или админом.
- Пройти авторизацию.
- Выбрать эндпоинт редактирования задачи: PATCH/api/tasks/{task_id}
- Нажать кнопку
Try it out
. - Ввести уникальный номер задачи в БД, которую необходимо отредактировать.
Note
- Доступ лишь у заказчика задачи и админа;
- Уникальный номер задачи можно получить в эндпоинте выданных пользователем задач: GET/api/tasks/my_tasks_ordered
- Заполнить поля формы и отметить, выполнена ли задача
Note
«True»
- выполнена,«False»
- еще в работе.- Если поля не заполнять, они останутся прежними.
- К задаче можно прикрепить новый файл, или не прикреплять. Чтобы добавить несколько файлов - необходимо редактировать задачу несколько раз.
- В случае выбора
«Удалить все прикрепленные файлы»
, все дополнительные файлы, прикрепленные к задаче, будут удалены безвозвратно как из БД, так и физически из каталога файлов.
Note
- Ответ содержит описание отредактированной задачи в формате
json
.- Имеется возможность скопировать данные в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).
Подробное описание задачи, с возможностью получения прикрепленных к ней файлов.
- Пройти авторизацию.
- Выбрать эндпоинт выданных пользователем задач: GET/api/tasks/{task_id}
- Нажать кнопку
Try it out
. - Выбрать формат отображения:
json
илиfiles
(дополнительно нажатьdownload_file
). - Нажать кнопку
Execute
.
Note
Список задач, выданных пользователем.
- Пройти авторизацию.
- Выбрать эндпоинт выданных пользователем задач: GET/api/tasks/my_tasks_ordered
- Нажать кнопку
Try it out
. - Нажать кнопку
Execute
.
Note
- Ответ содержит отстортированный по сроку исполнения список выданных пользователем еще нерешенных задач в формате
json
.- Имеется возможность скопировать данные в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).
Список задач, полученных пользователем.
- Пройти авторизацию.
- Выбрать эндпоинт полученных пользователем задач: GET/api/tasks/my_tasks_todo
- Нажать кнопку
Try it out
. - Нажать кнопку
Execute
.
Note
- Ответ содержит отстортированный по сроку исполнения список полученных пользователем еще нерешенных задач в формате
json
.- Имеется возможность скопировать данные в буфер обмана, или экспортировать в
файл json
, (открывается любым текстовым редактором).