Между Строк Требований|Блог системного аналитика
181 subscribers
24 photos
2 videos
6 links
О системном и бизнес-анализе, ИТ-архитектуре, технологиях и работе.
Собственно я: @tekhazanov1
Download Telegram
Размышления о GraphQL

Сегодня снова об интеграциях: подавляющее большинство интеграций в современных ИТ-продуктах и сервисах реализовано с использованием REST-подхода (мысли про который как раз писал в предыдущем посте). Однако не смотря на популярность этого архитектурного стиля, все равно не получится закрыть глаза на явные недостатки в виде over-fetching и under-fetching (иными словами избыточное и недостаточное извлечение данных), на которые я в том числе планирую сегодня ворчать.
Long Story Short: в очередной раз при проектировании сервиса и проработке его интеграций, когда понадобилось подключиться к другому нашему МС по готовому методу, возникли вот эти раздражающие мысли из серии "Мы сделаем 10 запросов к сервису, чтобы получить две нужные строчки на экран, но при этом получим кучу данных, которые нам, собственно, и не нужны". Так мне и пришла идея сделать ход конем — вкрутить саморезы гаечным ключом "А давайте замутим новую интеграцию через GraphQL 💻 и будем забирать только то, что нам нужно одним запросом!"
GraphQL для меня, как Биткоин. 💰 Он такой стильный, современный, все говорят, что за ним будущее, что вот-вот и фиатные деньги будут заменены им, ведь это удобно, децентрализованно и безопасно, но по факту реально расплатиться им ты можешь только в каком-нибудь Эквадоре, да и то при условии, что тебя после этого не подстрелят. Также и GraphQL — вроде что-то на прогрессивном и современном, но по данным на 2022 год (сорян, актуальнее данные не нашел не искал) подход используется всего-лишь в 0,4% сайтов. Почему так?

Пример полностью вымышленный, но похож на мой кейс (проект связан с парковками и видеонаблюдением):
GET /parkings/{parking_id} — тут получаем информацию по парковке, состоящую из огромного JSONа, 💻 берем отсюда только ID в системе Моспаркинга, все остальные данные нам не нужны;
GET /parkings/{parking_id}/address — тут получаем адрес.

С GraphQL это выглядело бы так:

query {
parking(id: parking_id) {
mospark_id
email
address {
city
street
building
}
}
}

В целом нормально, можно использовать: минимальное количество запросов к API, только необходимый набор данных. 💻 Тем не менее, могут возникнуть следующие сложности:

⚠️Один запрос на GraphQL может породить десятки SQL-запросов, если не использовать DataLoader. В REST эта проблема часто менее выражена, так как с предсказуемыми эндпоинтами он проще в управлении нагрузкой. Не надо одним запросом GraphQL дергать сотню полей с пятью уровнями вложенности... 🙏
⚠️Кэшировать GET-запросы по URL в REST легко. Кэшировать уникальные GraphQL-запросы на уровне HTTP — сложно. Для этого потребуются дополнительные инструменты, тот же DataLoader, например.

Собственно, GraphQL полезен в следующих кейсах 📈:
Много разных клиентов (мобильное приложение, веб, smart-TV) с разными потребностями.
Данные сильно связаны, и клиенту нужна гибкость в их получении.
Скорость разработки на клиенте критически важна (фронтенд может сам собирать свои данные).

Когда лучше выбрать что-то другое 📉:
🚩В случае простого CRUD-сервиса без сложных связей.
🚩Производительность и кэширование — главный приоритет, а команда не готова к сложностям.
🚩Нужны простые и стандартные мониторинг и логирование.

Возвращаясь к кейсу, который натолкнул меня на мысль начать использовать GraphQL на проекте, там в итоге было принято решение использовать REST, но по другим причинам: там планируется миграция сервиса с 🥲 на 💻, поэтому пока отказались от новых подходов.

Зафиналим философским выводом: GraphQL — это не «лучшая версия REST», а принципиально другой инструмент для других задач.

#GRAPHQL #API #HTTP #интеграция
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2💯1
To be honest, для следующего поста у меня была идея порассуждать на тему soft skills, но мой неугомонный кот в очередной раз устроил мне ночное пробуждение своим мяуваньем, поэтому сегодня будет пост про брокеры сообщений. Фото нарушителя приложено в комментарии,👨 а к посту мемчик на тему: Kafka и RabbitMQ. 🐇 Критерии выбора при декомпозиции монолита на примере сервиса обработки медиафайлов.

Как я уже упоминал в каком-то посте, на проекте, в котором я задействован, сейчас вовсю идет распилинг монолита на микросервисы, а заодно часть МС мигрируют с Python 👩‍💻 на Rust💻. Собственно, данный процесс уже давно идет и в рамках инфраструктуры активно используется RabbitMQ, так что есть повод порассуждать, почему именно такой выбор был сделан (к сожалению не мной, я пришел на все готовенькое, так что буду просто умничать на эту тему).
Очевидно, что брокер сообщений выбирается исходя из задач, которые будет выполнять система. В нашем случае мы имеем систему видеонаблюдения и распознавания. Грубо говоря, если ваша ТС оказалась в зоне, просматриваемой камерами, вы будете жестко сфотографированы📸, засняты на видео, а если вы что-то нарушили и дело дойдет до суда, то сурово наказаны как раз эти фоточки окажутся на столе у судьи. 👮‍♀️ На самом деле, в системе много МС и каждый делает что-то свое: сегментирует ТС, распознает ГРЗ, формирует разные отчеты по фиксациям и отправляет их во внешние системы, стримит видео и т.д. Упростим для примера: комплекс снимает фото и передает его какому-нибудь МС в облако, а МС что-нибудь с этим кадром делает (отчет, например) и назовем его, например, Video Analyzer (название вымышлено).

Когда нужно наладить асинхронную передачу данных между микросервисами, первое архитектурное решение — выбор между RabbitMQ и Kafka. Ключевое различие между ними в том, как сообщения попадают к потребителю.

Основное отличие: Push против Pull
✍️RabbitMQ работает по push-модели. Как только сообщение появляется в очереди, брокер немедленно проталкивает его на одного из доступных потребителей.
✍️Apache Kafka использует pull-модель. Потребители сами периодически опрашивают брокера, готовы ли новые сообщения к обработке.

Почему же в моем кейсе RabbitMQ предпочтительнее:
💪Мгновенная доставка (Push). Камера отправляет кадр в RabbitMQ, и брокер сразу же проталкивает его на свободный экземпляр Video Analyzer. Это обеспечивает минимальную задержку между съемкой и началом анализа, что критично для систем реального времени.
💪Балансировка нагрузки из коробки. RabbitMQ автоматически распределяет кадры между всеми работающими экземплярами Video Analyzer. Это не требует дополнительной логики на стороне потребителей.
💪Идеальное соответствие модели «задача-результат». Обработка каждого кадра — это отдельная, атомарная задача. RabbitMQ гарантирует, что каждый кадр будет обработан, а в случае сбоя обработчика будет перенаправлен другому.

Простой пример сообщения, которое можно передать в брокер, чтобы забрать картинку с S3:
{
"image_path": "s3://camera-bucket/entrance/2023-10-26/cam_01_15-30-00.jpg",
"camera_id": "cam_entrance_01",
"timestamp": "2023-10-26T15:30:00Z",
"analysis_type": "object_detection"
}

А что по Кафке?

Поскольку Kafka имеет pull-модель, микросервис Video Analyzer будет вынужден ее постоянно опрашивать: «Есть ли новые кадры?». Это создает дополнительную нагрузку и может увеличить задержку. Kafka великолепна там, где нужна гарантированная доставка и сохранение потока событий (например, телеметрия или логи), где можно обрабатывать данные пачками. Но для нашего сценария, где важна скорость реакции на одиночное событие, это избыточно.

Как обычно, глубокий вывод в конце:
RabbitMQ (Push) — ваш выбор, когда события требуют немедленной реакции и вы работаете с отдельными, важными задачами. Как в нашем случае с передачей кадров. 🧐
Kafka (Pull) — ваш выбор, когда вы имеете дело с непрерывным потоком данных, который нужно надежно хранить и иметь возможность переигрывать. 😎

#MessageBrokers #Kafka #RabbitMQ #Microservices #Architecture
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82🔥1
Каждый раз к концу рабочего дня в офисе у меня на столе собирается вот это 👆 (на фоточке). 😵‍💫
На самом деле, по моему договору на текущем месте у меня фулл-удаленка, даже привязки к конкретной стране нет, что по нынешним временам дорогого стоит. 😎 Тем не менее, пару раз в неделю я езжу в офис: так принято в текущей команде, и я понимаю, почему. Онбординг проходит легче, а погружение в процессы быстрее, взаимодействие между людьми выстраивается лучше, да и вообще, мне кажется, люди друг к другу теплее относятся, когда видят друг друга вживую, а не через фасад аватарок в маттермосте.
Надо сказать, что с начала пандемии я ни разу не работал в гибридном режиме — только удаленка. При этом, вроде как, все получалось: и со стейкхолдерами общаться, и с коллегами взаимодействовать, собственно, и задачи закрывались. Тем не менее, сейчас я часто ловлю себя на том, что часть вопросов просто удобнее обсудить face-to-face. Начинается вот такое: "Ты же в среду будешь в офисе? Ну давай тогда как раз обсудим это/посмотрим то." И вот с одной стороны на среду уже накидано несколько очных встреч, но с другой стороны они проходят продуктивно и наглядно. Особенно, если нужно что-то вместе посмотреть и пощелкать в какой-нибудь системе. Да, конечно, очень не хватает возможности сделать запись экрана во время встречи, чтобы потом отстенографировать ее какой-нибудь нейронкой и иметь уже перед глазам основные тезисы, но в остальном оно все равно удобнее лично общаться.
В целом, конкретно на текущем месте мне мотыляться в офис по кайфу, тут есть ряд перков:
🌟 Мне очень повезло с коллективом: все классные, всякие хиханьки, хаханьки и смехуечки — это святое дело тут;
🌟 Он близко к моему дому;
🌟 Регулярное приятное чувство смены обстановки (возможно это уйдет со временем, но пока есть);
🌟 Мой рабочий день в офисе стоит на 700 рублей дороже, чем удаленный. 🤑 У нас это компенсация за питание, приятный бонусик. Если в день, когда я в офисе, я поел меньше, чем на 700 рублей, то этот день я считаю профицитным. 📈 К сожалению, такого еще не случалось ни разу, так как я очень много жру...
🌟 Бесплатный невкусный кофе. Если бы он еще и вкусным был, я бы вообще спился бы... 🍵
Минусы:
1. Дождь на улице.

Возможно, оно так комфортно воспринимается мной, так как нет чувства обязаловки, да и по факту получается гибрид. Посему объявляю голосование. Мотаться в офис: стрем или норм? 👇

#работа #гибрид #удаленка #системныйанализ
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5🔥32
#Devops для аналитиков
Решил я немного погрузиться в основы деплоя и раскатки ПО. Во-первых, у нас на проекте свои полноценные Devops-практики с блекджеком GitLab и CI/CD, да к тому же одна из моих задач сейчас связана с разработкой софтины по мониторингу работоспособности камер, а также с некоторыми сервисными операциями по восстановлению работоспособности отдельных камер. Среди нужных фичей там актуализация Docker-образов, перезапуск контейнеров и всякое такое... Короче, предлагаю сегодня в связи с этой темой посмотреть, какие файлики должны быть в папке с проектом, чтобы задеплоить и развернуть твой print("Hello World") с оркестрацией и релизным пайплайном. 😄
Итак, что у нас может быть в папке с проектом.

👩‍💻 Docker файлы
Dockerfile — инструкция для сборки Docker-образа;
docker-compose.yml — запуск нескольких контейнеров вместе;
docker-compose.dev.yml — версия для разработки;
.dockerignore — что НЕ копировать в Docker-образ.

👩‍💻 CI/CD (GitLab)
.gitlab-ci.yml — пайплайн автоматической сборки, тестов, деплоя;
k8s-cronjob.yaml — задания по расписанию в Kubernetes.

👩‍💻 Git и документация
.gitignore — какие файлы игнорировать в Git;
.gitattributes — настройки обработки файлов в Git;
README.md — документация проекта;
.ipynb — Jupyter notebook с примерами/анализом.

🛠 Конфигурация
config.yml — общие настройки приложения;
.local.env.tests, env.tests — переменные окружения для тестов;
lockalhost_local_start.sh — скрипт для запуска локально.

👩‍💻 Python
.python-version — какая версия Python используется;
.pylintrc — настройки линтера (проверка качества кода);
mypy.ini — настройки статической типизации;
pip.conf — настройки менеджера пакетов pip;
logging.conf — настройки логирования;
.pyarmor_config — настройки обфускации кода.

👩‍💻 Rust (ну раз уж он у нас тоже на проекте есть)
Cargo.toml - зависимости и настройки проекта (как requirements.txt);
Cargo.lock - точные версии зависимостей (генерируется автоматически).

🎯 Что все это дело дает для деплоя:
1. Сборка → Dockerfile + docker-compose;
2. Тестирование → .gitlab-ci.yml + env.tests;
3. Деплой → .gitlab-ci.yml + k8s-cronjob.yaml;
4. Настройка → config.yml + переменные окружения.

In conclusion: у каждого в команде своя роль и своя специализация, но системный аналитик должен разбираться во всех этапах разработки ПО и ввода его в эксплуатацию (в том числе иметь представление, как работают Devops-инженеры).

#DevOps #системныйанализ #работа #docker #python
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍21
По ту сторону баррикад требований
Довелось мне тут давеча побывать в роли капризного стейкхолдера, который пока не определился с тем прекрасным будущим, которое он хотел бы видеть. В чем суть: так получилось, что в моей текущей компании я первый системный аналитик, поэтому процесс работы, практики и ритуалы приходится выстраивать с нуля. Собственно, по началу я немного даже провалился между стульев: де-юре я был причислен к архитектурному отряду, по факту работал с продуктовой командой. 🍔
Тем не менее, было принято волевое решение сформировать R&D отряд, в котором в том числе оказался и я (с продуктовой командой продолжаю работать). Так вот мне и было поручено заняться проработкой процесса работы: в том числе поставить задачу на ITSM по настройке проекта в Jira. 👩‍💻 Если в создании пространства в Confluence 🖼️ каких-то сложностей нет, то в случае с Jira нужно точно понимать, что ты хочешь.
Итак, что у меня было для постановки задачи:
☑️ 2 пакета травы, 75 табле...
☑️ Примерное представление, что у нас проект будет разделен на две Канбан-борды (для аналитики и разработки);
☑️ Список необходимых статусов, но без четкого понимания статусной схемы;
☑️ Видение интеграции с доской продуктовой разработки.
В задаче на ITSM команду я честно старался не писать в стиле "деловойте хорошевое плоховое не делойте", но все равно не получилось. Были какие-то слепые пятна, про которые я малодушно думал: "ну, там ребята сами как-нибудь придумают, чтобы красиво было". 🙏

В чем собственно моя проблема? Их две.
1️⃣ Отсутствие четкого видения процесса: как все должно быть в итоге;
2️⃣ Отсутствие знания всех возможностей Jira.

Как все это решилось? Профессионализмом ITSM-команды. Ребята не стали городить что-то от себя, а провели со мной две огромные интервью-сессии часа по полтора для выявления требований, где мы сформулировали в деталях весь процесс, посмотрели возможности Jira, прогнали несколько вариантов процессов и в итоге замутили обалденную двойную борду (а точнее две доски в одном проекте) с проработанным workflow и интеграцией с другим проектом.

Философский вывод (ну как обычно): профессиональное выявление требований — это не просто выслушать хотелки , чтобы задокументировать их. Это еще и помочь стейкхолдеру сформировать видение, которое учитывает баланс между потребностью, рисками, бюджетами и техническими возможностями. Побывав в роли "заказчика" прям чувствуешь это на себе.

#SystemAnalysis #Agile #Scrum #Kanban #Jira #СистемныйАнализ #ITSM #ЛичныйОпыт
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2😁1
Слепые пятна в подробнейшей документации и Client-Side Data Enrichment в микросервисной архитектуре

Я стараюсь очень подробно писать все свои доки. Так, чтобы максимально исключить возможность неоднозначных трактований, вопросы и неопределенности. Тем не менее, бывают случаи, что вопросы все-таки возникают там, где вроде бы все ну очень понятно. Собственно, про один такой случай я и хочу рассказать. 💖

Преамбула: есть микросервис (назовем его Микросервис1) и БД 📂, которую он обрабатывает, назовем ее, допустим DB лол, в данной БД есть таблица object с полями id (это пусть наш первичный ключ), полем name, ну и всякими прочими полями, которые нам для примера не нужны (изобразил на картинке ER схематичненько). 🖼 У нас тут микросервисная архитектура, вот это вот все, поэтому к DB имеет доступ только Микросервис1 и все данные этой базы мы должны обрабатывать через него. Я же разрабатываю Микросервис2, которому в какой-то момент потребуется поле object.name, чтобы что-нибудь с этим полем сделать (а именно наложить в качестве метаданных на монтируемое Микросервисом2 видео). 🐸

Ну, вроде, все понятно, поэтому переходим к сути:
В спеке у меня описание POST запроса от FE к Микросервису2, body которого по описанию должен выглядеть примерно вот так:
{
"object_id": 123,
"object_name": "Какое-то_имя_объекта_тут",
"request_datetime": "2025-11-03T10:12:31"
...
}

Ну и так далее, всякие поля дальше идут. Пишет мне фронтендер и спрашивает:
"Амиго, а зачем мы тут имя объекта передаем, если у нас есть его id?"

А я смотрю и реально не понимаю, на кой хрен я тут пытаюсь передавать имя, которое правильнее было бы просто по ключу из БД забирать... 🔨 Какой кринж и как я вообще мог так затупить? Я посчитал, что я ошибся, и согласился с разработчиком, что лучше это поле убрать отсюда и забрать на бэкенде, после чего пошел заниматься другими делами. Правда минут через 15 в голову пришла не сразу оформившаяся мысль в формате:
"Так, блэт, минуточку!.." 🌳

Перелистал еще раз спеку и вспомнил, что моя задумка была такая: передать сразу с фронтенда на уровень Микросервиса2 те данные, что нам нужны и уже есть на фронтенде, чтобы избежать большого количества запросов уже со стороны Микросервиса2 к Микросервису1. Например, чтобы получить имя объекта. Поэтому, Андрюха, по коням, у нас труп Client-Side Data Enrichment! 😁 Мы передаем избыточные данные с FE и, возможно, дублируем их на уровне БД микросервиса для того, чтобы уменьшить количество запросов между нашими сервисами. (Имя объекта в запрос вернули, все хорошо).

К чему я все это? К тому, что вся эта ситуация случилась через 5 дней после того, как я закончил писать эту спеку. Вот так мало времени потребовалось мне (автору доки, если что), чтобы какие-то нюансы просто вывалились из головы.

Философское завершение: лучше больше документации, чем меньше документации. Все классные идеи будут либо задокументированы, либо забыты, потому что у всех у нас место в голове до конца жизни уже занято чит-кодами для гта, а для всего остального есть Confluence. 🖼️ AEZAKMI

#интеграция #API #REST #HTTP #системныйанализ #json
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Роль системного аналитика в проектах с Computer Vision и Machine Learning

Если смотреть в целом, то задачи системного (либо фуллстак) аналитика в проекте с CV+ML не сильно отличаются от выполняемых в других доменах: тот же сбор, валидация и документирование требований, разработка спецификаций, а для тех, кто "постарше" — проектирование архитектуры, ну и дальше опционально могут добавляться user acceptance testing, обучение ключевых пользователей, функциональное тестирование, онбординг юнцов, организация и проведение корпоративов и вообще все, что можно придумать. 👨‍💻 Трактовать эту роль в разных компаниях могут по-разному: например, на текущем проекте мне пришлось выполнить несколько PM-задач в процессе формирования нового R&D-отряда (в общем-то, проработать рабочие процессы и организовать интеграцию с продуктовой командой, к которой я все еще на 50% принадлежу). 😎
Тем не менее, каждый домен имеет свои особенности. Если сравнивать ML с доменом ERP, в котором у меня есть достаточно большой опыт, то можно заметить, что основное отличие: требования в ERP в основном четко формализуемы и детерминированы ("сделайте кнопку, чтобы у меня проводки вот по этому счету бахались"), 📞 в то время как при работе с распознаванием всяких штук на видео всегда имеется высокая степень неопределенности и даже функциональные требования могут быть завязаны на метрики, где метрика — измеримое Acceptance Criteria:
"Котиньки на фотографии должны сегментироваться с точностью 95%". 😿

Что это добавляет в мою работу, как системного аналитика? Проведение исследований, от которых будет зависеть дальнейшее движение продукта (не даром же у я на 50% в R&D-отряде). Важно отметить, что я даже близко не ML-специалист, но я прихожу к ним с конкретным запросом: "Есть гипотеза, надо проверить". Для примера рассмотрим мой недавний кейс.

Сектор "Кейс" на барабане
Есть ML-ка, которая сегментирует и распознает дорожные знаки, по знакам, соответственно, можно определить правонарушение, в размеченной вручную зоне на кадре. Бывает так, что знаки к камере повернуты "спиной" и тогда такой кадр не получится использовать в суде. При разметке зон действия знака возникла потребность помечать такие знаки, развернутые к камере. Однако бывают ситуации, когда знак развернут к камере углом, при котором человеческий глаз может понять, что именно за знак, а вот ML — под вопросом. 📹 Нужно было определить, требуется ли придумывать отдельный "статус" для таких сцен, а мне для этого надо было понять, в какой момент (при каком угле поворота) ML перестает распознавать знак и можно ли (нужно ли?) как-то дообучить модель. С запросом на такое исследование я и пошел к ML-команде. После чего моей задачей было провалидировать результаты исследования с требованиями стейкхолдеров принять решение: вводим "промежуточный" статус или нет.

Мораль: в любой сфере есть своя специфика и нюансы, поэтому в первую очередь нужно качать софт-скиллы, но это не точно.

#системныйанализ #ML #DL #AI #CV #computervision #machinelearning
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍21🔥1
Short Polling vs Long Polling: донимать пустыми запросами или ждать у моря погоды

Не так давно писал спеку по фиче, которая предполагает передачу данных в режиме реального времени. Не вдаваясь в детали, это разработка микросервиса, который определенным образом монтирует видео и было требование того, чтобы на UI в режиме реального времени видеть статус обработки. 🎬
Изначально для этой цели я предполагал использовать WebSocket: открывать канал связи и получать сообщения напрямую с сервера, однако после обсуждения с архитектурной командой было принято решение, что держать открытыми соединения по каждой заявке на монтаж видео лишь для того, чтобы красиво рисовать полоску загрузки на экране... Охренеть как Немного расточительно. 👌 Поэтому про WebSocket пост будет как-нибудь потом, а сегодня мы поговорим про Polling.

Polling — это в некотором смысле имитация обмена данными в режиме real-time, можно сказать в режиме псевдо-реального времени. Мы не передаем сообщение напрямую с сервера на клиент, клиент запрашивает данные с сервера, но делает он это автоматически с заданной регулярностью. Есть две концепции: Short Polling и Long Polling.

Short Polling — клиент с заданным интервалом (например, каждые 2 секунды) отправляет на сервер запрос по схеме «Есть ли что-нибудь новое?». Сервер всегда сразу отвечает — либо с новыми данными, либо с пустым ответом. Представим себе ребенка в машине, который с интервалом отправляет запрос спрашивает маму за рулем:
"Мы уже приехали? Мы уже приехали?"

Он будет спрашивать это вне зависимости от того, молчит ли мама или уже рявкнула на него:
"ЕЩЕ НЕТ!" 💥


Long Polling
— Клиент отправляет запрос, сервер не отвечает сразу, а «замораживает» запрос до тех пор, пока не произойдет нужное событие ИЛИ не истечет таймаут (например, 30 секунд). Как только событие происходит, сервер немедленно отправляет ответ клиенту. Клиент, получив ответ, тут же отправляет следующий запрос. По аналогии с предыдущим примером, это ребенок, случайно хлебнувший утром батиного чая с коньяком и поэтому он задает вопрос бате за рулем и спокойно ждет ответа, пока на стороне сервера таймаут:
"Сколько времени нам еще ехать?"

После паузы батя отвечает и лишь после этого задается новый вопрос (надеюсь он не пил тот чай с коньяком, прежде чем сесть за руль).

Философское завершение: выбор между подходами — это классический компромисс между простотой и эффективностью.

P.S. Современными альтернативами для обоих подходов являются WebSocket (для двусторонней постоянной связи), его мы уже упоминали сегодня, Server-Sent Events (SSE) (для потоковой передачи данных от сервера к клиенту), gRPC Streaming и некоторые другие технологии, но везде есть свои нюансы и их мы обсудим в другой раз. 🔗

#системныйанализ #Архитектура #WebDevelopment #websocket #HTTP #интеграции
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3😁1
«А вот по поводу той фичи...» — как вести интервью со стейкхолдером, который хочет говорить о другом.

Большую часть своей карьеры я играю на позиции именно FullStack-аналитика, поэтому коммуникация со стейкхолдерами и сбор требований — важная часть моей работы и не часто удается переложить её на бизнес-аналитика. Вряд ли я кого-то удивлю, сказав, что есть разные классы стейкхолдеров и у всех них разные цели, задачи и потребности. Product Owners, конечные и ключевые пользователи, заказчики, инвесторы, support и т.д.: каждый будет заботиться о чем-то своем. ✍️ Мой сегодняшний пост будет не о том, как глобально дирижировать оркестр ожиданий стейкхолдеров, но как говорить с одной группой людей о том, что на самом деле волнует другую группу во время интервьюирования. 🎤

Я сейчас работаю над задачей, инициатором которой был... Лид команды разработки. Как так получилось? Есть некоторая проблема с накоплением излишних и дублирующих данных в БД. С момента проектирования прошло какое-то количество времени, часть бизнес-процессов поменялась, часть просто не была учтена при проектировании, внедрена новая функциональность и вообще много всего изменилось. Инициатива заключается в том, чтобы редизайнить схему данных для устранения имеющихся проблем. На данный момент мне кажется, что решение в конечном счете будет заключаться в денормализации, но детали еще предстоит выяснить. ⚙️

В чем на данный момент заключается моя задача? Выяснить у ключевых пользователей существующие на данный момент бизнес-сущности, взаимосвязи между ними, варианты их взаимодействия с точки зрения бизнеса и потом переложить это на модель данных. По этой теме я и решил пообщаться с одним из key users, тем более что контакт у нас с ним налажен очень хороший 💬 (unlimited бар на корпоративе сыграл в этом не последнюю роль, за что спасибо нашей компании). Сложность здесь в том, что его, как стейкхолдера, чьи подчиненные пользуются системой, вообще-то не особенно интересуют наши модели данных, таблицы, БД и как вообще все их объекты выглядят у нас под капотом. Поэтому в конечном счете диалог пришел к:
"Схема данных — это хорошо, но вот что нам реально нужно, так это предзаполнение полей вот на этом экране, а также..." 🖥

Ну, и так далее в таком духе. Thank God, у меня фича по этой теме давно в работе, поэтому я честно смог сказать, что работа кипит и скоро будем проводить UAT. 🗓 Интервью в итоге получилось максимально эффективным — я получил исчерпывающие ответы и очень классный схематичный рисунок в придачу, со своей стороны поделился статусом текущих задач.

Какой бы вывод я мог бы сделать для себя? Есть много разных приемов для эффективного ведения переговоров, которые я стараюсь использовать. Существуют приемы, направленные именно на выявление требований, они тоже есть в моем арсенале. Но самое эффективное из того, что я пробовал — это вставать на сторону интервьюируемого и искренне погружаться в его запросы и разделять ценности. Когда человек понимает, что вы играете в одной команде, он перестает быть оппонентом по переговорам, а становится напарником в общем деле создания хорошего продукта. Ведь если вы в одной команде, то как вы помогаете напарнику, так же и он поможет вам. Важно уметь напоминать об этом союзе, демонстрируя свою заинтересованность. 🔝

Философское саммари: Сбор требований — это не просто извлечение информации из головы стейкхолдера. Это ведение переговоров для укрепления взаимовыгодного партнерства.

#СборТребований #StakeholderManagement #Коммуникации #Переговоры #системныйанализ #softskills #IT
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3👏1
Инструменты, которые я использую в работе. Краткий обзор. 🔨

⚙️ Документирование: Для документирования (требования, спеки и т.д.) использую только Confluence 🖼️ и работаю с этим инструментом каждый день, тут особо ничего интересного. Из аналогов знаю Notion и Yonote, но в работе ими не пользуюсь (хотя использую для личных заметок). Ах да, и еще немного Swagger 👩‍💻 для API.

⚙️ Контроль задач: Чтобы не отходить далеко от Confluence, сразу скажу про таск-трекер — Jira 👩‍💻, тут тоже ничего особенного. Здесь веду и свои задачи и те, которые выставляю на разработку.

⚙️ Моделирование: Вот тут сейчас будет жесткий байт на комменты мое непопулярное мнение: я для моделирования использую Draw.io. Полетели тапки. Пока все от меня не отписались, я поясню: 1⃣В Confluence есть патч для интеграции Draw.io, поэтому все модели оказываются интегрированы прямо в доки и их можно редактировать там даже без изменения самого дока. Это очень удобно. 2⃣Универсальность. Да, я иногда пользуюсь и PlantUML, и Camunda, и dbdiagram.io (это для ER), но если нужна именно модель (визуальненько) просто удобнее это делать в одном месте. Поэтому UML, BPMN, C4, ER — все тут, в Draw.io.

⚙️ БД: А вот здесь ситуация обратная в сравнении с предыдущим пунктом в плане универсальности, поскольку для каждой БД я использую свой клиент. PgAdmin 👩‍💻 для Postgres, MongoDB Compass для Mongo, S3 Browser для S3. Раньше я использовал Dbeaver, подходящий и к Pg и к Mongo, но не углубляясь в детали, на текущем проекте он не очень мне подходит.

⚙️ Интеграции: Само собой это Postman 👩‍💻 — каждый день (тестирование API и запуск моков), очень редко SOAPUI и Insomnia, т.к. Postman в принципе покрывает всю необходимую функциональность. А также использую "Инструменты разработчика" браузерах, у нас web UI, поэтому очень удобно смотреть какие методы с UI вызываются, какие данные передаются и принимаются.

⚙️ Работа с кодом: GitLab 👩‍💻 для доступа к кодовой базе для чтения кода, если нужно что-то локально позапускать, то IntelliJ IDEA 👩‍💻, а конкретно PyCharm 👩‍💻 и RustRover.

⚙️ Прототипирование UI: Готовьте ваши тапки, на сцене снова Draw.io! Причины те же, что и в пункте с моделированием, а также хочу сказать, что у Draw.io есть классная типа "либа" Bootstrap как раз для прототипирования интерфейсов, очень удобно. Figma 👩‍💻 мне не очень удобна, это вообще скорее для дизайнеров, пробовал еще Pencil — тоже не фонтан. Из популярных помню Miro и Unidraw, коллеги на проекте ими пользуются, я не очень.

⚙️ AI: Ну, конечно, куда сейчас без него. В основном это DeepSeek и ChatGPT, ничего изощренного. Основные Use Cases: набросать код Mermaid для диаграммы по описанию, составить шаблон какого-нибудь дока, иногда SQL-запрос или просто накидать идей для дальнейшей проработки. Конечно, любой результат работы чудо-машины нужно править руками, а просить написать Эй-Ай доку... Это просто не работает, поэтому все доки я всегда пишу руками, но надо сказать, что они у меня чертовски хороши.

⚙️ Всякое прочее разное: Бывают штуки, которые используешь редко, но иногда они пригождаются. Всякие JsonValidator, Grafana, Prometheus... Paint. ✏️ (Нет).

⚙️ Телеграмчик: Чтобы постить всякое себе в канал. Огромное спасибо за Markdown разметку, я ее обожаю.

Философский финал в восточном стиле: Ученик попросил мастера показать его лучшую кисть. Мастер указал на свою руку. 🎨

#системныйанализ #инструментарий #диаграмма #bpmn #UML #confluence
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8👏1
This media is not supported in your browser
VIEW IN TELEGRAM
🖥Тестирует ли что-нибудь системный аналитик?
Мой ответ на данный вопрос будет провокационный, потому что я считаю, что... Да, аналитик может принимать участие в тестировании, но...
Есть один нюанс.

🛠 В разработке любого сложного программного продукта обычно принимает участие QA, который выполняет огромное количество разных видов тестирования: ручное функциональное, нагрузочное, регрессионное тестирование, white box/black box, тестирование как негативных, так и позитивных сценариев и чёрте что еще. ⚙️
Системный/fullstack аналитик — это по традиции человек-оркестр (мемчик на эту тему прилепил к посту), но все-таки весь спектр задач тестировщика на него взвалить не получится. 🤪Тем не менее, два вида тестирований, в которых я стараюсь участвовать:

➡️Функциональная приемка — это ручное функциональное тестирование позитивного сценария сразу после того, как разработчик выполнил задачу и задеплоил ее на тестовый стенд (хотя в некоторых случаях я разворачиваю доработку у себя локально для этих целей). Основная задача тут — верхнеуровнево провалидировать соответствие выполненной работы заявленным требованиям и аппрувнуть выполнение со своей позиции. Либо заранее начать бухтеть, если что-то не соответствует с моей точки зрения.
➡️User Acceptance Testing — все то же самое, но уже совместно со стейкхолдером/ключевыми пользователями. Посидеть вместе, потыкаться в новую функциональность, собрать ОС.

Хочу подчеркнуть, что в каждой избушке свои погремушки в разных командах, компаниях, на разных проектах могут быть свои подходы и свои традиции, поэтому у вас все может быть совсем не так, а тут я лишь описал свое представление об идеальном мире. 🎩

Как обычно философствую в конце: участие системного аналитика в тестировании — это не про поиск багов, а про валидацию ценности. Хотя, если честно, находить и описывать баги тоже периодически приходится.

#SystemAnalysis #Тестирование #QA #UAT #ФункциональнаяПриемка #BusinessAnalysis
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82😁1
🔛 Фича-флаги: что делать, чтобы не класть весь прод разом
Честно скажу, я совсем недавно узнал, как это на самом деле называется: Feature Flag. Я, в общем-то, всегда звал это просто — рубильник. 💩 Ну да ладно, короче, к сути.

Фича-флаг, он же Feature Toggle, а также Feature Flag (как же чертовски круто это все звучит) — это переключатель, который позволяет включать или выключать функциональность в работающем приложении без перевыпуска кода.

Ну грубо говоря как-то так:
if feature_flag.is_enabled('new_payment_system'):
use_new_payment()
else:
use_old_payment()

После того, как по моим постановкам пару раз положили прод там, где лучше бы этого было не делать, я начал частенько прописывать необходимость рубильника. (Чтобы я не сидел потом, как эта несчастная псина на картинке).

Зачем вообще это все нужно?
🟣Безопасные релизы. Увидели проблему? ➡️ Выключаем тумблер ➡️ Фича не работает, хотя код уже в проде.
🟣Dark Launches. Можно задеплоить код в прод, но не показывать его пользователям (пока не пришло время).
🟣Условный доступ: включить фичу только для внутренних тестировщиков/конкретной группы пользователей.
🟣Для A/B-тестов, но это для PO, наверное, интересно, я за такое вообще не шарю. 🤷 Просто знаю, что так делают.

Какие есть способы дернуть рубильник?
🔴Таблица в БД: плюс в том, что возможно динамическое изменение без перезапуска. Минусы — нужна соответственно инфраструктура (сама БД).
🔴Переменные окружения. Переключение через .env файл достаточно просто реализовать, но из минусов — переключение флага скорее всего потребует перезапуска.
🔴Конфигурационные файлы (JSON, YAML, TOML, .properties) — примерное те же минусы и плюсы, что в случае с переменными окружения.
🔴Специальные сервисы фича-флагов (их, оказывается, много всяких есть): LaunchDarkly, Split, Flagsmith, Unleash, CloudBees Feature Management. Тут и гибкость в настройке, и изменения в режиме реального времени, но с другой стороны зависимость от еще одного сервиса.

Что важно учитывать:
⚠️ Постараться Не забывать убирать флаги после полного внедрения фичи;
⚠️ Постараться Документировать флаги — какие есть, для чего, кто отвечает;
⚠️ Постараться Не превращать систему в спагетти-код из условий.

In conclusion: Фича-флаги — это не просто технический инструмент, это стратегия безопасной поставки изменений.

#SystemAnalysis #FeatureFlags #Разработка #python #IT #businessanalysis
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥21
✍️ Нормально делай — нормально будет: пост о нормализации БД

Наверное, как бы качественно и продумана ни была бы БД на старте проекта (на этапе Proof of Concept или MVP), если продукт развивается, если добавляются новые фичи, логика, бизнес-процессы и т.д., то скорее всего рано или поздно все-таки потребуется что-то в имеющейся модели данных перестроить. 👷 Один из способов реорганизации БД называется нормализацией. Собственно, вот и у меня сейчас есть потребность в нормализации некоторых таблиц в БД, что привело к идее поста. 🥺 Кстати, одну таблицу при этом придется денормализовать, так как выделенная в рамках таблицы сущность является излишней с точки зрения бизнес-объекта. 💥 Да, и такое бывает.

Нормализация — это процесс организации данных в базе для устранения дублирования и обеспечения их целостности. Часто её представляют как строгий этап проектирования, который нужно выполнить перед написанием первой строки кода. 🌳 Однако на практике всё часто иначе: нормализация становится необходимым шагом уже в процессе развития работающей системы. И не потому что "жмяк-жмяк и в продакшн", а потому что система растет и процессы усложняются.

Причины задумываться о нормализации (из тех, что наблюдаю конкретно я):
➡️Появляются требования к неизменности исторических данных (например, данные о заполненности парковки в разные моменты времени);
➡️Одинаковые данные приходится обновлять в куче полей;
➡️В систему вводятся сложные бизнес-правила, которые трудно реализовать в текущей структуре.

По канону есть три фазы нормализации (вспомню свое ERP-прошлое, поэтому разберу на примере с заказами на поставку):
1️⃣ Первая нормальная форма (1NF)
Цель: Убрать повторяющиеся группы и сделать все значения атомарными.
Действие: Если в заказе может быть несколько товаров, их нужно вынести в отдельную таблицу.
CREATE TABLE orders (order_id INT PRIMARY KEY, customer_name VARCHAR, customer_phone INT, order_date DATE);
CREATE TABLE items (item_id INT PRIMARY KEY, order_id INT NOT NULL, product_name VARCHAR, product_price NUMERIC(10, 2), FOREIGN KEY (order_id) REFERENCES orders(order_id));

2️⃣ Вторая нормальная форма (2NF)
Цель: Устранить зависимость неключевых полей только от части составного ключа.
Проблема: Цена и название товара в items зависят только от product_name, а не от всей пары (order_id, product_name).
Действие: Создаём справочник товаров.
CREATE TABLE products (product_id INT PRIMARY KEY, product_name VARCHAR NOT NULL, price NUMERIC(10, 2));
CREATE TABLE items (item_id INT PRIMARY KEY, order_id INT NOT NULL, product_id INT NOT NULL, price_at_order NUMERIC(10, 2), FOREIGN KEY (order_id) REFERENCES orders(order_id));

3️⃣ Третья нормальная форма (3NF)
Цель: Убрать транзитивные зависимости, когда поле зависит не от первичного ключа, а от другого поля.
Проблема: Телефон клиента в таблице orders зависит от его имени, а не напрямую от order_id.
Действие: Выносим данные о клиенте в отдельную сущность.
CREATE TABLE customers (customer_id INT PRIMARY KEY, name VARCHAR NOT NULL, phone INT);
CREATE TABLE orders (order_id INT PRIMARY KEY, customer_id INT NOT NULL, order_date DATE NOT NULL, FOREIGN KEY (customer_id) REFERENCES customers(customer_id));


По традиции философский вывод: главный критерий необходимости нормализации — не объём данных сам по себе, а появление требований, которые сложно или рискованно реализовывать в текущей денормализованной модели.

P.S. Во время подготовки поста ни одно дерево не пострадало я пользовался прикольным SQL-валидатором, чтобы чекать, что у меня не совсем дичь в запросах написана (может, кому тоже пригодится): SQL-Validator.

#SystemAnalysis #БазыДанных #Нормализация #SQL #DataModeling #postgresql #erd #системныйанализ
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9👏1
🚨 Не войти не в ту дверь: идентификация, аутентификация, авторизация

📣Пост навеян интересной движухой у нас на работе, а именно — проектированием системы управления доступом, IAM. Не вдаваясь в детали, проектировать будем с самого нуля и я скажу честно, это видится интересной задачей. Ввиду текущей загрузки я ей буду заниматься мало, но буду менеджерить работу по ней и помогать новому коллеге-аналитику. В любом случае будет увлекательно! 🐈

Итак, пару слов о IAM. IAM — Identity and Access Management, управление идентификацией и доступом. Этот термин включает в себя все три компонента: идентификация, аутентификация и авторизация. Чуть детальнее:
Идентификация — процесс распознавания пользователя. Иными словами, необходима для того, чтобы разобраться с вопросом: "Вы кто такой? Я вас не звал..." В контексте ИТ-продуктов: пользователь предоставляет email/номер телефона/логин (классика), публичный ключ (в асимметричных схемах), Client Certificate (для mTLS), whatever, сообщая тем самым системе свой уникальный идентификатор. В результате система понимает, под каким именем вы хотите работать и должна провалидировать в принципе наличие такого идентификатора. Это не даёт доступа, это просто декларация.
Аутентификация — проверка заявленной идентичности. После успешной аутентификации система создаёт для пользователя сессию (хранимую на сервере или в БД) или выдаёт подписанный токен (например, JWT). Механизмы делятся по типу проверяемого фактора:
🔘Что вы знаете (Knowledge): пароль, pin-код;
🔘Что у вас есть (Possession): OATH TOTP (коды из приложений типа Google Authenticator), FIDO2 / WebAuthn (аппаратные ключи — Yubikey), мобильное приложение с push-подтверждением;
🔘Что вы есть (Inherence): Биометрия (отпечаток, лицо).

Авторизация — предоставление прав на выполнение определённых действий или доступ к ресурсам после успешной аутентификации, иными словами — разделение по ролям. В рамках одного и того же ИТ-продукта у кого-то будет годмод (например, у специалиста поддержки), а кому-то можно будет только посмотреть. Реализовать авторизацию можно непосредственно в коде приложения/микросервиса, через API Gateway или на отдельном сервере авторизации. Из современных подходов можно отметить:
🔘RBAC (Role-Based Access Control): Классика. Пользователю назначается роль (ADMIN, EDITOR, VIEWER), а роли привязаны к разрешениям. Реализуется через таблицы в БД или специализированные сервисы.
🔘ABAC (Attribute-Based Access Control): Гибкая модель. Решение принимается на основе атрибутов пользователя, ресурса, действия и контекста.
🔘ACL (Access Control Lists): Простое прикрепление списка разрешений прямо к ресурсу («Кто может читать этот файл»). Это подходит только к очень простым сценариям.

Вообще, у меня был опыт работы над ролевой моделью и авторизацией на прошлом месте работы. Знаете, чем все закончилось? Я уволился и оставил это все в наследство своем другу. 😰 Но это совсем другая история. 🍔

В качестве вывода: разделение процессов IAM — основа для проектирования безопасной, понятной и масштабируемой системы управления доступом.

#SystemAnalysis #безопасность #авторизация #аутентификация #архитектура #системныйанализ #cybersecurity
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91👏1😁1
➡️ Agile vs Waterfall: философия планирования разработки

🤔 Последнее время периодически ловлю себя на том, что где-то в закулисье подсознания у меня происходит переосмысление отношения к гибким методологиям разработки, а именно — к Agile. Так что сегодня будет воскресный пост как раз про этот ваш Agile, а именно про фреймворк Scrum. 🥊 В противоположном углу ринга мы разместим каскадную модель Waterfall и прикинем, с кем из этих двоих мы будем меньше деплоить кринжа на прод сможем эффективнее поставлять ценность заинтересованным сторонам. 🎩

Начнем с Agile и сразу оговоримся — тут, конечно, каждый сам себе что-то напридумывал, сам как-то себе его понимает и в целом, надо сказать, Agile принято называть не столько методологией, сколько системой ценностей и принципов. 🤔 Т.е., тут у нас никакой строгости, тоталитаризма, разве что парочку ритуалов исполнять нужно, а чтобы точно никто ни в чем наверняка не разобрался — вот вам Манифест Agile, там все написано.

Ближе к делу:
🟢Agile (Гибкая методология): Итеративный и инкрементальный подход. Работа разбита на короткие циклы (спринты, итерации). План пересматривается в конце каждого цикла на основе обратной связи и новых данных.
🟢Waterfall (Каскадная модель): Последовательный линейный процесс. Этапы идут строго друг за другом: Сбор требований ➡️ Дизайн ➡️ Разработка ➡️ Тестирование ➡️ Внедрение. План, бюджет и сроки фиксируются в начале.

Закономерный вопрос:
А что, в Agile нет процесса сбора требований, дизайна системы, разработки, тестирования и релиза?

Да нет, все это мы тоже там делаем... Может, мы сначала тестируем, а потом разрабатываем? Ну это ж совсем бред какой-то. 🤪

В чем тогда суть-то?
Весь смысл в единице планирования. В Waterfall единица платнирования — потребность, это Scope-Driven подход, в Agile единица планирования — время (Time-Boxed). В каскадной модели у нас определен scope работ и мы решаем, за сколько времени мы можем это сделать. В гибкой модели в фокусе только время, а точнее — фиксированный отрезок времени, которым мы мерим все. Фиксирована длина спринта (time-box) — 1, 2, 3 недели и мы под это время подстраиваемся, решая, а что полезного мы сможем сделать за условные две недели.

Зафиналим: все эти дейлики, ретро, скрам мастера, стендапы и прочие атрибуты Agile в конечном счете не являются сутью. Все, что действительно важно — это конкретный отрезок времени, в котором команда будет перформить. Это непривычно, что мы не ставим во главу угла глобальный результат, ведь там у нас лишь двухнедельные циклы и надежды на то, что в итоге мы придем к чему-то крутому. Это не лучше и не хуже "водопада", само по себе это не позволит быстрее или качественнее пилить фичи, просто это попытка компенсировать уровень неопределенности при разработке. 🏖

#SystemAnalysis #Agile #Waterfall #УправлениеПроектами #Scrum #BusinessAnalysis
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7💯1
📝Моделируем схему данных: ERD против диаграммы классов

🤔 Как-то так получается, что второй пост подряд у меня получается в виде противопоставления двух подходов (осталось только определить, кто антагонист в этой пьесе). Предлагаю сегодня сравнить ERD (Entity-Relationship Diagram) и UML Class Diagram, ведь они так похоже выглядят. Почему мне кажется это интересным? Да просто при проектировании любого нового сервиса/микросервиса/мини-мили-сюси-пуси-сервиса одним из первых шагов будет определение объектов, которые будут участвовать в движухе, и связях между ними.

Таким образом мы подошли к первому вопросу: что общего между ERD и диаграммой классов?
1⃣Обе диаграммы представляют собой структуру данных;
2⃣Там есть прямоугольнички. 🗓 ...и стрелочки (хотя не совсем уж и стрелочки, а скорее связи). ↔️

Что касается различий, то начать нужно с конечной цели:
➡️ERD фокусируется на данных, которые нужно хранить, и их связях в реляционной модели. Иными словами отвечает на вопрос о том, какие данные мы сохраняем, как они связаны и как обеспечить их целостность.
➡️Class Diagram описывает структуру программы, её логические компоненты и их взаимодействие в рамках парадигмы ООП. Иллюстрирует, как будут организованы наши объекты, что они будут уметь делать и как они будут общаться.

Ну, вроде как и то и то нужно и полезно... Но лично мне кажется, что использовать оба эти инструмента при проектировании избыточно и лично я уделяю особое внимание именно данным и их отражению в БД.

Чуть деталей:
🟢Объекты: в ERD сущность, например, User (таблица с полями id, name). В Class Diagram соответственно класс — User (класс с полями id, name и методами createOrder(), getActiveOrders());
🟢Связь: в ERD User ---< Order (один-ко-многим, FK в orders.user_id), в Class Diagram User ---> Order (ассоциация: пользователь имеет заказы);
🟢Объекты уровня ниже: у ERD есть поля в таблицах (total_amount DECIMAL в таблице orders), в диаграмме классов атрибуты и методы: total_amount: fLoat + метод calculateTotal() в классе Order;
🟢Ах да, а еще в диаграмме классов у нас есть наследование.

И вот этот последний пункт вынуждает меня задаться вопросом, а допустимо ли вообще использовать Class Diagram в проекте, который пишется на Rust? 👩‍💻 Вопрос этот интересен мне по двум причинам:
1⃣В Rust нет ООП и, соответственно, нет наследования;
2⃣На моем текущем проекте используется Rust.

Отвечая на этот вопрос... Да можно, наверное, кто ж запретит? Было бы желание (у меня нет). Вместо классов будут структуры, методы функциями и т.д. Однако, лично я смысла в этом особо не вижу.

В качестве вывода: Удобнее использовать ERD, если ядро проекта — сложная предметная область с множеством связей, а основная задача — проектирование надежной схемы данных. Диаграмма классов, наверное, лучше подойдет для проектирования сложной бизнес-логики со множеством состояний и поведений, где взаимодействие объектов важнее схемы их хранения.

#SystemAnalysis #DataModeling #ERD #UML #Rust #Архитектура #БД #системныйанализ #BusinessAnalysis
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9👎1🔥1👏1
🌚 Не только реляционные, но и NoSQL: как мы используем MongoDB

Вообще, основная БД на проекте у на PostgreSQL 👩‍💻 ("Surprise Motherfucker", кто бы мог догадаться?), однако для пары сервисом у нас также подключена MongoDB 👩‍💻, там у нас всего несколько таблиц коллекций и в частности у нас там хранятся данные по парковкам.

Кратко про отличия:
🟡PostgreSQL (реляционная модель): Данные структурированы, разложены по таблицам со строгой схемой. Связи между таблицами обеспечиваются внешними ключами. Работа строится на языке SQL и операциях JOIN.
🟡MongoDB (NoSQL): Данные хранятся в виде гибких JSON-подобных документов в коллекциях. Схема может быть динамической, нет строгих связей, упор делается на вложение данных и денормализацию (кстати, про нормализацию у меня был пост вот тут, кому интересно).

В чем преимущество хранения данных в MongoDB? Прежде чем отвечать на этот вопрос, хочется уточнить, что определенная модель данных для парковок у нас есть и в Postgre, но конкретно в рамках данного микросервиса, который интегрируется с одним открытым API с данными о парковках, удобнее было сделать Mongo:
1️⃣ Все данные — это фактически просто JSON, практически в том же виде, в каком мы получаем данные по API;
2️⃣ Легкое моделирование иерархических данных: структура типом парковки, адресом и координатами в рамках одного документа. В реляционной БД соответственно потребуется несколько таблиц, которые нужно будет джоинить;
3️⃣ Производительность при чтении. Это пункт, вытекающий из предыдущего. Для получения всех данных о парковке мы делаем один запрос по _id;
4️⃣ Встроенная геопространственная поддержка. Легко работать с GeoJSON (вообще в Postgre тоже можно и это не сложно с помощью расширений, таких как PostGIS, но я все-таки добавлю это в плюс для Монги). В рамках одной фичи я вообще хотел бы тут реализовать определение отношения координаты к обрасти (полигону координат) через 2dsphere для MongoDB, но это пока планы на будущее;
5️⃣ Шардинг из коробки: возможность горизонтального масштабирования за счет шардирования без дополнительных активностей.

Конечно, использовать везде MongoDB не получится и реляционные БД еще долго будут оставаться основным способом хранения данных. Недостатки NoSQL модели (конкретно Монги):
1️⃣ Отсутствие Join. Да-да, я чуть выше указал, что нам не нужно использовать джоины в Монге ввиду некоторых ее преимуществ... Но иногда почти всегда они все-таки нужны, чтобы связывать данные из разных таблиц. Тут же, чтобы связать данные из двух коллекций, нам нужно будет сделать два отдельных запроса;
2️⃣ Избыточность данных. С одной стороны, здорово, что все данные об одной парковке у нас в рамках одной записи, с другой стороны в рамках каждой записи у нас есть, например, информация о категории парковки.
3️⃣ Всякие технические ограничения в виде проблем с консистентностью, ограничением транзакций, неполной поддержкой ACID. Все это делает Монгу недопустимой к использованию во всяких бухгалтерских, финансовых, платежных и других требовательных к транзакционности системах (объединил все в один пункт, чтобы не писать много).

Попробую сделать какой-нибудь вывод: MongoDB отлично подходит для определенных сценариев (Каталоги, Документ-ориентированные данные и т.д.), но важно понимать ее ограничения и правильно оценивать требования проекта.

#SystemAnalysis #БазыДанных #MongoDB #PostgreSQL #NoSQL #Архитектура #BusinessAnalysis #системныйанализ
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥32
This media is not supported in your browser
VIEW IN TELEGRAM
😄 Нет, на самом деле наша последняя рабочая неделя не похожа не этот мемчик сверху. 👆У нас уже вторую неделю, как фриз на деплой: все хотят провести праздники спокойно. 🎁
До 🔠🔠 осталось всего ничего, сил пилить вдумчивые посты совсем не осталось, так что до конца объявляю серию постов на расслабоне. 😴

И раз уж я тут упомянул про фриз на деплой, поделюсь историей из своей практики, когда такое решение не подходило. Истории этой два года и я тогда еще работал в ERP-домене. Я делал очень большую фичу, связанную с контролем платежных бюджетов и проведением платежей. Это все делалось в рамках ERP огромной компании, в которой велись тысячи разных бизнес-процессов для сотен филиалов и дочерних обществ и сама эта фича — большая разработка, фактически система внутри системы. А самая хитрость была в чем? Старт промышленной эксплуатации должен был быть ровно с начала календарного года, чтобы все финансовые процессы (связанные с этой системой) стартовали уже в рамках нее. Сразу уточню: возможность не привязываться к началу года с последующим проведением миграции данных рассматривалась, но было принято решение, что это практически невозможно будет сделать безболезненно. 💭

Короче, стартовали с нового года. Предварительно задеплоили все на прод, я расставил фича-флаги, чтобы все это работало только с первого января (кстати, тут у меня был пост про фича-флаги, кому интересно), а после этого укатил на зимние праздники в женой в ОАЭ на Фуджейру. 💨 С одной стороны, было очень много тестов фичи, проверок и так далее, с другой — огромное количество зависимостей... Короче, покрыть все тестами не получилось, а я, как аналитик, упустил часть контекста системы при разработке (ввиду ее, системы, огромности), что в определенных ситуациях приводило к неправильной работе.

В общем, бизнес начал уже колотить документы в системе, не все идет гладко, а на работе с доступом к системе один дежурный программист, который вообще вне контекста доработки, и ребята из поддержки (спасибо им, они прикрыли мою жопь и нашли много решений в моменте, чтобы продержаться до глобального исправления ❤️). Я на пляжике с телефоном без доступа к логам, отладке, только со скриншотиками пытаюсь придумать, как обойти какие-то баги, продержаться до конца праздников, вернуться и все исправить. Все, конечно, хорошо закончилось, но было стрессово. Улетать из ОАЭ тогда очень не хотелось. 😏

Вывод: лучше не деплоить перед НГ, даже если очень хочется.

#SystemAnalysis #BusinessAnalysis #системныйанализ #личныйопыт #erp #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🙈31