<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Engineer — Platform — Портфоліо та нотатки</title>
    <link>https://platform.engineer.company/uk/</link>
    <description>Engineer ApS — розробка програмного забезпечення та IT-консалтинг у Копенгагені, Данія. Портфоліо підтверджених інженерних досягнень у даних, хмарі та IT.</description>
    <language>uk</language>
    <copyright>Авторське право © 2025 – дотепер · Engineer ApS</copyright>
    <generator>Hugo 0.167.0</generator>
    <docs>https://www.rssboard.org/rss-specification</docs>
    <ttl>60</ttl>
    <lastBuildDate>Fri, 09 Oct 2026 14:31:18 +0200</lastBuildDate>
    <atom:link href="https://platform.engineer.company/uk/index.xml" rel="self" type="application/rss+xml" />
    <image>
      <url>https://platform.engineer.company/assets/icons/apple/apple-touch-icon-144x144.png</url>
      <title>Engineer — Platform — Портфоліо та нотатки</title>
      <link>https://platform.engineer.company/uk/</link>
    </image>
    <item>
      <title>Розробила та запустила перший у компанії дашборд observability, що забезпечував аналітику продуктивності системи в реальному часі та візуалізацію даних на великому офісному телевізорі.</title>
      <link>https://platform.engineer.company/uk/portfolio/developed-and-launched-the-company-s-first-observability-9/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/developed-and-launched-the-company-s-first-observability-9/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Дашборд суттєво підвищив прозорість системи та швидкість реагування на операційні проблеми. Команди отримали змогу виявляти та усувати інциденти на 40% швидше.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Аналітика даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Контейнери (Docker/Kubernetes)</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Аналітика даних та BI‑дашборди</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Компанія стикалася з труднощами в моніторингу продуктивності систем у реальному часі, що часто призводило до затримок у реагуванні на інциденти та зниження видимості стану інфраструктури. Централізованого рішення, яке дозволяло б командам отримувати уявлення про операційні метрики, не існувало.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб розробити рішення, яке дозволило б технічним і нетехнічним зацікавленим сторонам відстежувати ключові системні метрики в реальному часі, з акцентом на доступність, зрозумілість і проактивне виявлення проблем.</p>
<p><strong>Дія.</strong> Було спроєктовано та впроваджено перший дашборд observability компанії, що збирав усі ключові системні метрики — такі як CPU, RAM, HDD, температура тощо — з віддалених серверів Linux через SSH. Навіть контейнери Docker відстежувалися за допомогою цього методу. Пізніше було спроєктовано та впроваджено другу версію з використанням Grafana та Prometheus для розширених можливостей візуалізації й моніторингу. У співпраці з командами DevOps та інженерії було визначено критичні метрики, такі як утилізація CPU, використання пам&rsquo;яті, час безвідмовної роботи сервісів і затримка API. Пайплайни даних було налаштовано для приймання й обробки метрик продуктивності з різних систем, а дашборд розгорнуто на великому телевізорі в офісі для максимальної видимості. Також було впроваджено механізми сповіщень про перевищення порогових значень для забезпечення негайного реагування.</p>
<p><strong>Результат.</strong> Дашборд суттєво підвищив прозорість системи та швидкість реагування на операційні проблеми. Команди отримали змогу виявляти та усувати інциденти на 40% швидше. Це також сформувало культуру спільної відповідальності за стан системи, зробивши дані про продуктивність доступними для всіх в офісі, що зрештою сприяло стабільнішому й ефективнішому продакшн‑середовищу.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Спроєктувала, розгорнула та підтримувала 10 серверів PostgreSQL і MS SQL на Ubuntu Linux VPS, забезпечивши оптимальну продуктивність і надійність серверів.</title>
      <link>https://platform.engineer.company/uk/portfolio/designed-deployed-and-maintained-10-postgresql-and-ms-13/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/designed-deployed-and-maintained-10-postgresql-and-ms-13/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>- Досягнуто 99,9% безвідмовної роботи на всіх 10 серверах баз даних. - Покращено час відповіді запитів на 30% завдяки налаштуванню конфігурації та оптимізації…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Адміністрування баз даних (DBA)</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> На посаді DevOps‑інженера в компанії середнього розміру завдання полягало в тому, щоб керувати інфраструктурою баз даних та оптимізувати її для підтримки зростаючої бази користувачів і критично важливих бізнес‑застосунків. Організація значною мірою покладалася на PostgreSQL та Microsoft SQL Server для зберігання даних та аналітики, що вимагало високої доступності, масштабованості та безпеки.</p>
<p><strong>Завдання.</strong> Основна відповідальність полягала в тому, щоб спроєктувати, розгорнути, налаштувати та підтримувати 10 інстансів PostgreSQL і MS SQL Server на VPS з Ubuntu Linux. Це включало забезпечення оптимальної продуктивності, впровадження надійних протоколів безпеки та налаштування проактивного моніторингу для запобігання простоям. Крім того, завдання включало масштабування інфраструктури для майбутнього зростання з мінімізацією витрат та дотриманням галузевих стандартів.</p>
<p><strong>Дія.</strong> 1. Розгортання та налаштування:</p>
<ul>
<li>Встановлено та налаштовано PostgreSQL 14 і MS SQL Server 2019 на інстансах VPS з Ubuntu 20.04 LTS, з забезпеченням сумісності із застосунками компанії.</li>
<li>Налаштовано автоматичне резервне копіювання за допомогою <code>pg_dump</code> для PostgreSQL і завдань SQL Server Agent для MS SQL, з політиками зберігання та офсайт‑зберіганням.</li>
<li>Оптимізовано конфігурації серверів (наприклад, розподіл пам&rsquo;яті, кешування запитів та пулінг з&rsquo;єднань) для покращення продуктивності запитів та зниження затримок.</li>
</ul>
<ol start="2">
<li>
<p>Моніторинг та обслуговування:</p>
<ul>
<li>Впроваджено інструменти моніторингу, такі як Prometheus, Grafana, для відстеження CPU, пам&rsquo;яті, дискового вводу‑виводу та метрик продуктивності запитів у режимі реального часу.</li>
<li>Проведено регулярне патчування та оновлення як баз даних, так і ОС Ubuntu для усунення вразливостей безпеки та забезпечення відповідності стандартам.</li>
<li>Створено власні скрипти для аналізу логів.</li>
</ul>
</li>
<li>
<p>Безпека та масштабованість:</p>
<ul>
<li>Налаштовано фаєрволи (UFW), впроваджено рольове керування доступом (RBAC) для захисту чутливих даних.</li>
<li>Задокументовано процедури аварійного відновлення, включно з відновленням на конкретний момент часу та протоколами failover.</li>
</ul>
</li>
</ol>
<p><strong>Результат.</strong> - Досягнуто 99,9% безвідмовної роботи на всіх 10 серверах баз даних.</p>
<ul>
<li>Покращено час відповіді запитів на 30% завдяки налаштуванню конфігурації та оптимізації індексів, що підвищило продуктивність застосунків.</li>
<li>Скорочено ручні завдання з обслуговування на 50% за рахунок автоматизації, вивільнивши понад 10 годин на місяць для стратегічних проєктів.</li>
<li>Успішно масштабовано інфраструктуру для підтримки зростання трафіку користувачів на 40% без погіршення якості обслуговування, що сприяло зростанню доходу на 20% у наступному кварталі.</li>
<li>Отримано визнання від CTO за впровадження найкращих практик безпеки, які запобігли потенційним витокам даних.</li>
</ul>
<p>Цей досвід закріпив глибоку експертизу в управлінні базами даних, DevOps‑автоматизації та оптимізації інфраструктури, забезпечуючи надійні, безпечні та масштабовані рішення для складних корпоративних середовищ.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Посилила безпеку даних, впровадивши 1 000 правил RBAC для розробників, екземплярів застосунків, PostgreSQL, MS SQL та інших Linux‑серверів, запобігши несанкціонованому доступу; задокументувала за допомогою автоматизації Ansible.</title>
      <link>https://platform.engineer.company/uk/portfolio/enhanced-data-security-by-implementing-1-000-rbac-14/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/enhanced-data-security-by-implementing-1-000-rbac-14/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Впровадження забезпечило понад 1 000 правил без внесення зайвої складності, скоротивши ризики несанкціонованого доступу на 85%.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Адміністрування баз даних (DBA)</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Організації потрібно було посилити контроль доступу в кількох системах, включно з середовищами розробників, інстансами застосунків, PostgreSQL, MS SQL та Linux‑серверами. Хоча базова модель RBAC була простою, складність полягала в керуванні понад 1 000 окремих правил для різних ролей користувачів та системних вимог. Метою було забезпечити суворі обмеження доступу без внесення зайвої складності.</p>
<p><strong>Завдання.</strong> Впровадити масштабоване рішення RBAC шляхом визначення та застосування понад 1 000 правил контролю доступу. Це передбачало відображення дозволів на конкретні ролі (наприклад, розробники, інстанси застосунків, адміністратори баз даних) та забезпечення послідовного застосування правил у всіх системах. Завдання також вимагало документування правил та автоматизації їхнього розгортання для уникнення ручних помилок.</p>
<p><strong>Дія.</strong> Підхід був зосереджений на створенні простої, модульної структури RBAC, розбиваючи дозволи на чіткі, повторно використовувані категорії (наприклад, «доступ лише для читання до продакшн‑баз даних»). За допомогою Ansible налаштування кожного правила було автоматизовано, що забезпечило узгодженість у всіх середовищах. Наприклад, розробники отримували доступ лише до призначених їм серверів, тоді як інстанси застосунків мали обмежені дозволи для запобігання латеральному переміщенню. Процес пріоритизував ясність над складністю: кожне правило було явно прив&rsquo;язане до конкретної ролі та системи.</p>
<p><strong>Результат.</strong> Впровадження забезпечило понад 1 000 правил без внесення зайвої складності, скоротивши ризики несанкціонованого доступу на 85%. Автоматизація спростила розгортання, скоротивши час налаштування на 60% порівняно з ручними методами. Задокументована структура дала змогу командам швидко перевіряти або змінювати правила, забезпечуючи масштабованість у міру зростання інфраструктури. Завдяки фокусу на простоті та обсязі рішення забезпечило надійну безпеку при збереженні операційної ефективності.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала розгортання GIS SaaS‑застосунку, обробку даних та систему звітності за допомогою GitHub Actions CI/CD, Python, Bash та SQL.</title>
      <link>https://platform.engineer.company/uk/portfolio/automated-gis-saas-application-deployment-data-processing-and-16/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/automated-gis-saas-application-deployment-data-processing-and-16/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Розгортання, обробка даних та звітність стали автоматизованими й надійними, ручна рутина зникла з плеча команди, а цикл релізів скоротився.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">GIS / геопростір</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">SQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інженерія даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Пайплайни даних (ETL/ELT)</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">GIS та геопросторові рішення</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка пайплайнів даних (ETL/ELT)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Розгортання GIS SaaS‑застосунку, обробка його даних та формування звітів були повністю ручними кроками — а ручні кроки одночасно й повільні, і тихо небезпечні. Кожен реліз забирав час інженерів і ніс ризик помилки, а повторювана робота з даними та звітністю сиділа там, з&rsquo;їдаючи потужність тиждень за тижнем.</p>
<p><strong>Завдання.</strong> Завданням була автоматизація всього шляху від коду до продакшну, а також повторюваної обробки даних і звітності — з метою отримати релізи, які були б швидкими, безпечними та відтворюваними, а не ретельним ручним ритуалом щоразу.</p>
<p><strong>Дія.</strong> Весь шлях було автоматизовано. Пайплайни GitHub Actions взяли на себе цикл test‑build‑deploy, тож реліз перестав залежати від того, чи хтось пам&rsquo;ятає всі кроки. Повторювана обробка даних та звіти перейшли в заплановані завдання на Python, Bash та SQL, тож вони просто виконувалися, а не були чиєюсь рутинною роботою. А конфігурація та секрети були стандартизовані так, щоб кожне середовище поводилося однаково — саме це усуває несподіванки на кшталт «у мене на машині працює», бо не залишається «моєї машини», яка відрізняється від продакшну.</p>
<p><strong>Результат.</strong> Розгортання, обробка даних та звітність стали автоматизованими й надійними, ручна рутина зникла з плеча команди, а цикл релізів скоротився. Команда змогла зосередити увагу на продукті, а не на операціях, що його оточували.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала постачання 20 пайплайнів GIS‑даних та ETL‑процесів даних застосунку, оптимізувавши автоматизацію інфраструктури та звітність.</title>
      <link>https://platform.engineer.company/uk/portfolio/automated-delivery-of-20-gis-data-pipelines-and-17/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/automated-delivery-of-20-gis-data-pipelines-and-17/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Усі двадцять пайплайнів та їхній ETL працювали автоматично й передбачувано, а вся картина автоматизації інфраструктури та звітності стала охайнішою.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">GIS / геопростір</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інженерія даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Пайплайни даних (ETL/ELT)</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">GIS та геопросторові рішення</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка пайплайнів даних (ETL/ELT)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформа працювала на великій кількості GIS‑пайплайнів даних та ETL‑процесів для даних застосунку, які постачалися й контролювалися вручну. Ручні пайплайни створюють вузькі місця, вони втрачають узгодженість, і найгірше — вони несуть постійний невеликий ризик того, що один із них тихо відмовить, і ніхто цього не помітить, доки дані далі за потоком уже не стануть неправильними.</p>
<p><strong>Завдання.</strong> Завданням була автоматизація постачання цих пайплайнів та ETL‑процесів — щоб дані надходили надійно та передбачувано без того, щоб хтось їх супроводжував.</p>
<p><strong>Дія.</strong> Двадцять GIS‑пайплайнів даних та ETL для даних застосунку перейшли на автоматизоване постачання, від початку до кінця. Планування, логування та обробку відмов було стандартизовано, тож кожен пайплайн поводився однаково і, що важливо, було видно, коли якийсь із них поводився інакше — тиха відмова залишається тихою, лише якщо ніхто не стежить. І їх було вбудовано в наявну автоматизацію інфраструктури та звітність, тож вони стали частиною однієї узгодженої системи, а не шухляди зі скриптами, які хтось мусив пам&rsquo;ятати запустити.</p>
<p><strong>Результат.</strong> Усі двадцять пайплайнів та їхній ETL працювали автоматично й передбачувано, а вся картина автоматизації інфраструктури та звітності стала охайнішою. Бізнес отримав надійні, актуальні дані без того, щоб хтось проводив їх вручну — і без ризику тихої відмови, що висів над цим.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала 100 критично важливих резервних копій даних за допомогою Barman, Google Cloud, Bash та Python, забезпечивши цілісність даних у базах даних.</title>
      <link>https://platform.engineer.company/uk/portfolio/automated-100-critical-data-backups-using-barman-google-18/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/automated-100-critical-data-backups-using-barman-google-18/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Резервне копіювання виконувалося автоматично й підлягало перевірці для кожної бази даних, що перетворило відновлюваність даних із припущення на щось…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Адміністрування баз даних (DBA)</category>
      <category domain="https://platform.engineer.company/uk/services/">Резервне копіювання та відновлення</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Критичні GIS‑дані, інстанси застосунків та бази даних були розкидані по системах з резервним копіюванням, яке було непослідовним і частково ручним. Для продукту, що живе своїми даними, це не той ризик, який можна залишити без уваги — і день, коли резервна копія справді знадобиться, це саме той день, найгірший для того, щоб дізнатися, що вона неповна.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб гарантувати можливість відновлення всіх критичних даних, що означало автоматизацію всебічного, перевіреного резервного копіювання в усьому господарстві — де саме слово «перевіреного» й мало значення.</p>
<p><strong>Дія.</strong> Режим резервного копіювання було побудовано від початку до кінця. Сто критичних резервних копій даних було автоматизовано, з Barman на стороні PostgreSQL та Google Cloud для офсайт‑копій, а весь процес було оркестровано й перевірено за допомогою Bash та Python — бо резервна копія, яку зроблено, але ніколи не перевірено, це не насправді резервна копія, а лише сподівання. Тож були впроваджені політики зберігання, щоб тримати їх актуальними, та перевірки цілісності, щоб підтвердити, що кожна з них справді хороша, а не просто присутня.</p>
<p><strong>Результат.</strong> Резервне копіювання виконувалося автоматично й підлягало перевірці для кожної бази даних, що перетворило відновлюваність даних із припущення на щось перевірене. Значний операційний ризик було знято з бізнесу та замінено шляхом відновлення, якому справді можна довіряти — різниця в тому, що цей шлях був перевірений, а не лише налаштований.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Розгорнула та підтримувала 20 контейнеризованих застосунків Docker, усуваючи несправності за допомогою Podman і Kubernetes, а також керувала застосунками на R у Google Cloud та AWS.</title>
      <link>https://platform.engineer.company/uk/portfolio/deployed-and-maintained-20-docker-containerized-applications-troubleshooting-19/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/deployed-and-maintained-20-docker-containerized-applications-troubleshooting-19/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Контейнеризоване господарство надійно працювало в обох хмарах, проблеми діагностувалися швидше, а розгортання залишалися стабільними й відтворюваними.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Аналітика даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Контейнери (Docker/Kubernetes)</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Контейнеризація та оркестрація</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Існував зростаючий набір контейнеризованих застосунків — включно з деякими аналітичними застосунками на R — що працювали як на Google Cloud, так і на AWS. Розподілені між двома хмарами й кількома середовищами виконання контейнерів, вони мали розгортатися послідовно та швидко діагностуватися у разі проблем, що складніше, ніж звучить, коли жодні два середовища не є цілком однаковими.</p>
<p><strong>Завдання.</strong> Роботою було надійне розгортання та підтримка цих навантажень, а також здатність швидко діагностувати проблеми в різних середовищах виконання та хмарах.</p>
<p><strong>Дія.</strong> Контейнеризоване господарство керувалося в обох хмарах — двадцять Docker‑застосунків розгорнуто й підтримувано з узгодженою конфігурацією та моніторингом, тож жоден з них не був власною сніжинкою. Коли щось йшло не так, усунення несправностей відбувалося через Podman, а налагодження оркестрації — через Kubernetes. Аналітичні застосунки на R отримали окрему увагу в продакшн‑середовищах Google Cloud та AWS, залишаючись стабільними й відтворюваними, що для аналітики важливо — результат, який не можна відтворити, це не дуже й результат.</p>
<p><strong>Результат.</strong> Контейнеризоване господарство надійно працювало в обох хмарах, проблеми діагностувалися швидше, а розгортання залишалися стабільними й відтворюваними. Застосунки, на які спирався продукт, залишалися надійними незалежно від того, в якій хмарі вони на той момент працювали.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Керувала 30 екземплярами Ubuntu Linux VPS, впровадивши стратегії аварійного відновлення та забезпечивши оптимальні конфігурації мережі.</title>
      <link>https://platform.engineer.company/uk/portfolio/managed-30-ubuntu-linux-vps-instances-implementing-disaster-20/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/managed-30-ubuntu-linux-vps-instances-implementing-disaster-20/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Інфраструктура стала стійкою й послідовною, з шляхами відновлення, які були перевірені, та мережею, на яку можна покластися.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Резервне копіювання та відновлення</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Компанія працювала на флоті інстансів VPS з Ubuntu Linux, чиє налаштування органічно розросталося з часом — що є ввічливим способом сказати, що воно радше накопичувалося, ніж проєктувалося. Це залишило прогалини: непослідовні конфігурації та механізми відновлення й мережі, які були радше історичною випадковістю, ніж планом.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб взяти флот під належне управління, посилити сторону аварійного відновлення та зробити мережеву конфігурацію послідовною й розумною для кожного інстансу.</p>
<p><strong>Дія.</strong> Тридцять інстансів перейшли під свідоме управління — до них ставилися як до одного узгодженого флоту, а не тридцяти окремих «домашніх улюбленців». Було впроваджено справжнє аварійне відновлення: резервні копії та процедури відновлення, які справді перевірялися, бо неперевірене відновлення — це лише теорія. А мережеву конфігурацію було стандартизовано для безпеки й продуктивності, тож кожен інстанс дотримувався того самого захищеного базового рівня замість того, з чим випадково опинявся.</p>
<p><strong>Результат.</strong> Інфраструктура стала стійкою й послідовною, з шляхами відновлення, які були перевірені, та мережею, на яку можна покластися. Ризик простою знизився, і бізнес отримав надійну основу для зростання замість клаптикового рішення, яке доводилося постійно доглядати.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Запобігла порушенням безпеки, очоливши ініціативи з керування доступом, використовуючи M365, 1Password, Red Hat SSO та OKTA SSO.</title>
      <link>https://platform.engineer.company/uk/portfolio/prevented-security-breaches-by-leading-access-management-initiatives-21/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/prevented-security-breaches-by-leading-access-management-initiatives-21/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Ризик несанкціонованого доступу різко знизився, а доступ став підданим аудиту й послідовним — нарешті можна було відповісти на запитання «хто має доступ до…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Доступ до систем і сервісів в усій компанії керувався непослідовно — дозволи надавалися ситуативно, з часом, різними людьми. Це подвійна проблема: вона відкриває двері до доступу, якого ніхто не планував, і робить аудит майже неможливим, бо ніхто насправді не може сказати, хто до чого має доступ і чому.</p>
<p><strong>Завдання.</strong> Метою було закрити цю вразливість безпеки шляхом централізації та посилення керування доступом у всій організації.</p>
<p><strong>Дія.</strong> Перегляд консолідував ідентифікаційні дані та доступ у M365, 1Password, Red Hat SSO та OKTA SSO, тож замість розрізнених дозволів по системах з&rsquo;явилася узгоджена картина. Було впроваджено принцип найменших привілеїв — люди й системи мали рівно те, що їм потрібно, і нічого зайвого — а онбординг і офбординг стандартизовано, тож доступ надавався і, що не менш важливо, вчасно й послідовно відкликався, а не залишався після того, як хтось пішов далі.</p>
<p><strong>Результат.</strong> Ризик несанкціонованого доступу різко знизився, а доступ став підданим аудиту й послідовним — нарешті можна було відповісти на запитання «хто має доступ до цього і чому». Дивна деталь у тому, що це також спростило повсякденне життя команди: потрібні двері відкривалися легко, а непотрібні залишалися зачиненими, а саме так і відчувається добре керування доступом.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Знизила операційні ризики, впровадивши дашборд моніторингу на базі Grafana та Prometheus, підвищивши надійність системи.</title>
      <link>https://platform.engineer.company/uk/portfolio/mitigated-operational-risks-by-implementing-a-monitoring-dashboard-22/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/mitigated-operational-risks-by-implementing-a-monitoring-dashboard-22/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Проблеми почали фіксуватися й вирішуватися до того, як вони ескалювалися, і надійність системи від цього покращилася.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Проблеми зазвичай помічали вже після того, як вони зачіпали користувачів, бо не існувало єдиного огляду того, як почуваються системи. Без цієї видимості команда постійно була в програшній позиції — реагуючи на те, що вже пішло не так, замість того, щоб бачити це заздалегідь.</p>
<p><strong>Завдання.</strong> Метою було знизити операційний ризик, надавши команді видимість у реальному часі щодо систем, від яких вона залежала.</p>
<p><strong>Дія.</strong> Було вибудовано шар observability. Дашборд моніторингу на Grafana та Prometheus, ключові сервіси інструментовано, і — та частина, яка справді має значення — метрики, які щось означали, а не показні числа, що виглядають зайнятими й нічого не повідомляють. Далі — порогові значення сповіщень, налаштовані на цих метриках, показані там, де команда справді їх бачила б і могла діяти, поки на дії ще був час.</p>
<p><strong>Результат.</strong> Проблеми почали фіксуватися й вирішуватися до того, як вони ескалювалися, і надійність системи від цього покращилася. Команда перейшла від реактивного гасіння пожеж до чогось спокійнішого й проактивнішого — виловлюючи проблеми, поки ті ще були достатньо дрібними, щоб бути нудними.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Керувала та усувала несправності 8 з&#39;єднань WireGuard VPN та IPSEC VPN, забезпечивши безпечний зв&#39;язок між системами Google Cloud та Linux.</title>
      <link>https://platform.engineer.company/uk/portfolio/managed-and-troubleshooted-8-wireguard-vpn-and-ipsec-23/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/managed-and-troubleshooted-8-wireguard-vpn-and-ipsec-23/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Усі вісім тунелів працювали безпечно й надійно, зв&#39;язок між середовищами залишався захищеним, а повторювані інциденти зі з&#39;єднанням, що раніше переривали…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Захищене з&rsquo;єднання між хмарою та локальними Linux‑системами проходило через кілька VPN‑тунелів, які були крихкими й незручними для діагностики у разі падіння. Мертвий тунель міг обірвати зв&rsquo;язок між середовищами, а усунення несправностей одного з них було повільним і невизначеним — ніколи не було повної впевненості, що справжню причину знайдено.</p>
<p><strong>Завдання.</strong> Роботою було керування та усунення несправностей цих з&rsquo;єднань для гарантування безпечного й безперебійного зв&rsquo;язку.</p>
<p><strong>Дія.</strong> VPN‑господарство взяли під контроль — вісім тунелів WireGuard та IPSec між Google Cloud та Linux‑системами, якими керували й для яких усували несправності як для єдиного набору, а не восьми окремих загадок. Їхню конфігурацію стандартизували, тож вони стали послідовними й зрозумілими замість того, щоб кожен був власним особливим випадком, а їхній стан моніторили, вирішуючи повторювані проблеми з маршрутизацією та обміном ключами в корені, а не заклеюючи їх перезапуском.</p>
<p><strong>Результат.</strong> Усі вісім тунелів працювали безпечно й надійно, зв&rsquo;язок між середовищами залишався захищеним, а повторювані інциденти зі з&rsquo;єднанням, що раніше переривали роботу, припинилися. Саме усунення першопричин, а не догляд за симптомами, перетворило їх з повторюваного головного болю на щось, що просто працювало.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Покращила комунікацію та співпрацю в команді, впровадивши Slack, Mattermost, 1Password та Jira, заощадивши 8 000 людино‑годин.</title>
      <link>https://platform.engineer.company/uk/portfolio/improved-team-communication-and-collaboration-by-implementing-slack-34/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/improved-team-communication-and-collaboration-by-implementing-slack-34/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Комунікація та співпраця помітно покращилися, а впорядкована система заощадила приблизно 8 000 годин праці — час, який раніше йшов на пошук інформації та…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Agile та Scrum</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Керівництво командою</category>
      <category domain="https://platform.engineer.company/uk/categories/">Управління проєктами</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Управління проєктами (Agile)</category>
      <category domain="https://platform.engineer.company/uk/services/">Формування команди та менторство</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> У міру зростання команди комунікація та інструменти не встигали за нею, і це було помітно. Щось говорилося в одному місці й губилося для людей, яким це було потрібно, робота дублювалася, бо ніхто не бачив, що вже зробив хтось інший, а координація будь‑чого займала більше часу, ніж сама робота. Такий тип тертя непомітний день у день, але з часом складається у велику втрату часу.</p>
<p><strong>Завдання.</strong> Мета полягала в тому, щоб виправити спосіб, у який команда спілкувалася та працювала разом, і повернути час, який непомітно втрачався через це тертя.</p>
<p><strong>Дія.</strong> Інструменти було впроваджено та стандартизовано, і — це та частина, яка справді має значення, — було встановлено практики їх використання, щоб вони не перетворилися просто на ще одне місце, яке треба перевіряти. Slack і Mattermost для комунікації, 1Password, щоб спільні секрети не передавалися способами, які ніхто не міг відстежити, Jira, щоб робота відстежувалася в одному місці, а не жила в головах і поштових скриньках людей. Інструменти були простою частиною; змусити всіх дійсно використовувати їх однаково — це і була справжня робота.</p>
<p><strong>Результат.</strong> Комунікація та співпраця помітно покращилися, а впорядкована система заощадила приблизно 8 000 годин праці — час, який раніше йшов на пошук інформації та переробку роботи, тепер спрямовувався на реальне постачання.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Реорганізувала внутрішні процеси, заощадивши 8 000 годин завдяки вдосконаленню архітектури програмного забезпечення, систем та ефективності планування.</title>
      <link>https://platform.engineer.company/uk/portfolio/overhauled-internal-processes-saving-8-000-hours-by-38/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/overhauled-internal-processes-saving-8-000-hours-by-38/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Переробка зекономила приблизно 8 000 годин завдяки суттєвому підвищенню ефективності архітектури, систем і планування.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/categories/">Управління проєктами</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <category domain="https://platform.engineer.company/uk/services/">Управління проєктами (Agile)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> У внутрішніх процесах накопичилися типові нашарування — архітектура програмного забезпечення, що розросталася стихійно, а не за задумом, системи, які працювали, але неефективно, і планування, через яке люди то простоювали, то були перевантажені. Нічого з цього не «горіло», саме тому це й залишали без змін, але тихо це коштувало багато часу.</p>
<p><strong>Завдання.</strong> Метою було докорінно переглянути ці процеси — знайти витрати й усунути їх, а не продовжувати за них платити.</p>
<p><strong>Дія.</strong> Внутрішні процеси було перероблено за трьома напрямами: архітектуру програмного забезпечення — так, щоб її можна було логічно осмислювати й розвивати, а не обходити; системи — оптимізовано так, щоб рутинна робота більше не займала більше часу, ніж потрібно; і планування — так, щоб потужності справді відповідали обсягу роботи. Зміни закріпили так, щоб вони прижилися, — вбудували в те, як працює команда, а не залишили у вигляді меморандуму, який усі кивнули й забули, — адже покращення процесів, які не закріплюються, просто відкочуються назад до старого способу роботи.</p>
<p><strong>Результат.</strong> Переробка зекономила приблизно 8 000 годин завдяки суттєвому підвищенню ефективності архітектури, систем і планування. Це потужності, які пішли безпосередньо на роботу з вищою цінністю, а не на накладні витрати, які раніше ніхто навіть не ставив під сумнів.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Адмініструвала мережеву інфраструктуру для понад 1 000 серверів, забезпечивши оптимальне розгортання систем, безпеку та усунення несправностей.</title>
      <link>https://platform.engineer.company/uk/portfolio/administered-network-infrastructure-for-over-1-000-servers-39/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/administered-network-infrastructure-for-over-1-000-servers-39/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Парк серверів працював із надійним розгортанням, надійною безпекою та проблемами, які вирішувалися оперативно, а не накопичувалися.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Операційна діяльність компанії трималася на великому парку серверів — понад тисяча одиниць, — а парк такого масштабу сам собою надійним не залишається. Розгортання, безпека та постійний потік того, що йде не так, потребують справжньої дисципліни в управлінні, інакше все стає нестабільним, і ніхто до кінця не розуміє чому.</p>
<p><strong>Завдання.</strong> Завданням було адмініструвати цю мережеву інфраструктуру — забезпечувати її безпеку, надійність і узгодженість у масштабі, де саме неузгодженість здатна все зіпсувати.</p>
<p><strong>Дія.</strong> Мережева інфраструктура працювала на понад тисячі серверів. Розгортання систем було стандартизовано, тож кожен сервер піднімався одним і тим самим передбачуваним способом, а не був трохи «індивідуальним»; безпеку посилили, а не покладалися на те, що ніхто не почне шукати вразливості; а усунення несправностей відбувалося щоразу, коли щось справді ламалося. У такому масштабі саме стандартизація рятує ситуацію — тисяча унікальних конфігурацій не піддається керуванню, а тисяча однакових — це просто робота.</p>
<p><strong>Результат.</strong> Парк серверів працював із надійним розгортанням, надійною безпекою та проблемами, які вирішувалися оперативно, а не накопичувалися. Це саме той тип інфраструктурної роботи, який непомітний, коли все йде добре, — і в цьому суть: вона була стабільним кістяком, на якому трималося все інше в компанії.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала створення сертифікатів SSL/TLS для 100 застосунків Docker, забезпечивши безпечні з&#39;єднання на хостах Ubuntu Linux.</title>
      <link>https://platform.engineer.company/uk/portfolio/automated-ssl-tls-certificate-creation-for-100-docker-41/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/automated-ssl-tls-certificate-creation-for-100-docker-41/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Усі сто застосунків самостійно підтримували дійсні сертифікати та захищені з&#39;єднання. Ручна робота із сертифікатами просто зникла, а разом із нею — і ціла…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Контейнери (Docker/Kubernetes)</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Контейнеризація та оркестрація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Сто застосунків на Docker потребували сертифікатів SSL/TLS, а сертифікати — це саме те, що працює нормально, доки раптом не перестає. Видавати й поновлювати сто сертифікатів вручну — повільно, нудно, і це якраз той тип ручної роботи, де одне забуте поновлення виводить застосунок з ладу через помилку простроченого сертифіката в найгірший можливий момент.</p>
<p><strong>Завдання.</strong> Метою було автоматизувати створення й поновлення сертифікатів — щоб кожен застосунок мав дійсне, довірене шифрування, і нікому не доводилося пам&rsquo;ятати про це.</p>
<p><strong>Дія.</strong> Робочий процес на основі ACME обробляв увесь життєвий цикл сертифікатів для ста застосунків на Docker — створював сертифікати й поновлював їх до завершення терміну дії — і автоматично розгортав їх на хостах Ubuntu Linux, де працювала суміш Apache та Nginx. Уся мета полягала в тому, щоб виключити людину з цього процесу, адже саме людина — та ланка, яка забуває.</p>
<p><strong>Результат.</strong> Усі сто застосунків самостійно підтримували дійсні сертифікати та захищені з&rsquo;єднання. Ручна робота із сертифікатами просто зникла, а разом із нею — і ціла категорія збоїв, коли щось ламається не через відмову, а через те, що сертифікат непомітно прострочився, і ніхто цього не помітив.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Оптимізувала процеси CI/CD, заощадивши 4 000 годин завдяки впровадженню автоматизації в пайплайнах розробки програмного забезпечення.</title>
      <link>https://platform.engineer.company/uk/portfolio/streamlined-ci-cd-processes-saving-4-000-hours-42/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/streamlined-ci-cd-processes-saving-4-000-hours-42/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Автоматизація повернула приблизно 4 000 годин і зробила релізи швидшими та надійнішими водночас. Команда могла випускати реліз без внутрішнього напруження —…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Випуск програмного забезпечення залежав від ручних, неузгоджених кроків — комусь доводилося пам&rsquo;ятати послідовність дій і щоразу виконувати їх трохи по‑різному, — і це сповільнювало релізи та з&rsquo;їдало інженерні години, які мали б витрачатися на розробку.</p>
<p><strong>Завдання.</strong> Метою було оптимізувати процес CI/CD і впровадити автоматизацію в пайплайни, щоб релізи перестали бути ручним ритуалом.</p>
<p><strong>Дія.</strong> Було впроваджено автоматизовані пайплайни збирання, тестування та розгортання, тож шлях від зміни до її роботи у production став стандартизованим, а не імпровізованим. Повторювані ручні кроки — повільні й, що гірше, виконувані по‑різному залежно від того, хто їх робив, — прибрали. Коли пайплайн щоразу робить це однаково, ціла категорія проблем на кшталт «на моїй машині працювало» та напівзабутих кроків розгортання просто зникає.</p>
<p><strong>Результат.</strong> Автоматизація повернула приблизно 4 000 годин і зробила релізи швидшими та надійнішими водночас. Команда могла випускати реліз без внутрішнього напруження — впевненість була наслідком узгодженості процесу, а не того, що всі діяли обережно.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Оптимізувала процеси аналізу даних та розробки програмного забезпечення, заощадивши 4 000 годин завдяки впровадженню практик CI/CD на базі GitHub, GitLab, Bash та Python.</title>
      <link>https://platform.engineer.company/uk/portfolio/streamlined-data-analysis-and-software-development-processes-saving-43/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/streamlined-data-analysis-and-software-development-processes-saving-43/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Оптимізовані процеси заощадили приблизно 4 000 годин і пришвидшили як аналіз даних, так і розробку програмного забезпечення, а також, що не менш корисно,…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Аналітика даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інженерія даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Пайплайни даних (ETL/ELT)</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Аналітика даних та BI‑дашборди</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка пайплайнів даних (ETL/ELT)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> І роботу з аналізу даних, і розробку програмного забезпечення стримувало одне й те саме: ручні процеси. Робота рухалася від розробки до постачання повільно й неузгоджено, а на боці аналізу накопичилася власна купа повторюваних кроків, які щоразу доводилося виконувати вручну.</p>
<p><strong>Завдання.</strong> Метою було оптимізувати обидва напрями, впровадивши сучасну автоматизацію та практики CI/CD у робочі процеси, які їх раніше не мали.</p>
<p><strong>Дія.</strong> Було впроваджено практики CI/CD на основі GitHub та GitLab, а автоматизацію в основі забезпечували Bash і Python. Повторювані кроки в робочих процесах аналізу даних і розробки автоматизували, а те, як робота рухалася від розробки до постачання, стандартизували, щоб вона щоразу відбувалася однаково, а не вигадувалася заново для кожного проєкту. Значною частиною цього стало включення аналітичного напряму в той самий дисциплінований пайплайн, що й розробка, — раніше його розглядали як окремий, більш ручний світ.</p>
<p><strong>Результат.</strong> Оптимізовані процеси заощадили приблизно 4 000 годин і пришвидшили як аналіз даних, так і розробку програмного забезпечення, а також, що не менш корисно, зробили результати постачання більш узгодженими — менше несподіванок від роботи, яку щоразу виконували трохи по‑різному.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала завдання обробки даних за допомогою Shell scripting, PL/pgSQL, Python та Transact‑SQL, підвищивши продуктивність і ефективність.</title>
      <link>https://platform.engineer.company/uk/portfolio/automated-data-processing-tasks-using-shell-scripting-pl-45/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/automated-data-processing-tasks-using-shell-scripting-pl-45/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Продуктивність та ефективність зросли, ручне навантаження зникло з плечей людей, а обробка даних стала узгодженою й надійною замість того, щоб бути джерелом…</description>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">SQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інженерія даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Пайплайни даних (ETL/ELT)</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Адміністрування баз даних (DBA)</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка пайплайнів даних (ETL/ELT)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Існувало стабільне навантаження повторюваної роботи з обробки даних, яку виконували вручну. Ручна робота з даними має одразу дві проблеми: вона з&rsquo;їдає час і вона неузгоджена — виконуй одну й ту саму задачу вручну достатньо разів, і щоразу вона робитиметься трохи по‑різному, а деякі з цих відмінностей — це помилки.</p>
<p><strong>Завдання.</strong> Метою було автоматизувати ці задачі, щоб і повернути час, і зробити їх надійними.</p>
<p><strong>Дія.</strong> Обробку даних автоматизували в усіх базах даних і системах, яких вона стосувалася, використовуючи те, що підходило під конкретне завдання, — Shell‑скрипти для «клею» між компонентами, PL/pgSQL і Transact‑SQL на рівні баз даних, Python там, де потрібно було більше, ніж міг дати SQL. Ручні кроки замінили завданнями, які щоразу виконувалися однаково, а в цьому й уся суть: скрипт не втомлюється, не пропускає крок і не робить усе по‑іншому у п&rsquo;ятницю під кінець дня.</p>
<p><strong>Результат.</strong> Продуктивність та ефективність зросли, ручне навантаження зникло з плечей людей, а обробка даних стала узгодженою й надійною замість того, щоб бути джерелом дрібних повторюваних помилок.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Налаштувала та розгорнула 1 000 Wi‑Fi‑роутерів, покращивши доступність і продуктивність мережі для клієнтів.</title>
      <link>https://platform.engineer.company/uk/portfolio/configured-and-deployed-1-000-wi-fi-routers-48/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/configured-and-deployed-1-000-wi-fi-routers-48/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Тисяча роутерів забезпечила клієнтам надійний бездротовий зв&#39;язок — кращий доступ, кращу продуктивність — і робила це послідовно, оскільки налаштування були…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">IT‑підтримка та helpdesk</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Клієнтам потрібен був бездротовий зв&rsquo;язок, який просто працює, а це зводилося до налаштування й розгортання великої кількості Wi‑Fi‑роутерів — і робити це щоразу однаково ретельно, адже недбало налаштований роутер буде або небезпечним, або повільним, а яким саме — зазвичай з&rsquo;ясовується вже потім.</p>
<p><strong>Завдання.</strong> Завданням було налаштувати й розгорнути ці роутери, щоб забезпечити клієнтам кращий доступ до мережі та продуктивність.</p>
<p><strong>Дія.</strong> Було налаштовано й розгорнуто тисячу Wi‑Fi‑роутерів. Хитрість за такої кількості полягає в стандартизації налаштувань — узгодженій, безпечній, продуманій конфігурації, — а не в підборі кожного роутера окремо з нуля в день установлення, адже тисяча «ручних» роутерів — це тисяча різних систем, які потім треба підтримувати. Тож щоразу їх налаштовували на безпеку й продуктивність однаковим способом і надійно розгортали на об&rsquo;єктах клієнтів.</p>
<p><strong>Результат.</strong> Тисяча роутерів забезпечила клієнтам надійний бездротовий зв&rsquo;язок — кращий доступ, кращу продуктивність — і робила це послідовно, оскільки налаштування були стандартними, а не імпровізованими. Мета — роутер, про який більше нікому не потрібно думати; більшість із них цього досягли.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Адмініструвала 100 серверів Bare Bone, фізичні мережі та системи IP‑телефонії, забезпечивши надійну інфраструктуру для зростання компанії.</title>
      <link>https://platform.engineer.company/uk/portfolio/administered-100-bare-bone-servers-physical-networks-and-50/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/administered-100-bare-bone-servers-physical-networks-and-50/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Сервери, мережі та телефонія працювали надійно, і саме цей стабільний фізичний фундамент дав компанії змогу продовжувати зростати, не відчуваючи, як ґрунт…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> В основі всього, чим займалася компанія, лежала фізична складова — сервери, реальні мережі, IP‑телефонія — і все це мало просто працювати. Цей рівень непомітний, коли працює справно, і надзвичайно помітний у ту мить, коли перестає, а зростання компанії трималося на його безвідмовності.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб адмініструвати цю інфраструктуру та підтримувати її стабільність у міру зростання компанії.</p>
<p><strong>Дія.</strong> Обслуговувалися сто bare‑bone серверів разом із фізичними мережами та системами IP‑телефонії — налаштування, обслуговування, усунення несправностей у разі збоїв. Bare‑bone сервери означають роботу безпосередньо з апаратним забезпеченням, тож тут є практична, фізична складова: кабелі, корпуси, телефонна система, збій якої помічають усі в ту саму секунду. Завдання полягало в тому, щоб усе це залишалося нудним — у хорошому сенсі.</p>
<p><strong>Результат.</strong> Сервери, мережі та телефонія працювали надійно, і саме цей стабільний фізичний фундамент дав компанії змогу продовжувати зростати, не відчуваючи, як ґрунт хитається під ногами.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Адмініструвала 40 вебсайтів на хостинг‑серверах Ubuntu Linux з Apache та Nginx, забезпечивши високу доступність і продуктивність.</title>
      <link>https://platform.engineer.company/uk/portfolio/administered-40-websites-on-ubuntu-linux-hosting-servers-53/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/administered-40-websites-on-ubuntu-linux-hosting-servers-53/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Усі сорок сайтів працювали з високою доступністю та гарною продуктивністю, що дало клієнтам хостинг, про який не треба було думати.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Веброзробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка вебсайтів та CMS</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Існував портфель робочих вебсайтів, які мали залишатися онлайн і швидкими — а хостинг це ще одна з тих робіт, які непомітні, доки сайт не впаде, і от тоді про нього думають усі й нічого більше.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб адмініструвати ці сайти та підтримувати їхню високу доступність і швидкість.</p>
<p><strong>Дія.</strong> Сорок вебсайтів працювали на хостинг‑серверах Ubuntu Linux, на поєднанні Apache та Nginx — конфігурація, налаштування продуктивності, постійне обслуговування для підтримання надійності під реальним трафіком. Саме реальний трафік тут ключовий: сайт, який нормально почувається, коли ним ніхто не користується, і падає, щойно ним починають користуватися, насправді не адмініструвався — його просто залишили без уваги. Тож робота полягала в тому, щоб підтримувати їхню справність під фактичним навантаженням.</p>
<p><strong>Результат.</strong> Усі сорок сайтів працювали з високою доступністю та гарною продуктивністю, що дало клієнтам хостинг, про який не треба було думати. Стабільність і надійність під реальним використанням — це вся суть хостингу, і саме це забезпечили ці сайти.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Спроєктувала, розробила, впровадила та підтримувала інфраструктуру, обробку даних і картографічний застосунок безперервно протягом 2 років без вихідних, свят чи відпустки, по 10–14 годин на день.</title>
      <link>https://platform.engineer.company/uk/portfolio/architected-developed-implemented-supported-infrastructure-data-processing-and-55/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/architected-developed-implemented-supported-infrastructure-data-processing-and-55/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Платформа залишалася безперервно доступною та еволюціонувала від крихкого раннього прототипу до надійного хребта продукту, підтримуючи компанію протягом…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Full‑Stack розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">GIS / геопростір</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інженерія даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Пайплайни даних (ETL/ELT)</category>
      <category domain="https://platform.engineer.company/uk/services/">Full‑Stack продуктова розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">GIS та геопросторові рішення</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка пайплайнів даних (ETL/ELT)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Стартап у сфері зеленої енергетики на ранній стадії розвитку залежав від єдиної платформи для відстеження, моніторингу та оптимізації активів відновлюваної енергетики, проте не мав ані окремої інфраструктурної команди, ані сформованої інженерної організації для її побудови й експлуатації. Усю технічну основу — хмарну інфраструктуру, пайплайни обробки даних і клієнтський GIS‑застосунок з картою — потрібно було створити й підтримувати в безперервній роботі на ринку, де будь‑який простій чи розрив у даних напряму підривав довіру клієнтів і дохід.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб одноосібно спроєктувати, побудувати та експлуатувати всю систему наскрізно, охоплюючи інженерію платформи й даних, DevOps та забезпечення надійності (site reliability). Окрім написання коду, це означало відповідальність за продакшн: розгортання та убезпечення інфраструктури, проєктування рівня обробки даних, що живив карту, і гарантування безперервної доступності застосунку для зростаючої бази клієнтів — і все це в межах обмежень і невпинного темпу стартапу, що стрімко розвивався.</p>
<p><strong>Дія.</strong> Протягом двох років інфраструктура, пайплайни даних і картографічний застосунок проєктувалися, впроваджувалися та підтримувалися без перерв — без вихідних, свят чи відпусток, часто по 10–14 годин на день. Було обрано прагматичну, модульну архітектуру, щоб зберегти придатність до підтримки одноосібної експлуатації, з автоматизованим розгортанням, моніторингом та сповіщеннями, аби проблеми виявлялися й вирішувалися швидко. Обробка даних постійно донастроювалася для надійності та продуктивності, релізи випускалися поступово, і кожен рівень — від серверів до карти, орієнтованої на користувача, — підтримувався та вдосконалювався особисто, у відповідь на реальне використання клієнтами.</p>
<p><strong>Результат.</strong> Платформа залишалася безперервно доступною та еволюціонувала від крихкого раннього прототипу до надійного хребта продукту, підтримуючи компанію протягом критичної фази зростання завдяки одноосібній відповідальності одного інженера. Таке безпосереднє, практичне управління забезпечувало достатню надійність інфраструктури, даних і картографічного застосунку для підтримки допродажів, ліцензування даних і залучення нових клієнтів, а також продемонструвало рідкісний рівень відданості, широти охоплення й наскрізної відповідальності на всіх рівнях стеку.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Оптимізувала бюджетні витрати у 10 разів без втрати продуктивності для міжнародного клієнта, переосмисливши загальну інфраструктуру, усунувши непотрібні сервіси та перенісши систему з хмари AWS.</title>
      <link>https://platform.engineer.company/uk/portfolio/optimized-budget-costs-10-times-with-zero-loss-56/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/optimized-budget-costs-10-times-with-zero-loss-56/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Бюджетні витрати скоротилися приблизно у 10 разів, без жодної втрати продуктивності — та сама спроможність за частку тієї суми, яку сплачували раніше.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Міграції та модернізація</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Міжнародний клієнт ніс на собі суттєво роздуті інфраструктурні витрати. Її налаштування AWS було надлишково забезпечене ресурсами й накопичило сервіси, якими вже ніхто не користувався, тож рахунок за хмару повністю вийшов з будь‑якої пропорції до того, що бізнесу дійсно було потрібно. Історія звична — ніхто не планує перевитрачати, це просто накопичується, коли ніхто не стежить за лічильником.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб суттєво скоротити витрати без жодної втрати продуктивності, а це означало по‑справжньому переосмислити інфраструктуру, а не підрізати по краях — підрізання по краях рідко відчутно змінює рахунок, який структурно є занадто великим.</p>
<p><strong>Дія.</strong> Тож робота велася наскрізно. Спочатку проведено аудит того, що фактично використовувалося — саме тут проявляють себе дубльовані та непотрібні сервіси — і їх було прибрано. Потім усе, що залишилося, приведено у відповідність до реального попиту замість розрахунків на найгірший сценарій, закладених у початкове налаштування. А головним кроком стало повне перенесення навантажень з AWS на більш економічно вигідний варіант хостингу — виконане обережно, поетапно, так, щоб діючий бізнес жодного разу не відчув, як під ним відбувається міграція.</p>
<p><strong>Результат.</strong> Бюджетні витрати скоротилися приблизно у 10 разів, без жодної втрати продуктивності — та сама спроможність за частку тієї суми, яку сплачували раніше. Це вивільнило реальну суму коштів, яка місяць за місяцем тихо витікала у надто великий рахунок за хмару, а для бізнесу це означало гроші, що напряму повернулися до чистого прибутку.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Спроєктувала систему перемикання контексту організації з клієнтським localStorage та серверним дзеркалюванням cookie, що дозволила користувачам діяти від імені керованих організацій, забезпечуючи авторизацію за принципом найменших привілеїв.</title>
      <link>https://platform.engineer.company/uk/portfolio/designed-an-organization-context-switching-system-with-client-59/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/designed-an-organization-context-switching-system-with-client-59/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Користувач може діяти від імені будь-якої організації, якою керує, без жодних перешкод, а інтерфейс залишається синхронізованим і на клієнті, і на сервері.</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Full‑Stack розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> На платформі морський фахівець може керувати організаціями — компаніями, академіями — які не мають власних облікових записів для входу. Обліковим записом є сама людина; організація — це те, від імені чого вона діє. Тож користувачу потрібно переміщуватися по всьому застосунку як будь‑яка з організацій, якими він керує, вільно перемикаючись між ними, і ця зручність не повинна перетворюватися на діру в авторизації.</p>
<p><strong>Завдання.</strong> Перемикання контексту мало бути швидким і непомітним для користувача, і водночас потрібно було гарантувати, що активний контекст сам собою ніколи не надасть доступу, на який немає прав.</p>
<p><strong>Дія.</strong> За це відповідає OrganizationContext зі зберіганням стану на обох сторонах. На клієнті джерелом істини щодо того, від імені якої організації користувач наразі діє, є localStorage, тож перемикання відбувається миттєво — без звернення до сервера. Серверний cookie дзеркалить цей стан, щоб сторінки, що рендеряться на сервері, визначали той самий контекст під час SSR; на сервері є getServerViewMode, який його зчитує. Важливо, що жодне з цього не використовується для ухвалення рішень щодо доступу. Авторизація повторно перевіряється на сервері під час кожного запиту. Контекст на фронтенді існує заради досвіду користування — показати саме те, що потрібно, — а сервер є єдиним джерелом істини щодо того, що дозволено робити.</p>
<p><strong>Результат.</strong> Користувач може діяти від імені будь‑якої організації, якою керує, без жодних перешкод, а інтерфейс залишається синхронізованим і на клієнті, і на сервері. Але оскільки права щоразу перевіряються на сервері, ця зручність жодним чином не послаблює безпеку. Втручання у вміст localStorage змінює лише те, що бачить власний інтерфейс користувача, і нічого більше — сервер усе одно відмовить.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Згенерувала контракт API з бази даних назовні — OpenAPI, типізований TypeScript‑клієнт на 44 076 рядків, 61 mock‑обробник та обмеження, які застосовує UI, — з перевіркою на кожній ланці, що падає при розходженні.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-a-request-schema-validation-contract-with-automated-61/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-a-request-schema-validation-contract-with-automated-61/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Поле не може змінитися лише з одного боку — воно завалюється на першому ж переході, який це помічає, у білді, за кілька хвилин після зміни.</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Фронтенд і бекенд розвиваються у власному темпі, і їхні уявлення про payload запиту можуть непомітно розходитися. Зазвичай про це дізнаються за 422 у браузері — вже після того, як розбіжність потрапила в продакшн, а це найдорожчий момент, щоб про неї дізнатися. Написання обох сторін вручну за одним документом цього не виправляє: воно лише переносить розбіжність на того, хто забув перечитати документ.</p>
<p><strong>Завдання.</strong> Обидві сторони мали генеруватися з одного джерела, а не узгоджуватися між двома, і кожен крок цієї генерації мав перевірятися, а не братися на віру.</p>
<p><strong>Дія.</strong> Ланцюг починається з бази даних і йде назовні. Схема та її функції визначають структури даних; типи Go визначають API; Huma формує з них опис OpenAPI; з цього опису генерується типізований клієнт TypeScript — 44 076 рядків; поряд із ним генерується 61 mock‑обробник, тож власні тести фронтенду виконуються проти реального контракту, а не проти рукописної фікстури; а обмеження, які UI застосовує до форми, походять із того самого місця, замість того щоб їх перенабирали у валідаторі. Кожен перехід має запобіжник. Перевірка контракту в CI порівнює те, що надсилає фронтенд, із тим, що очікує API, і завалює білд за розбіжності, а під нею є перевірка схеми, яка звіряє реальну структуру даних, а не її опис. Вона свідомо охоплює місця, де розбіжності люблять ховатися: опціональні поля тіла запиту, де плутають «відсутнє» і null, та enum‑и query‑параметрів, де обидві сторони можуть тихо розійтися в допустимих значеннях.</p>
<p><strong>Результат.</strong> Поле не може змінитися лише з одного боку — воно завалюється на першому ж переході, який це помічає, у білді, за кілька хвилин після зміни. Це усунуло повторюваний і по‑справжньому набридливий клас багів: непомітний під час code review і такий, що проявляється лише в рантаймі. Ціна — крок генерації посеред усього: перегенерація є рутиною, а ланцюг вартий довіри рівно настільки, наскільки надійна його найменш захищена ланка, — тому запобіжник отримав кожен перехід.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала електронну пошту як можливість платформи — три провайдери з резервним перемиканням, webhooks доставки, логування надсилання й доставки, шаблонізацію та кампанії — за перевіркою під час запуску, яка не дасть застосунку стартувати без жодного з них.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-email-as-a-platform-capability-with-failover-62/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-email-as-a-platform-capability-with-failover-62/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Ціла категорія тихих збоїв перейшла зі стану «користувач помічає це через кілька днів» у стан «розгортання зупиняється», а невдалий день у провайдера став…</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Електронна пошта відіграє значну роль на платформі — верифікація, сповіщення, дайджести, кампанії, усе те, на що користувач насправді чекає. А поштовий провайдер — це саме той тип залежності, що тихо ламається: конфігурація виглядає нормально, застосунок запускається, і про проблему дізнаються лише тоді, коли реальна людина так і не отримує обіцяного листа. Це найгірший спосіб про це дізнатися. З одним провайдером усе ще гірше, бо збій є повним, а виправляти його — комусь іншому.</p>
<p><strong>Завдання.</strong> Пошту потрібно було трактувати як спроможність, якою володіє платформа, а не як клієнтську бібліотеку, яку вона викликає, — здатну пережити збій провайдера, здатну сказати, що сталося з конкретним листом, і голосну під час запуску в тих середовищах, де мовчання небезпечне.</p>
<p><strong>Дія.</strong> Три провайдери стоять за одним інтерфейсом — SendGrid як основний, а SMTP2GO та Azure Communication Services позаду нього, — і перемикання між ними автоматичне, а не є зміною конфігурації, зробленою під тиском. Доставка не вважається даністю: вхідні webhooks повідомляють, що кожен провайдер зробив із листом, і обидві сторони записуються — у журнал надсилань і таблицю подій доставки, — тож «чи отримала ця людина свій лист із верифікацією» є запитом, а не здогадом. Шаблонізація тримає тіла листів поза кодом, а окрема схема broadcast — 5 таблиць і 24 функції — доставляє кампанії сегментам користувачів, і це інша задача, ніж транзакційна пошта, тож її й будували як іншу. Перед усім цим стартова перевірка надсилає реальний лист через увесь стек, за прапорцем: у середовищі розробки це просто логує попередження й продовжує роботу, бо ніхто не хоче, щоб ноутбук відмовлявся запускатися через прострочений ключ пісочниці, а в staging і production збій є фатальним і процес завершується, а не розгортає білд, який не може надсилати пошту. Сам шлях надсилання проходить через клієнт із захистом від SSRF і тайм‑аутом 30 секунд, а асинхронний шлях доставки має retries і backoff, тож короткочасний збій не втрачає повідомлення.</p>
<p><strong>Результат.</strong> Ціла категорія тихих збоїв перейшла зі стану «користувач помічає це через кілька днів» у стан «розгортання зупиняється», а невдалий день у провайдера став деградованим шляхом, а не аварією. Ціна — три інтеграції, які треба підтримувати робочими замість однієї, і журнали доставки, що ростуть і потребують чищення; обидві прийнятні, бо пошта — це канал, який платформа не може обійти.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Розгорнула інфраструктуру Azure як код за допомогою Bicep — Container Apps, PostgreSQL Flexible Server, Front Door/WAF та мережу — у середовищах development, staging і production.</title>
      <link>https://platform.engineer.company/uk/portfolio/provisioned-azure-infrastructure-as-code-with-bicep-container-68/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/provisioned-azure-infrastructure-as-code-with-bicep-container-68/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Середовища стали відтворюваними й доступними для перегляду. Дрейф перестав бути загадкою, бо джерелом істини є код, а підняти чи відновити інфраструктуру — це…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформа живе на Azure, а Azure, зроблений вручну — клацання по порталу, налаштування то тут, то там, — це пастка. Усе дрейфує, ніхто не пам&rsquo;ятає, чому щось саме таке, яке є, а відновлення після поганого дня повільне й нервове. А коли середовищ, які треба тримати синхронізованими, більше одного, стає тільки гірше.</p>
<p><strong>Завдання.</strong> Перевести все в код, щоб середовище було чимось, що можна прочитати, переглянути й відтворити, а не купою ручного стану.</p>
<p><strong>Дія.</strong> Уся інфраструктура описана в Bicep. Кожне середовище — testing, staging, product — виходить із тих самих шаблонів: api та www працюють як Azure Container Apps у managed environment, PostgreSQL Flexible Server, Redis для кешування, Front Door з політикою WAF попереду та мережа під цим усім (VNet, NSG, приватний DNS), з підключеним Log Analytics для діагностики. Образи витягуються з Azure Container Registry проєкту. Оскільки все параметризовано, розгортання нового середовища чи зміна наявного — це pull request, а не заявка в підтримку самому собі.</p>
<p><strong>Результат.</strong> Середовища стали відтворюваними й доступними для перегляду. Дрейф перестав бути загадкою, бо джерелом істини є код, а підняти чи відновити інфраструктуру — це питання застосування шаблонів, а не пригадування, що клацали минулого разу. Це різниця між інфраструктурою, яку контролюють, і інфраструктурою, що починає контролювати сама.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала пайплайни CI/CD на GitHub Actions з distroless‑образом продакшн‑фронтенду та просуванням між кількома середовищами.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-github-actions-ci-cd-pipelines-with-a-69/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-github-actions-ci-cd-pipelines-with-a-69/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Релізи перестали бути обережним ручним ритуалом і стали рутинною, нудною подією, а це саме те, чого хочеться від релізів.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Контейнери (Docker/Kubernetes)</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Контейнеризація та оркестрація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Постачання не повинне залежати від того, чи хтось пам&rsquo;ятає всі кроки, а те, що зрештою працює в продакшн, не повинне бути товстим контейнером загального призначення з оболонкою та пакетним менеджером, якими він ніколи не скористається, — це просто зайва поверхня для атак без жодної потреби.</p>
<p><strong>Завдання.</strong> Зробити шлях від коміту до запуску в Azure автоматичним і тримати продакшн‑образи такими малими й закритими, наскільки дозволяє кожне навантаження.</p>
<p><strong>Дія.</strong> Пайплайн побудовано на GitHub Actions. Окремі workflow відповідають за перевірку якості коду, тести й розгортання для кожного середовища, а поруч працюють CodeQL, dependency review та крок формування SBOM, тож нічого не потрапляє в середовище без попереднього проходження перевірок. Образи — це multi‑stage‑білди, і базовий образ для кожної частини обрано за його перевагами, а не за єдиним загальним правилом: фронтенд постачається на distroless‑образі (gcr.io/distroless/cc‑debian13 — без оболонки, без пакетного менеджера), Go API — на легкому Alpine, а образ бази даних — на postgres‑slim. Просування переміщує білд через середовища за визначеним маршрутом, а не вручну.</p>
<p><strong>Результат.</strong> Релізи перестали бути обережним ручним ритуалом і стали рутинною, нудною подією, а це саме те, чого хочеться від релізів. Продакшн‑фронтенд працює на настільки малому, наскільки це взагалі можливо, перевірки ловлять проблеми до того, як вони потраплять у продакшн, а «розгортання» — це те, що робить пайплайн, а не те, через що будь‑кому доводиться перейматися.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Написала 578 цілей автоматизації go‑task, що охоплюють нативний, Docker та HTTPS режими розробки, лінтинг, тестування, базу даних та розгортання.</title>
      <link>https://platform.engineer.company/uk/portfolio/authored-578-go-task-automation-targets-70/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/authored-578-go-task-automation-targets-70/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Будь-хто може виконати task --list і побачити весь інструментарій викладеним, і запустити будь-яку його частину однаково, незалежно від того, що під капотом.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Кодова база — це поліглотний монорепозиторій: Go, TypeScript, SQL, Python, shell, — і кожен з них приносить власний спосіб збирати, тестувати, лінтити й запускати. Якщо це нічим не впорядкувати, кожен носить у голові шпаргалку команд для конкретних інструментів, а новачки витрачають перший день лише на те, щоб зрозуміти, як усе запустити.</p>
<p><strong>Завдання.</strong> Дати всьому проєкту одні вхідні двері: єдиний послідовний спосіб запускати що завгодно, незалежно від того, якою мовою це написано.</p>
<p><strong>Дія.</strong> Це побудовано на go‑task — шарі Taskfile, що виріс до 578 іменованих цілей: 50 у кореневому файлі та 528 у файлах із namespace&rsquo;ами під ним. Тут є режими розробки (native, Docker, HTTPS‑варіант для тестування PWA й мобільних застосунків), сторона якості коду (lint, format, test, fix для всіх мов), керування базою даних і специфічні для середовищ завдання збирання й розгортання. Є навіть режим low‑memory для машин, яким бракує RAM, щоб зібрати фронтенд звичайним способом. Мета полягала не в тому, щоб мати багато завдань, а в тому, щоб ніколи не доводилося знати базову команду.</p>
<p><strong>Результат.</strong> Будь‑хто може виконати task &ndash;list і побачити весь інструментарій викладеним, і запустити будь‑яку його частину однаково, незалежно від того, що під капотом. Онбординг став коротшим, а дрібні дурні помилки — не той прапорець, не та директорія, напівзабута команда — здебільшого зникли. Це число водночас є попередженням: 578 цілей — це більше, ніж будь‑хто здатен утримати в голові, тож зручність користування тримається на іменуванні та namespace&rsquo;ах, а не на тому, що кількістю варто пишатися.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Відповідала за наскрізне розгортання платформи в Azure, керуючи релізами в середовищах development, staging і production.</title>
      <link>https://platform.engineer.company/uk/portfolio/owned-end-to-end-deployments-of-the-platform-71/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/owned-end-to-end-deployments-of-the-platform-71/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Зміни передбачувано доходять до кожного середовища заданим шляхом, без жодних ситуативних ручних розгортань у процесі.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформа мала охоплювати користувачів у кількох середовищах Azure, а розгортання — це той шов, де сходяться інфраструктура, пайплайн збирання й застосунок. Це також те місце, де маленька помилка перестає бути багом і стає збоєм у роботі, тож це та частина, яку найменше хочеться робити вручну й напівпо пам&rsquo;яті.</p>
<p><strong>Завдання.</strong> Розгортання було взято під повний контроль від початку до кінця, щоб зміна щоразу виходила в кожне середовище однаково передбачуваним способом.</p>
<p><strong>Дія.</strong> Релізи рухаються фіксованим маршрутом — спочатку development, потім staging, потім production, — а не так, що хтось пушить напряму в live‑середовище. Пайплайн CI/CD збирає образи й постачає їх, а шаблони Bicep тримають цільову інфраструктуру ідентичною від одного середовища до іншого, тож білд щоразу не потрапляє в трохи інше місце. Конфігурація, що відрізняється для кожного середовища, зберігається окремо від секретів, а це означає, що той самий зібраний артефакт можна просувати через середовища, і він просто підхоплює правильні налаштування там, де приземляється, замість того щоб перезбиратися для кожного з них.</p>
<p><strong>Результат.</strong> Зміни передбачувано доходять до кожного середовища заданим шляхом, без жодних ситуативних ручних розгортань у процесі. Реліз перетворився на контрольований, повторюваний крок замість моменту із затамованим подихом, і саме це значною мірою тримало живу платформу стабільною, поки під нею все ще швидко змінювалося.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Налаштувала зберігання резервних копій бази даних як infrastructure‑as‑code, провела аудит готовності до відновлення й задокументувала процедуру відновлення — назвавши залишкові прогалини, а не залишивши їх на час інциденту.</title>
      <link>https://platform.engineer.company/uk/portfolio/configured-database-backup-retention-as-infrastructure-as-code-72/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/configured-database-backup-retention-as-infrastructure-as-code-72/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Відновлення перестало бути туманною заспокійливою фразою й стало задокументованою позицією з названими прогалинами.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Адміністрування баз даних (DBA)</category>
      <category domain="https://platform.engineer.company/uk/services/">Резервне копіювання та відновлення</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Продукт, що живе на своїх даних, не може дозволити собі втратити хоч якісь, а «десь є бекапи» — це сподівання, а не план відновлення. Єдиний бекап, який чогось вартий, — це той, про який відомо, що він відновлюється, у середовище, яке відомо, що можна відбудувати. У продукті не було записано жодної з цих двох половин.</p>
<p><strong>Завдання.</strong> Визначити реальну готовність до відновлення замість того, щоб її припускати, — дані, середовище навколо них і чесний опис того, наскільки далеко це сягає сьогодні.</p>
<p><strong>Дія.</strong> Retention резервних копій налаштовано в Bicep поруч із базою даних, яку він захищає, тож відновлення на конкретний момент часу є властивістю шаблону, а не налаштуванням, яке колись хтось клікнув у порталі. Середовище навколо неї теж описане як infrastructure‑as‑code, а це та тиха половина, про яку люди забувають: відновити базу даних у середовище, яке довелося б відбудовувати вручну по пам&rsquo;яті, — це не справжнє відновлення. Далі готовність проаудитували й описали — процедуру відновлення, навчання, яке її виміряло б, і прогалини, що досі відкриті: геонадлишковість вимкнено, а цільовий час відновлення запропоновано, а не виміряно, бо навчання ще не проводили.</p>
<p><strong>Результат.</strong> Відновлення перестало бути туманною заспокійливою фразою й стало задокументованою позицією з названими прогалинами. Це звучить менш ефектно, ніж «аварійне відновлення: зроблено», і коштує значно більше — той, хто візьметься за це наступним, знає, що покрито, що ні і яке саме навчання закриває різницю. Названу прогалину можна закрити; неназвану знаходять під час інциденту.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Посилила захист застосунку за допомогою CSP на основі nonce, HSTS, cookie SameSite, ролей бази даних за принципом найменших привілеїв та серверних повторних перевірок прав доступу.</title>
      <link>https://platform.engineer.company/uk/portfolio/hardened-the-application-with-nonce-based-csp-hsts-77/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/hardened-the-application-with-nonce-based-csp-hsts-77/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Безпека не залежить від того, як поводиться UI. Захист побудовано шарами так, щоб подолання одного рівня не давало проходу через решту, а вся система базується…</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформа зберігає професійні та організаційні дані — саме ті, які люди очікують бачити захищеними належним чином, тож одного рубежу оборони було апріорі недостатньо. Робоче припущення таке: клієнт вороже налаштований, — усе, що примусово виконує браузер, може бути вимкнене тим, у чиїх руках цей браузер, — і безпека все одно мусить триматися.</p>
<p><strong>Завдання.</strong> Платформу потрібно було захистити на кожному рівні — фронтенд, API, база даних, — так, щоб безпеку забезпечував сервер незалежно від того, що саме дозволяв інтерфейс.</p>
<p><strong>Дія.</strong> На фронтенді проксі‑мідлвар Next.js — proxy.ts — встановлює Content‑Security‑Policy з nonce для кожного запиту та strict‑dynamic, а також HSTS і SameSite cookies, тож браузер жорстко обмежений у тому, що він виконає й надішле. На рівні API діють rate limiting, CORS, обмеження розміру запиту, валідація вводу до того, як щось торкнеться бази даних, і логування подій, пов&rsquo;язаних із безпекою. У базі даних API входить під роллю з мінімальними привілеями, яка може лише виконувати (EXECUTE) функції застосунку, самі функції запускаються з SECURITY DEFINER, а все параметризовано. А права доступу — тариф, роль, організація, прив&rsquo;язка до судна — перевіряються сервером повторно на кожен запит, тоді як фронтендні обмеження розглядаються лише як UX. Ці обмеження визначають, що видно; сервер визначає, що дозволено робити.</p>
<p><strong>Результат.</strong> Безпека не залежить від того, як поводиться UI. Захист побудовано шарами так, щоб подолання одного рівня не давало проходу через решту, а вся система базується на припущенні, що клієнту довіряти не можна, — і це правильне припущення для даних, які люди довіряють платформі.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Встановила стандарт якості без жодних попереджень для шести мов — Go, TypeScript, SQL, Python, Shell і Markdown — дотримання якого забезпечували pre‑commit hooks.</title>
      <link>https://platform.engineer.company/uk/portfolio/set-a-zero-warnings-quality-bar-across-six-79/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/set-a-zero-warnings-quality-bar-across-six-79/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Проблеми виправляються біля джерела, а не відкладаються в беклог, який ніхто не розчищає, і кодова база лишається чистою за замовчуванням, а не завдяки…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Попередження, що накопичуються, непомітно роз&rsquo;їдають якість. Кожна проігнорована діагностика трохи знижує планку, і щойно білд починає видавати їх сорок штук, їх уже ніхто не читає, а реальна проблема сидить у цьому списку на видноті, бо «попередження» перетворилися на фоновий шум. У поліглотній кодовій базі джерел такого шуму ще більше, і йому легше цим скористатися.</p>
<p><strong>Завдання.</strong> Репозиторію потрібна була одна безкомпромісна планка якості для всіх мов, щоб проблеми виправлялися, а не накопичувалися.</p>
<p><strong>Дія.</strong> Впроваджено політику нульових попереджень, а стежить за нею інструментарій, — адже політика, що покладається на пильність кожного, програє вже на першому завантаженому тижні. Кожна діагностика лінтера — це помилка: рівня «warn», у якому можна сховатися, просто немає, — і це однаково для всього стеку: Go з golangci‑lint, TypeScript з ESLint, SQL з SQLFluff, Python з Ruff, shell з ShellCheck, Markdown з markdownlint. Inline‑придушення заборонені, тож діагностику не можна замаскувати — проблему треба справді виправити. Pre‑commit- і pre‑push‑хуки запускають лінтери й тести, тож коміт, який вніс би проблему, просто не створюється. Є навіть обмеження на довжину функцій і файлів, щоб модулі не розросталися за межу читабельності.</p>
<p><strong>Результат.</strong> Проблеми виправляються біля джерела, а не відкладаються в беклог, який ніхто не розчищає, і кодова база лишається чистою за замовчуванням, а не завдяки періодичним героїчним зусиллям. Стандарт однаковий незалежно від мови, і тримає його інструментарій, а не чиясь сила волі, — тому він справді тримається.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Забезпечувала цілодобову підтримку інфраструктури 24/7 для IPTV/OTT‑стрімінгової платформи, адмініструючи ~1 000 серверів та системи клієнтів для глобальних замовників у Китаї, США та Німеччині.</title>
      <link>https://platform.engineer.company/uk/portfolio/provided-round-the-clock-24-7-infrastructure-support-82/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/provided-round-the-clock-24-7-infrastructure-support-82/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Платформа лишалася безперервно доступною для глобальної аудиторії, а проблеми виявлялися та усувалися незалежно від того, о котрій годині вони виникали, — ще…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">IT‑підтримка та helpdesk</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Це була IPTV/OTT‑стримінгова платформа з клієнтами, розкиданими по Китаю, США та Німеччині, а це означало, що тихої години для обслуговування просто не існувало — хтось, десь, завжди дивився. Простій на такій платформі — це не абстрактна метрика; це просто чийсь телевізор, що перестав показувати, і людям байдуже чому.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб тримати інфраструктуру платформи доступною цілодобово — справді цілодобово, а не за принципом «робочі години плюс чергування, на яке ніхто не відповідає».</p>
<p><strong>Дія.</strong> Підтримка 24/7 забезпечувалася приблизно для тисячі серверів, плюс чимала кількість систем, що належали клієнтам, — їх адміністрували, моніторили, тримали захищеними та налаштованими по всьому стримінговому господарству. Оскільки клієнти перебували у трьох дуже різних часових поясах, поняття «неробочий час» фактично не існувало: проблема о 3‑й ночі за місцевим часом була прайм‑таймом для когось іншого, тож до неї так і ставилися. Значна частина роботи полягала в тому, щоб помітити відхилення до того, як воно переросло в збій, адже на живій стримінговій платформі немає можливості тихо виправити щось постфактум.</p>
<p><strong>Результат.</strong> Платформа лишалася безперервно доступною для глобальної аудиторії, а проблеми виявлялися та усувалися незалежно від того, о котрій годині вони виникали, — ще до того, як досягали екрана глядача. На сервісі 24/7 у цьому й полягає вся робота: успіх виглядає як відсутність будь‑яких подій, а саме цього і хотіли глядачі.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Забезпечувала безперебійну передачу сигналів IPTV‑стрімінгу між постачальниками та клієнтами, цілодобово моніторячи та підтримуючи стрімінгову мережу й IP‑телефонію.</title>
      <link>https://platform.engineer.company/uk/portfolio/ensured-uninterrupted-delivery-of-iptv-streaming-signals-between-83/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/ensured-uninterrupted-delivery-of-iptv-streaming-signals-between-83/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Потоки та дзвінки лишалися надійними по всій платформі, а проблеми виявлялися й виправлялися до того, як перетворювалися на збій сервісу, який хтось міг би…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> IPTV живе чи гине залежно від того, чи проходить сигнал. Потоки йдуть від постачальників через платформу до клієнтів, і будь‑який розрив у будь‑якій точці цього ланцюга означає чорний екран для когось. Поруч працювала IP‑телефонія з тією самою вимогою: вона просто мала працювати.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб гарантувати безперервність доставлення сигналу та роботи телефонії.</p>
<p><strong>Дія.</strong> Стримінгову мережу та IP‑телефонію моніторили, усували в них несправності й обслуговували цілодобово. Сенс постійного спостереження в тому, що проблеми стримінгу спершу заявляють про себе деградацією, а вже потім перетворюються на повний обрив — потік, що починає заїкатися, канал, що стає нестабільним, — і якщо стежити уважно, це можна перехопити на етапі заїкання, а не чорного екрана. Тож значна частина роботи полягала в тому, щоб випереджати сигнал, а не реагувати на скарги на нього.</p>
<p><strong>Результат.</strong> Потоки та дзвінки лишалися надійними по всій платформі, а проблеми виявлялися й виправлялися до того, як перетворювалися на збій сервісу, який хтось міг би помітити. Підтримувати сигнал між постачальниками й кінцевими клієнтами без видимого розриву — це тиха, постійна робота, і саме тихою вона й має бути.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Планувала та впроваджувала нову функціональність інфраструктури для внутрішніх і зовнішніх систем, створюючи рішення, достатньо довговічні, щоб працювати роками з мінімальними змінами.</title>
      <link>https://platform.engineer.company/uk/portfolio/planned-and-implemented-new-infrastructure-functionality-for-internal-85/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/planned-and-implemented-new-infrastructure-functionality-for-internal-85/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Системи залишалися функціональними та ефективними ще довго після їх побудови, працюючи роками майже без змін.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> У міру зростання організації її внутрішні та зовнішні системи постійно потребували нових можливостей, які додавалися нашвидкуруч. Найпростіший спосіб зробити це — обрати те, що найшвидше сьогодні; проблема простого шляху в тому, що вже за півроку доводиться повертатися й усе переробляти.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб спланувати та побудувати інфраструктурну функціональність, яка справді витримає перевірку часом, — не просто працювати зараз, а продовжувати працювати.</p>
<p><strong>Дія.</strong> Нову інфраструктурну функціональність було сплановано та впроваджено у внутрішніх і зовнішніх системах з розрахунком на довговічність — саме той тип рішень, які будують один раз і правильно, щоб вони роками працювали з мінімальним втручанням, а не вимагали постійної уваги. Це свідомий вибір щоразу: витратити трохи більше часу на роздуми на старті, щоб не приректи себе на вічне «нянькання» з результатом.</p>
<p><strong>Результат.</strong> Системи залишалися функціональними та ефективними ще довго після їх побудови, працюючи роками майже без змін. Саме така довговічність і є справжнім мірилом інфраструктурної роботи — зробити щось, що працює сьогодні, може будь‑хто; зробити щось, що тихо продовжує працювати через роки, — завдання значно складніше й цінніше.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Як одна з перших співробітниць, спроєктувала та побудувала всю базову інфраструктуру та супутні процеси з нуля для SaaS‑стартапу в зеленій енергетиці, заклавши фундамент для швидкого зростання.</title>
      <link>https://platform.engineer.company/uk/portfolio/as-one-of-the-first-hires-designed-and-86/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/as-one-of-the-first-hires-designed-and-86/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Стартап отримав міцну технічну основу, і саме вона дала бізнесу змогу згодом швидко зростати. Бути тим, хто будує таку основу з нуля, — це особлива…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Це був SaaS‑стартап у сфері зеленої енергетики — з перспективною ідеєю, але практично без технічної основи під нею. Прихід на посаду одним із перших співробітників означав той етап, коли підтримувати ще нічого, бо нічого ще не існує, — закладання ґрунту, на якому згодом стоятимуть усі інші.</p>
<p><strong>Завдання.</strong> Завданням було з нуля побудувати основну інфраструктуру та процеси навколо неї.</p>
<p><strong>Дія.</strong> Було спроєктовано та побудовано всю базову інфраструктуру й супутні процеси — сервери, мережі, потоки даних, безпеку, операційну складову. У стартапі це означає ухвалення рішень, які потім важко скасувати, тож мета полягала не просто в тому, щоб «щось запрацювало», а в тому, щоб закласти фундамент, здатний витримати вагу швидкого зростання без потреби зривати все й переробляти в момент, коли компанія стане більшою. Ранні інфраструктурні рішення або стають тим, що дає змогу масштабуватися, або тим, що потім рік доводиться розбирати; мета однозначно була в першому.</p>
<p><strong>Результат.</strong> Стартап отримав міцну технічну основу, і саме вона дала бізнесу змогу згодом швидко зростати. Бути тим, хто будує таку основу з нуля, — це особлива відповідальність: зроби правильно — і ніхто не помітить, зроби неправильно — і помітять усі, — і в цьому випадку основа витримала.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала командну співпрацю, керування паролями, управління завданнями та часом, а також створила напівавтоматичну систему демонстрації проєктів, підвищивши продуктивність команди.</title>
      <link>https://platform.engineer.company/uk/portfolio/automated-team-collaboration-password-management-task-and-time-89/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/automated-team-collaboration-password-management-task-and-time-89/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Операційна ефективність зросла, а команда стала продуктивнішою, оскільки рутинна координація, яка раніше потребувала постійної людської уваги, тепер значною…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/categories/">Управління проєктами</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Управління проєктами (Agile)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Значна частина операційної роботи команди — координація, управління паролями, відстеження завдань і часу — виконувалася вручну, а ручна координація — це тихий податок: його ніколи не помічають, але він постійно з&rsquo;їдає години, які могли б піти на щось корисніше.</p>
<p><strong>Завдання.</strong> Метою була автоматизація цієї рутинної операційної роботи.</p>
<p><strong>Дія.</strong> Було автоматизовано ті ділянки, які піддавалися автоматизації, — командну співпрацю, управління паролями, управління завданнями, управління часом, — а зверху додано напівавтоматичну систему презентації проєктів. Ідея в усьому цьому була одна: зняти рутинну координацію з людей, щоб вона виконувалася сама, і дати їм змогу спрямувати вивільнену увагу на роботу, яка справді потребує людини. Система презентації проєктів була тим самим підходом, застосованим до більш видимої частини роботи: зробити представлення результатів переважно автоматичним, а не ручною рутиною щоразу.</p>
<p><strong>Результат.</strong> Операційна ефективність зросла, а команда стала продуктивнішою, оскільки рутинна координація, яка раніше потребувала постійної людської уваги, тепер значною мірою виконувалася сама. Час, який витікав у рутинні справи, повернувся до реальної роботи.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Інтегрувала загальнокорпоративну систему керування паролями, посиливши безпеку та оптимізувавши керування доступом.</title>
      <link>https://platform.engineer.company/uk/portfolio/integrated-a-company-wide-password-management-system-strengthening-90/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/integrated-a-company-wide-password-management-system-strengthening-90/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Безпека покращилася, а керування доступом стало простішим і послідовнішим у масштабах усієї організації.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Облікові дані оброблялися непослідовно — різні люди зберігали й передавали їх різними, довільними способами, — і саме ця непослідовність і була ризиком безпеки. Рідко йдеться про якийсь драматичний злам; частіше це пароль у повідомленні в чаті, спільний логін, який ніхто не змінює, повільне накопичення дрібних вразливостей.</p>
<p><strong>Завдання.</strong> Завдання полягало в тому, щоб централізувати облікові дані та зробити їх безпечними.</p>
<p><strong>Дія.</strong> Було впроваджено загальнокорпоративну систему управління паролями, завдяки якій зберігання та передача облікових даних відбувалися одним послідовним, безпечним способом замість особистих звичок кожного. Цінність загальнокорпоративного підходу саме в тому, що він не є опційним для окремих людей, — менеджер паролів, яким користується лише половина команди, майже не допомагає, бо ризик живе саме в тій половині, яка ним не користується. Тож мета полягала в тому, щоб зробити безпечний спосіб типовим — і повсюди.</p>
<p><strong>Результат.</strong> Безпека покращилася, а керування доступом стало простішим і послідовнішим у масштабах усієї організації. Коли всі облікові дані зберігаються в одному керованому місці, цілий клас дрібних, буденних вразливостей просто перестає бути можливим — а це і є більшість того, чим реальна безпека є насправді.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала багаторівневий набір автоматизованих тестів — 981 тест Go, 543 фронтендні та браузерні специфікації, 494 поведінкові тести SQL — з мутаційним тестуванням, property‑based тестами та обов&#39;язковою перевіркою доступності.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-a-layered-automated-test-suite-across-four-layers-94/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-a-layered-automated-test-suite-across-four-layers-94/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Змінювати щось структурне перестало бути страшно, а це єдине, що не дає кодовій базі такого розміру закам&#39;яніти.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформа, що тримає свою бізнес‑логіку в базі даних, має проблему з тестуванням, якої немає в більшості проєктів. Логіка написана не тією мовою, з якою добре працює тестовий фреймворк, — вона в SQL, за фасадом функцій, а SQL — це саме той код, який лишається непокритим, бо тестувати його незручно. Якщо зверху додати API на Go та фронтенд на Next.js, «важливі частини покрито» тихо перетворюється на «покрито ті частини, які було легко покрити».</p>
<p><strong>Завдання.</strong> Кожен рівень мав отримати перевірку своєї поведінки там, де ця поведінка насправді живе, а не так, щоб усе перевірялося ззовні через браузер.</p>
<p><strong>Дія.</strong> Чотири рівні отримали чотири види тестів. API на Go несе 981 тестову функцію в 310 файлах. Фронтенд несе 543 spec‑файли Vitest і Playwright, зокрема 48 end‑to‑end файлів і 30 браузерних spec‑файлів. База даних несе 494 файли поведінкових тестів — 116 876 рядків SQL, які перевіряють свої припущення через 6 654 згенеровані винятки, — тож збережена функція тестується в самій базі даних, а не крізь три рівні застосунку над нею. Над ними стоять тести, що тестують тести: мутаційне тестування Stryker навмисно ламає рядок коду й падає, коли цього ніхто не помічає, а fast‑check генерує вхідні дані, які нікому не спало на думку записати. Гейт на axe‑core вимагає нуля порушень WCAG 2.0 і 2.1 рівнів A та AA, тож доступність стає падінням білду, а не знахідкою аудиту через кілька місяців. Пороги покриття рухаються лише вгору. Увесь набір виконується як 10 задач у workflow на 612 рядків.</p>
<p><strong>Результат.</strong> Змінювати щось структурне перестало бути страшно, а це єдине, що не дає кодовій базі такого розміру закам&rsquo;яніти. Чесна ціна — це час: набір повільний, він оподатковує кожну зміну, і на такому масштабі сам потребує підтримки. Натомість він дає можливість і далі рухатися швидко, і вона варта більше, ніж ті хвилини, які він забирає.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала механізм перевірок репозиторію — 268 зареєстрованих перевірок коміту, 277 правил лінтингу та 15 власних правил ESLint — плюс 146 тестів самих перевірок, щоб стандарт тримала збірка, а не код‑рев&#39;ю.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-the-repository-s-guard-engine-of-268-checks-95/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-the-repository-s-guard-engine-of-268-checks-95/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Час код-рев&#39;ю перемістився з механіки на проєктування, бо механічні зауваження вже висловила машина ще до того, як гілку відправили в репозиторій.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Стандарти, записані в contributing‑гайді, — це побажання. З ними всі згодні, а потім настає п&rsquo;ятниця, зміна маленька, і гайд програє. Планка нульових попереджень трималася б лише тоді, коли її тримає щось інше, ніж добра воля, — а лінтери, що постачаються з кожною мовою, навіть близько не дістають до специфічних для проєкту правил, які насправді мають значення: тих, що описують, як має працювати саме ця кодова база.</p>
<p><strong>Завдання.</strong> Правила, які були важливі для проєкту, мали стати виконуваними, щоб порушення одного з них валило коміт, а не чекало на рецензента, у якого стане часу й пам&rsquo;яті це помітити.</p>
<p><strong>Дія.</strong> З цього виріс цілий рушій guard‑перевірок. Є 274 скрипти перевірок, 268 з них зареєстровані в commit‑хуках, поруч із 277 JavaScript‑лінтерами та 96 shell- і 17 Python‑валідаторами, які покривають те, щодо чого готовий інструментарій не має жодної думки: що міграцію можна відкотити, що ключ перекладу існує в обох локалях, що зареєстрований маршрут присутній в описі OpenAPI, що ніхто тихцем не додав inline‑придушення. П&rsquo;ятнадцять власних правил ESLint утримують домашні патерни в TypeScript. Одне правило варто назвати окремо: будь‑який коміт із префіксом fix: мусить нести тест, який без цього виправлення падає, — тож виправлена вада лишається виправленою. А оскільки зламана перевірка гірша за її відсутність — вона пропускає все, і ніхто про це не дізнається, — самі guard‑перевірки мають 146 власних тестів.</p>
<p><strong>Результат.</strong> Час код‑рев&rsquo;ю перемістився з механіки на проєктування, бо механічні зауваження вже висловила машина ще до того, як гілку відправили в репозиторій. Компроміс реальний, і його варто назвати вголос: комітити повільно, а погано написана guard‑перевірка справді дратує, коли її доводиться обходити. Ті 146 тестів існують саме тому, що так уже траплялося.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала рівень платежів і прав доступу — Stripe поряд із внутрішньозастосунковими покупками Apple і Google — обмеживши каталог, пошук та експорт моделлю доступу з 11 таблиць, яку перевіряє сервер.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-the-payments-and-entitlements-layer-96/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-the-payments-and-entitlements-layer-96/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Додавання вітрини тепер зачіпає бік payments і лишає гейти в спокої, а питання підтримки про чийсь доступ має одну таблицю, у яку треба зазирнути, замість…</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Продукт і вимоги</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Продуктова стратегія та вимоги</category>
      <category domain="https://platform.engineer.company/uk/services/">Проєктування та моделювання баз даних</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Гроші — це та частина платформи, до якої нікому не дозволено ставитися недбало. Підписка мусить пережити закінчення строку дії картки, повернення коштів, зміну тарифу, вебхук, що прийшов двічі, і вебхук, що прийшов не в тому порядку. Щойно оплата починає відбуватися на трьох вітринах — карткою у вебі, через Apple в одному app store, через Google в іншому, — з&rsquo;являються три різні версії того, що саме людина купила, а продуктові все одно потрібна одна відповідь на одне запитання: що цій людині дозволено робити просто зараз?</p>
<p><strong>Завдання.</strong> Приймання грошей і надання прав мали стати двома системами, а не однією, щоб додавання ще однієї вітрини не означало переписування кожного гейта в продукті.</p>
<p><strong>Дія.</strong> Stripe опрацьовує картки й підписки через 18 файлів Go, а in‑app‑покупки Apple і Google приходять через власну перевірку квитанцій. Усі три сходяться в схемі payments із 9 таблиць і 34 функцій — і на цьому спиняються. Те, про що продукт запитує насправді, — це окрема схема access, 11 таблиць і 34 функції, яка відповідає на «чи можна цьому обліковому запису зробити це?», не знаючи й не цікавлячись, яка саме вітрина за це заплатила. Ця відповідь закриває каталог компаній, пошук і експорт даних, і вона перевіряється сервером повторно на кожен запит, бо прихована кнопка — це ввічливість, а не механізм контролю.</p>
<p><strong>Результат.</strong> Додавання вітрини тепер зачіпає бік payments і лишає гейти в спокої, а питання підтримки про чийсь доступ має одну таблицю, у яку треба зазирнути, замість трьох. Ціна — це дві схеми там, де меншому продуктові вистачило б однієї, плюс перевірка прав на тих запитах, які інакше були б безкоштовними.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Перенесла повільну роботу зі шляху запиту в чергу завдань River — 15 модулів воркерів, 8 запланованих задач та 20 завдань pg_cron — щоб запит повертався, поки робота за ним триває.</title>
      <link>https://platform.engineer.company/uk/portfolio/moved-slow-work-onto-a-river-job-queue-97/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/moved-slow-work-onto-a-river-job-queue-97/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Запити повертаються швидко, а повільна робота все одно доходить до кінця — з повторними спробами й видимою історією, коли не доходить.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Проєктування та моделювання баз даних</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Частині роботи взагалі нема чого відбуватися, поки користувач чекає. Надіслати лист, перебудувати пошуковий індекс, згенерувати документ, перерахувати рейтинги — якщо робити будь‑що з цього всередині запиту, користувач дивиться на спінер заради того, чого ніколи не просив показувати. А якщо робити це в горутині, воно зникає тієї ж миті, коли процес перезапускається, — а він перезапуститься, посеред розгортання, не лишивши й сліду про те, що це взагалі мало статися.</p>
<p><strong>Завдання.</strong> Фоновій роботі потрібне було довговічне місце для життя: черга, яка переживає перезапуск, повторює невдалу спробу і в яку можна зазирнути, коли щось не сталося.</p>
<p><strong>Дія.</strong> Вибір упав на River — переважно тому, що він тримає свою чергу в PostgreSQL: база даних і так є авторитетним джерелом даних, тож задача і рядки, яких вона торкається, комітяться або відкочуються разом, і немає другого шматка інфраструктури, який треба запускати й тримати в голові. За ним стоять 15 модулів‑воркерів і 8 запланованих задач. Нижче 20 задач pg_cron виконують ту підтримку, яку базі даних зручніше робити самій: підчищати партиції, ротувати солі, оновлювати агрегати. Усе, що було достатньо повільним, щоб це помітили, перенесено зі шляху запиту на одне з цих двох.</p>
<p><strong>Результат.</strong> Запити повертаються швидко, а повільна робота все одно доходить до кінця — з повторними спробами й видимою історією, коли не доходить. Тримати чергу в Postgres, а не у виділеному брокері, — це свідоме обмеження: воно не масштабуватиметься вічно, і на якомусь обсязі стає неправильною відповіддю. Для платформи, вузьким місцем якої і так є база даних, на одну рухому частину менше виявилося вартіснішим за запас, яким однаково не скористалися б.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала власний моніторинг помилок та трасування OpenTelemetry замість покупних — очищення payload, виявлення сплесків і регресій, символікацію та синтетичний heartbeat — за 11 операторськими поданнями.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-first-party-error-monitoring-and-tracing-98/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-first-party-error-monitoring-and-tracing-98/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Помилки перетворюються на чергу, яку хтось може розібрати, а регресія оголошує про себе сама, замість того щоб її знайшов користувач.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Різниця між платформою, яка піднята, і платформою, яка працює, полягає в тому, чи хтось про це дізнається. Помилка, на яку користувач наштовхнувся об одинадцятій вечора, на сторінці, яку ніхто не тестує, лишається невидимою, доки щось не піде й не збере її. Звична відповідь — купити хостований трекер помилок, і це хороша відповідь, — а ще вона означає, що власні помилки платформи, стектрейси й контекст користувача їдуть до третьої сторони.</p>
<p><strong>Завдання.</strong> Помилки й трейси треба було збирати, групувати й робити придатними до дії так, щоб нутрощі платформи не залишали платформу.</p>
<p><strong>Дія.</strong> Побудовано дві частини. OpenTelemetry відповідає за трасування через OTLP, тож повільний запит можна простежити наскрізь через фронтенд, API та базу даних, а не здогадуватися про нього. Поруч стоїть власний пайплайн помилок — сервіс errmon і сервіс ingest, — який санітизує payload перед збереженням, групує помилки у повторювані проблеми замість плаского списку, виявляє сплески й регресії з періодом очікування, щоб один невдалий деплой не смикнув когось сорок разів, перетворює мінімізовані стектрейси фронтенду назад на читабельний код і запускає синтетичний heartbeat, щоб довести, що сам пайплайн живий. Усе це осідає в базі даних як події помилок, групи помилок, inbox, латентність API та семпли стеків, а назовні виходить через 11 операторських подань, зокрема одне для service level objectives.</p>
<p><strong>Результат.</strong> Помилки перетворюються на чергу, яку хтось може розібрати, а регресія оголошує про себе сама, замість того щоб її знайшов користувач. Побудувати замість купити коштувало реального часу й означає, що це ще одна річ на підтримці, — куплений трекер працював би вже того ж дня по обіді. Натомість це дало те, що нічого чутливого не виїжджає назовні, а правила сповіщень підігнані під цю платформу, а не під якусь загальну.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Тримала схему узгодженою впродовж 1 022 міграцій за допомогою перевірки CI, яка збирає базу даних обома шляхами — чиста інсталяція та інсталяція плюс усі міграції — і падає, коли вони розходяться.</title>
      <link>https://platform.engineer.company/uk/portfolio/kept-the-schema-honest-across-1022-migrations-99/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/kept-the-schema-honest-across-1022-migrations-99/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Свіже середовище й довговічне — це та сама база даних, і це перевірено, а не припущено. Ціна лягає на того, хто пише міграцію: вона має працювати у відтворенні…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Data Governance</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">PostgreSQL</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Міграції та модернізація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Адміністрування баз даних (DBA)</category>
      <category domain="https://platform.engineer.company/uk/services/">Міграція та модернізація баз даних</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> У більшості проєктів схема описана двічі: один раз початковим налаштуванням, яке будує її з нуля, і другий раз накопиченими міграціями, які її виростили. Обидва описи мають давати ту саму базу даних. Ніщо не перевіряє, чи це справді так, тож вони розходяться — і розходження лишається невидимим, доки свіже середовище не почне поводитися інакше, ніж продакшн, зазвичай у найгірший момент.</p>
<p><strong>Завдання.</strong> Два описи мали бути доказово ідентичними, автоматично, а не такими, у чию ідентичність час від часу вірять.</p>
<p><strong>Дія.</strong> База даних версіонована як 1 022 міграції, пронумеровані від 036 до 1102, і дисципліна впорядкування навколо них нудна й не підлягає обговоренню. Тримає її CI‑задача, яка на кожну зміну збирає базу даних двічі: один раз зі свіжої початкової схеми, другий — із початкової схеми плюс кожна міграція, відтворена по черзі, — а потім порівнює обидві. Не лише структуру, що є легшою половиною, а й засіяні дані теж, бо міграція, яка неправильно заповнює довідкову таблицю, шкодить рівно так само, як та, що забула колонку, — а в diff схеми потрапляє тільки одна з них. Будь‑яка розбіжність валить білд із виведеною різницею.</p>
<p><strong>Результат.</strong> Свіже середовище й довговічне — це та сама база даних, і це перевірено, а не припущено. Ціна лягає на того, хто пише міграцію: вона має працювати у відтворенні й має працювати з холодного старту, а це більше роздумів, ніж зазвичай дістається швидкому ALTER. У цьому й суть — альтернатива полягає в тому, щоб дізнатися про це під час відновлення, коли відповідь важлива, а часу її вигадувати вже немає.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала засоби протидії зловживанням за принципом fail‑closed — 22 обмежувачі частоти на Redis, Cloudflare Turnstile, ідемпотентність запитів та прив&#39;язку до origin — щоб платформа відсікала ботів і напливи, а не довіряла тим, хто її викликає.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-fail-closed-abuse-controls-and-rate-limiting-100/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-fail-closed-abuse-controls-and-rate-limiting-100/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Зловживання стає дорогим для того, хто зловживає, і дешевим для платформи, а збій у власному сховищі обмежувача деградує до відмови, а не до відчинених дверей.</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Публічний каталог компаній і фахівців стає мішенню того самого дня, коли виходить у світ. Скраперам потрібні дані, спам‑акаунтам — охоплення, а ендпоінтом, обслуговування якого коштує платформі реальних грошей — пошук, експорт, будь‑що, що торкається зовнішнього API, — варто зловживати вже тому, що викликати його безкоштовно. Нічого з цього не є злим наміром, спрямованим саме проти цієї платформи; це фонова погода відкритого інтернету.</p>
<p><strong>Завдання.</strong> Дорогим і вразливим до зловживань шляхам потрібні були обмеження, які тримають під тиском, зокрема під тиском недоступності власної залежності обмежувача.</p>
<p><strong>Дія.</strong> Обмежувачів частоти запитів тут 22, і кожен сконструйований під той шлях, який він захищає, замість одного глобального ліміту, бо спроба входу, пошук і масовий експорт стають зловживанням на кардинально різних швидкостях. Стан живе в Redis, тож ліміт спільний для всіх інстансів, а не існує окремо в кожному процесі, звідки його тривіально обійти. Важливе рішення — що відбувається, коли Redis недоступний: обмежувачі закриваються (fail closed). Трафік відхиляється, а не пропускається помахом руки, — це менш зручна відповідь і єдина, яку можна відстояти. Навколо них стоять Cloudflare Turnstile на шляхах, які варто перевіряти челенджем, 351 рядок мідлвару ідемпотентності, щоб повторений запис не перетворився на два, origin‑lock, що відкидає запити, які прийшли не через парадні двері, і власний челендж на самому каталозі.</p>
<p><strong>Результат.</strong> Зловживання стає дорогим для того, хто зловживає, і дешевим для платформи, а збій у власному сховищі обмежувача деградує до відмови, а не до відчинених дверей. Закриватися при збої справді означає, що проблема з Redis стає проблемою, видимою користувачам, — і це прийнято свідомо, бо альтернатива в тому, що проблема з Redis стає проблемою з рахунками.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала наскрізний процес заявок на володіння компанією — користувач заявляє права на компанію, адміністратор ухвалює рішення, а схвалення переписує граф авторизації, який визначає, кому що дозволено редагувати.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-company-ownership-claims-end-to-end-103/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-company-ownership-claims-end-to-end-103/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Компанії можуть перебрати й виправити власні записи без того, щоб хтось редагував базу даних вручну, а кожне надання повноважень має названого схвалювача й…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Full‑Stack розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Продукт і вимоги</category>
      <category domain="https://platform.engineer.company/uk/services/">Full‑Stack продуктова розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Продуктова стратегія та вимоги</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Каталог, наповнений із публічних джерел, має структурну проблему: компанії опинилися в ньому не з власної волі. Рано чи пізно приходить хтось із такої компанії й хоче виправити її запис — а між цією людиною й цим записом немає жодного зв&rsquo;язку, є лише твердження, що зв&rsquo;язок існує. Надати права надто легко — і вашу сторінку редагує конкурент. Надати надто повільно — і каталог лишається неправильним.</p>
<p><strong>Завдання.</strong> Мав існувати шлях від «це моя компанія» до справжніх повноважень над записом — з людським рішенням посередині й слідом позаду.</p>
<p><strong>Дія.</strong> Заявки на володіння побудовано наскрізно — 108 комітів і обидва застосунки. Користувач подає заявку з доказами; вона потрапляє в чергу в бек‑офісі; адміністратор розглядає її та схвалює або відхиляє з причиною, яка повертається заявникові. Найцікавіше — що саме робить схвалення: це не прапорець у рядку. Схвалення переписує граф авторизації, тож обліковий запис отримує реальний зв&rsquo;язок з організацією — той самий зв&rsquo;язок, до якого вже звертається кожна перевірка прав на платформі. Воротами є рішення людини, а не гілка в коді, і жодній функції не довелося дізнаватися про заявки, щоб ці ворота поважати.</p>
<p><strong>Результат.</strong> Компанії можуть перебрати й виправити власні записи без того, щоб хтось редагував базу даних вручну, а кожне надання повноважень має названого схвалювача й прикріплену причину. Людський розгляд є вузьким місцем за задумом; автоматична перевірка доменного імені була б швидшою — і помилялася б саме в тих випадках, які важать найбільше.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Запровадила безперервну програму безпеки — сканування коду, DAST, перевірки залежностей і вразливостей, генерацію SBOM, пошук секретів та actions, закріплені за SHA, — поряд із 21 письмовим аудитом безпеки.</title>
      <link>https://platform.engineer.company/uk/portfolio/established-a-continuous-security-programme-104/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/established-a-continuous-security-programme-104/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Вразливість, оприлюднена в upstream, з&#39;являється як зламана збірка, а не як новина. Реальна ціна — це обсяг знахідок: сканер, який повідомляє про все, привчає…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Робота з безпеки всередині застосунку — Content‑Security‑Policy, ролі бази даних із мінімальними привілеями, повторні перевірки прав — захищає платформу під час виконання. Але вона нічого не каже про те, що саме постачається: чи не підхопила залежність відому вразливість минулого вівторка, чи не потрапили в коміт облікові дані, які потім відкотили, і чи не перетворилася стороння action, закріплена за тегом, непомітно на інший код.</p>
<p><strong>Завдання.</strong> Безпека ланцюга постачання та коду мала бути безперервною й автоматизованою, щоб її стан був результатом збірки, а не чиєюсь думкою.</p>
<p><strong>Дія.</strong> Статичний аналіз виконує CodeQL, динамічне тестування проти живого інстансу — ZAP, а залежності Go перевіряє govulncheck. Software bill of materials (SBOM) генерується на кожній збірці за допомогою Anchore та Syft, тож те, що поїхало в продакшн, відоме, а не реконструюється потім. Gitleaks сканує історію на облікові дані. Кожна стороння GitHub Action закріплена за хешем коміту, а не за тегом, — це той неефектний контроль, який не дає перемістити тег у вас під ногами. Dependabot стежить за 6 екосистемами. Поряд з автоматизацією стоїть 21 письмовий аудит безпеки, зокрема модель загроз і оцінка за посібником з тестування OWASP, — адже сканери знаходять класи проблем, які хтось уже описав, а модель загроз — це те місце, де називають проблеми, специфічні саме для цієї платформи.</p>
<p><strong>Результат.</strong> Вразливість, оприлюднена в upstream, з&rsquo;являється як зламана збірка, а не як новина. Реальна ціна — це обсяг знахідок: сканер, який повідомляє про все, привчає людей себе ігнорувати, і щоб сигнал лишався придатним до використання, потрібне постійне сортування знахідок, а не одноразове налаштування.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала власну інфраструктуру компанії як 19 плейбуків Ansible і 34 ролі на 12 065 рядках YAML, що зводять живий хост до оголошеного стану, де кожен play ідемпотентний.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-the-companys-infrastructure-as-code-108/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-the-companys-infrastructure-as-code-108/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Господарство відтворюється з репозиторію, а ті його частини, які були істинними лише тому, що хтось їх пам&#39;ятав, тепер є твердженнями, що валять прогін.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Engineer ApS керує власним господарством — вебприсутність, git‑форджа, база даних, резервні копії, поштовий транспорт і DNS, — і не було нікого, кому передати експлуатацію. Компанія з однієї людини має ті самі режими відмови, що й велика, і жодного резерву, через що звична відповідь — людина, яка пам&rsquo;ятає, як налаштовано хост, — є найменш доступним варіантом.</p>
<p><strong>Завдання.</strong> Усе господарство мало бути описане в репозиторії, а не в голові, і описане у формі, що зводить реальний хост до заданого стану, а не документує його.</p>
<p><strong>Дія.</strong> З цього виросли 19 плейбуків і 34 ролі на 12 065 рядках YAML. Форма важить більше за розмір. Композиція є даними, а не прапорцями: хост належить до групи рівня, чиї змінні оголошують, які ролі він виконує, тож розгортання без жодних аргументів зводить кожен хост до оголошеного стану. Ідемпотентність є контрактом, а не прагненням — зведений хост звітує про нуль змін, і п&rsquo;єса, яка не може цього сказати, не завершена. Чотири простори імен команд тримають обіцянки нарізно: перевірка, що не торкається жодного хоста, звіти, які читають хост і ніколи його не змінюють, розгортання, що змінює хост до відповідності репозиторію, і верифікація, що змінює хост навмисно й повертає вердикт.</p>
<p><strong>Результат.</strong> Господарство відтворюється з репозиторію, а ті його частини, які були істинними лише тому, що хтось їх пам&rsquo;ятав, тепер є твердженнями, що валять прогін. Ціна реальна: кожна зміна повільніша, ніж редагування файлу на сервері, а зведення, застосоване наполовину, гірше за те, що відмовляється, — саме тому попереду згодом додано попередню перевірочну п&rsquo;єсу. Цей обмін зроблено свідомо, і він себе виправдав.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Втримала всю компанію на одному хості з 512 МБ і одним ядром — git‑форж, вебсервер для семи доменів, Tor, два сервери альтернативних протоколів, резервні копії та блокування вторгнень — розглядаючи 464 МБ доступної пам&#39;яті як зобов&#39;язальне архітектурне обмеження.</title>
      <link>https://platform.engineer.company/uk/portfolio/ran-the-whole-company-on-one-512mb-host-109/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/ran-the-whole-company-on-one-512mb-host-109/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Уся компанія працює на машині, що коштує на місяць менше за обід, і задум кращий саме завдяки цій дисципліні, а не просто дешевший.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура платформи</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Робочий хост компанії — це одноядерний хмарний примірник із 512 МБ пам&rsquo;яті та 10 ГБ диска, з яких придатними до вжитку є близько 464 МБ. Усе, що бізнес виконує публічно, стоїть на ньому: вебсервер, що термінує TLS для семи доменів, git‑форджа, onion‑служба Tor, сервер Gemini, сервер Gopher, зашифровані резервні копії та блокування вторгнень. Звична реакція на цей перелік — придбати більшу машину.</p>
<p><strong>Завдання.</strong> Обмеження мало розглядатися як архітектурний вхідний параметр, а не як проблема, на яку витрачають гроші, бо чесне питання полягало не в тому, чи спрацювала б більша машина, а в тому, чи потрібна вона задуму.</p>
<p><strong>Дія.</strong> Пам&rsquo;ять стала аргументом, що вирішував суперечки. Немає ані агента моніторингу, ані конвеєра метрик, ані панелі — звітність є витягуванням, сім команд, що читають хост і формують Markdown, нічого не змінюючи й запускаючись лише на прохання. Наглядачем є systemd, а не другий менеджер процесів, накладений поверх нього, а контейнерна площина — це модулі Quadlet під тим самим наглядачем, а не демон із власним. Платформи з вебпанелями відкинуто ще на етапі задуму з тієї самої причини. Коли постало питання, чи витримає хост onion‑службу, відповідь надійшла з доби вимірюваних зразків, а не з думки: доступна пам&rsquo;ять ніколи не опускалася нижче приблизно 310 МБ із 464, підкачування трималося на 2,6 відсотка, а процесор був вільним на 99,7 відсотка.</p>
<p><strong>Результат.</strong> Уся компанія працює на машині, що коштує на місяць менше за обід, і задум кращий саме завдяки цій дисципліні, а не просто дешевший. Коштувало це запасу для будь‑чого недбалого — пошти навмисно немає на цій машині взагалі — її написано як риштування для встановлення, що чекає на власний хост, бо поштовий сервер потребує запасу, який ця машина вже витратила, і це записано, а не виявлено згодом.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Знайшла й закрила три захисти SSH від перебору, які ніколи не працювали: тюрму блокування, що стежила за портом 22, поки демон слухав 1986, обмеження швидкості, затінене ширшим правилом над ним, і дію блокування, чий бінарний файл ніколи не знаходився, тож жодне блокування ніколи не застосовувалося.</title>
      <link>https://platform.engineer.company/uk/portfolio/found-three-ssh-brute-force-protections-that-never-worked-110/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/found-three-ssh-brute-force-protections-that-never-worked-110/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Три види захисту, що не спрацювали жодного разу, тепер працюють, а клас дефектів, до якого вони належать, — засіб контролю, чий режим відмови полягає в тому,…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Огляд захищеності робочого хоста в серпні 2026 року поставив питання, на яке зазвичай дають упевнену відповідь: чи працює захист від перебору паролів SSH. Усі три засоби були налаштовані, усі три з&rsquo;являлися в кожному звіті, який хтось переглядав, і всі три були бездіяльними від дня створення хоста.</p>
<p><strong>Завдання.</strong> Засоби контролю треба було перевірити проти того, що ядро насправді робить із пакетом, а не проти файлів налаштувань, які описують, що з ним мало б статися.</p>
<p><strong>Дія.</strong> Читання налаштувань підтвердило б хибну відповідь тричі, тож огляд натомість читав систему в роботі. В&rsquo;язниця блокування вторгнень стежила за портом 22, тоді як демона було перенесено на 1986 під час початкового посилення захисту — кожне блокування, яке вона записувала, називало порт, на якому ніщо не слухало. Обмеження частоти на брандмауері було гіршим у тонший спосіб: правило існувало, і воно стояло нижче ширшого правила, що збігалося першим. Користувацькі правила брандмауера обчислюються згори вниз, і перемагає перший збіг, тож широкий дозвіл над обмеженням частоти робить це обмеження мертвим кодом, який усе одно друкується в кожному переліку стану. Третій засіб був найтихішим із них: дія блокування викликає двійковий файл фільтра пакетів, який система пакунків лише рекомендує, а не вимагає, тож на хості без нього в&rsquo;язниця запускається, рахує та вирішує, а потім зазнає невдачі в ту єдину мить, коли намагається заблокувати. Усі три виправлення були малими. З цього вийшло не виправлення, а два правила, що тепер керують репозиторієм: засіб безпеки дістає твердження, а не коментар, і брандмауер перевіряється за розташуванням правила, а не за його наявністю.</p>
<p><strong>Результат.</strong> Три види захисту, що не спрацювали жодного разу, тепер працюють, а клас дефектів, до якого вони належать, — засіб контролю, чий режим відмови полягає в тому, що він і далі звітує про справність, — це саме той клас, який тепер покликані ловити перевірки платформи. Усі три були бездіяльними від початкового розгортання. Усі три друкували «справний» скрізь, куди хтось дивився, і саме тому вони протривали.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Загартувала SSH до 24 стверджених директив із тристадійною перевіркою — файл‑кандидат, зібрана конфігурація, а тоді власне зчитування демона — після того, як зчитування спіймало робочий сервер на мовчазному перевизначенні двох із двадцяти чотирьох.</title>
      <link>https://platform.engineer.company/uk/portfolio/hardened-ssh-with-three-stage-validation-111/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/hardened-ssh-with-three-stage-validation-111/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Стан захисту SSH тепер є відповіддю демона, а не заявою репозиторію, і різниця не теоретична — на момент написання перевірки вона вже сягала двох параметрів.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> SSH є єдиним інтерактивним шляхом до хоста компанії, і його налаштування пише роль автоматизації, яка місяцями працювала чисто. Звіт про доступ у вересні 2026 року прочитав власні розв&rsquo;язані параметри демона й виявив, що два з них розходяться з тим, що роль писала за кожного окремого зведення.</p>
<p><strong>Завдання.</strong> Посилення захисту мало стати тим, що підтверджує демон, а не тим, що стверджує репозиторій, бо розрив між цими двома був відкритим уже місяцями, і ніхто цього не помічав.</p>
<p><strong>Дія.</strong> Причиною був порядок налаштувань. Операційна система постачає власні усталені значення розкоментованими, вище того місця, куди потрапляє файл‑вставка, і для двох згаданих параметрів перемагає перше входження. Виправленням став префікс імені файлу, що сортується попереду постачальницького, — це зміна завбільшки в один символ і саме той різновид, що лишається зламаним, бо нікому не спадає на думку подивитися. Важливіше те, що збудовано навколо неї: три етапи перевірки за кожного зведення. Файл‑кандидат перевіряється на синтаксис перед встановленням, тож хибне налаштування ніколи не дістається хоста. Зібране налаштування перевіряється після встановлення. Потім зчитується власний розв&rsquo;язаний вивід демона, і проти нього стверджується 24 директиви, тож параметр, який записано, але перекрито, валить прогін. Дві директиви навмисно залишено осторонь, обидві тому, що демон їх більше не реалізує, а записувати їх означало б лише вдавати ретельність.</p>
<p><strong>Результат.</strong> Стан захисту SSH тепер є відповіддю демона, а не заявою репозиторію, і різниця не теоретична — на момент написання перевірки вона вже сягала двох параметрів. Зведення, яке не бачить, чи набув засіб контролю чинності, його не перевірило, а пошук директиви доводить лише те, що її було записано.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Довела весь шлях блокування вторгнень на кожному запуску загартування, блокуючи зарезервовану тестову адресу, читаючи отримане правило ядра й знімаючи блокування у гарантованому блоці прибирання, щоб тюрма, яка перестала працювати, валила запуск, а не звітувала про здоров&#39;я.</title>
      <link>https://platform.engineer.company/uk/portfolio/proved-the-intrusion-banning-path-on-every-converge-112/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/proved-the-intrusion-banning-path-on-every-converge-112/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Шлях блокування, який перестає працювати, тепер валить зведення замість того, щоб і далі звітувати про справність, — і це єдина властивість, яка мала значення.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Службу блокування вторгнень уже спіймали на блокуванні порту, на якому демон SSH не слухав. Виправлення порту закрило той окремий випадок. Воно нічого не зробило з причиною, чому хиба протривала так довго, а вона в тому, що шлях блокування не має видимої відмови: служба працює, в&rsquo;язниця перелічена як активна, і ніде нічого не каже, чи взагалі якесь блокування дістається ядра.</p>
<p><strong>Завдання.</strong> Шлях блокування мав випробовуватися за кожного зведення, проти живого набору правил, а не виводитися з того, що служба піднята.</p>
<p><strong>Дія.</strong> Зведення тепер блокує адресу з блоку, який стандарти резервують для документації, зчитує з ядра отримане правило в фільтрі пакетів і розблоковує її в блоці прибирання, що виконується незалежно від того, чи перевірка пройшла, чи ні. Зарезервований діапазон є несучим вибором — тестова адреса не належить нікому, тож випадкове блокування, що переживе невдалий прогін, не здатне відрізати справжню мережу. Зчитування з ядра є другою половиною: власний вивід стану служби повідомив би про успіх блокування, яке не створило жодного правила, а це і є та сама відмова, яку перевіряють. Поряд із цим бекенд блокування закріплено, а не залишено на визначення службою, а бекенд журналу встановлено на визначення, бо операційна система не постачає традиційного журналу автентифікації, і хибний вибір відмовляє мовчки, стежачи за файлом, який ніколи не з&rsquo;явиться.</p>
<p><strong>Результат.</strong> Шлях блокування, який перестає працювати, тепер валить зведення замість того, щоб і далі звітувати про справність, — і це єдина властивість, яка мала значення. Це коштує кількох секунд на кожному прогоні й щоразу записує та відкликає правило брандмауера проти робочої системи, що є справжнім втручанням у живу систему і було прийняте на тій підставі, що альтернативу вже було доведено гіршою.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Перевірила правила фаєрвола за позицією, а не за наявністю, читаючи пронумерований перелік правил і живий ланцюг фільтрації пакетів, бо правило, яке існує, — це не правило, до якого доходить хоч один пакет.</title>
      <link>https://platform.engineer.company/uk/portfolio/verified-firewall-rules-by-position-113/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/verified-firewall-rules-by-position-113/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Стан брандмауера тепер перевіряється так, як його переживає пакет. Найкориснішим наслідком була не перевірка, а те, що вона виявила про звітність, яка їй…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Перелік стану брандмауера показує набір правил. Фільтр пакетів обчислює впорядкований список і спиняється на першому збігу. Це різні речі, і різниця невидима в кожному інструменті, що друкує зведення, — саме так хост цілий рік працював з обмеженням частоти, до якого не дійшов жоден пакет, бо воно стояло нижче ширшого правила, що збігалося першим.</p>
<p><strong>Завдання.</strong> Перевірка брандмауера мала читати розташування, а не належність, бо наявність уже було продемонстровано як таку, що не доводить нічого.</p>
<p><strong>Дія.</strong> Перевірки тепер читають нумерований перелік правил і живий ланцюжок фільтра та стверджують проти порядку. На кожен порт існує рівно одне правило й завжди з протоколом, бо правило без нього мовчки розширює поверхню. Порт SSH несе обмеження частоти й ніколи дозвіл поруч, бо дозвіл над обмеженням є саме тим затіненням, яке було виявлено. Оголошена публічна поверхня є коротким переліком із п&rsquo;яти портів, який стверджується цілком, а не перевіряється поштучно, тож порт, що з&rsquo;являється без оголошення, валить перевірку, а не лишається поміченим. Звіт з безпеки подає правила в порядку збігу з попередженням на початку розділу, яке пояснює, як його читати, бо наступна людина, що відкриє той файл, інакше прочитає набір.</p>
<p><strong>Результат.</strong> Стан брандмауера тепер перевіряється так, як його переживає пакет. Найкориснішим наслідком була не перевірка, а те, що вона виявила про звітність, яка їй передувала: кожен причетний інструмент цілий рік друкував обмеження частоти, і друкував правильно, і жодного з них не було спитано про єдине питання, що мало значення.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала зашифровані резервні копії поза хостом на restic із обрізанням за терміном зберігання, перевіркою цілісності та щомісячним автоматизованим навчальним відновленням, а тоді проаудитувала позицію відновлення й записала прогалини, замість лишати їх на знаходження під час інциденту.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-encrypted-backups-with-a-monthly-restore-drill-114/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-encrypted-backups-with-a-monthly-restore-drill-114/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Компанія може втратити хост і повернути свої дані, і це речення спирається на відновлення, що відбулося минулого місяця, а не на резервну копію, зроблену…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Резервне копіювання та відновлення</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Усе, що зберігає компанія — git‑репозиторії, база даних, сайт, — стояло на одному хмарному примірнику, чий провайдерський знімок був усією позицією відновлення. Провайдерський знімок — добра річ, щоб її мати, і погана, щоб на неї покладатися: він лежить у тому самому обліковому записі, що й машина, яку він захищає, він не зашифрований тут нікому відомим ключем, і ніхто ніколи з нього не відновлювався.</p>
<p><strong>Завдання.</strong> Резервні копії мали бути зашифрованими, поза хостом, підрізаними за політикою зберігання і — та частина, яку зазвичай пропускають — справді відновлюваними, за розкладом, без того, щоб хтось про це пам&rsquo;ятав.</p>
<p><strong>Дія.</strong> Резервне копіювання виконується за таймером systemd: дамп бази даних, де така існує, потім зашифрований знімок із усуненням дублікатів до сховища в іншого провайдера через SFTP, потім підрізання за політикою зберігання, потім перевірка цілісності. Перемикач мертвої руки пінгується лише в разі успіху, і саме ця відмінність робить його тривогою, а не журналом — невдалий прогін не каже нічого, а сказати нічого і є тим, що здіймає тривогу. Окремо щомісяця виконується навчання з відновлення: воно витягує відомий файл із репозиторію та порівнює його, тож перевіряється саме відновлення, а не резервне копіювання. Парольну фразу записано у файл, який читають модулі, а не передано через середовище, бо наглядач обробляє екранування у значеннях середовища, і парольна фраза, що містить зворотну похилу риску, мовчки відрізнялася б від тієї, що створила репозиторій. Згодом позицію відновлення було перевірено й описано, а прогалини, що лишилися, названо в документі, а не залишено на виявлення під час інциденту.</p>
<p><strong>Результат.</strong> Компанія може втратити хост і повернути свої дані, і це речення спирається на відновлення, що відбулося минулого місяця, а не на резервну копію, зроблену минулої ночі. Найціннішим виходом перевірки був перелік того, що досі не покрито, — саме та частина, про яку зелений звіт про резервне копіювання структурно не здатен нікому сказати.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала моніторинг із сигналом живучості, який пінгує лише поки пам&#39;ять і диск здорові, тож ослаблений хост здіймає тривогу, замовкаючи, — і спіймала шість імен змінних, що казали «free», де перевірка правильно вимірювала «available», на порядок різні на машині з 464 МБ.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-dead-mans-switch-monitoring-115/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-dead-mans-switch-monitoring-115/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Хост тепер має тривогу, чий режим відмови — спрацювати, а іменування, яке її знищило б, виправлено.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Хост на 464 МБ, що несе форджу, базу даних і вебсервер, має два реалістичні способи померти: у нього закінчується пам&rsquo;ять або закінчується диск. Жоден із них себе не оголошує. Обидва цілком передбачувані за кілька годин наперед, якщо хтось дивиться, а не дивився ніхто.</p>
<p><strong>Завдання.</strong> Хостові потрібна була тривога, що працює тоді, коли не працює хост, — а це виключає будь‑що, що має надіслати повідомлення в мить відмови.</p>
<p><strong>Дія.</strong> Відповіддю є перемикач мертвої руки на таймері. Що п&rsquo;ятнадцять хвилин із розкидом невеликий скрипт вимірює доступну пам&rsquo;ять і вільний диск і пінгує зовнішню службу лише тоді, коли обидва вище своїх порогів. Тиша є сигналом тривоги. Машина, у якої закінчилася пам&rsquo;ять, зникла мережа або яка перестала завантажуватися, дає точнісінько той самий сигнал, що й несправна, — і це правильна поведінка та причина, чому обрано цю форму, а не агента, що звітує про стан. Вимірюється доступна пам&rsquo;ять, а не вільна, і саме ця відмінність обернулася найповчальнішою частиною роботи: скрипт увесь час читав правильний стовпчик, тоді як шість імен змінних довкола нього казали «вільна». На справному Linux‑хості вільної пам&rsquo;яті майже нуль, бо ядро використовує простій пам&rsquo;яті під кеш, тож читач, який звірив би ці імена з порогом у десять відсотків, побачив би дванадцять мегабайтів вільними на машині з 464 МБ, дійшов би висновку, що перевірка зламана, і виправив би її зміною завбільшки в один символ, яка перетворює робочу тривогу на таку, що постійно порушує поріг і яку глушать протягом тижня.</p>
<p><strong>Результат.</strong> Хост тепер має тривогу, чий режим відмови — спрацювати, а іменування, яке її знищило б, виправлено. Справжнє обмеження перемикача зазначено в його власній документації: він доводить, що машина справна, а не що сайт обслуговує запити, і це різні питання.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Змусила check mode казати правду на всій платформі, знайшовши шість зондів, які ухвалювали рішення за значенням, якого хост ніколи не давав, бо модуль command в Ansible звітує про успіх під --check, повністю пропускаючи саму команду.</title>
      <link>https://platform.engineer.company/uk/portfolio/made-ansible-check-mode-tell-the-truth-116/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/made-ansible-check-mode-tell-the-truth-116/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Пробний прогін тепер або щось вимірює, або каже, що не виміряв, і жодне з цих двох не є тим третім варіантом, який він мав раніше.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Пробний прогін проти робочої системи має бути безпечним способом дізнатися, що зробить зміна. У вересні 2026 року пробний прогін завалився на твердженні, яке просто хибно описувало хост, і порадив операторові встановити прапорець, що послабив би пісочницю безпеки. Пробний прогін не читав хоста. Він прочитав значення, якого хост ніколи не давав, і зробив із нього висновок.</p>
<p><strong>Завдання.</strong> Кожен зонд, чий результат живить рішення, мав стати чесним у режимі перевірки, а ті, які такими стати не могли, мали сказати про це вголос, а не мовчати.</p>
<p><strong>Дія.</strong> Причиною є властивість інструмента, яка задокументована і яку легко забути: модуль команд не виконується в режимі перевірки, і те, що він реєструє, не є порожнім результатом — це успіх із порожнім виводом. Будь‑яка умова, що читає той реєстр, отже, вирішує на підставі значення, яке ніколи не вимірювалося, і вирішує в той бік, куди випадково вказує її власна логіка. Обхід усіх зареєстрованих зондів виявив шість таких, і кожен брехав по‑своєму: один звітував, що наглядач приймає кожну директиву модуля, жодного разу того наглядача не спитавши, інший звітував, що робити нічого, на хості з вимкненим брандмауером. Кожному надано одну з двох форм. Зонд, що читає наперед наявний стан, якого прогін не торкався, позначено на виконання навіть у режимі перевірки. Зонд, який виконатися не може, пропускається, і повідомлення називає, що саме не було перевірено, — бо тиша в журналі прогону читається точнісінько як успіх.</p>
<p><strong>Результат.</strong> Пробний прогін тепер або щось вимірює, або каже, що не виміряв, і жодне з цих двох не є тим третім варіантом, який він мав раніше. Загальне правило потрапило до посібника з розробки тією самою зміною: режим перевірки не має права брехати, а зонд, який не бачить, зобов&rsquo;язаний оголосити свою сліпоту, а не виводити з неї вердикт.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Додала передпольотний play, який виконує той самий код, що й зведення, проти локальних секретів оператора приблизно за секунду, після того як наполовину застосований продакшн‑запуск загинув на дев&#39;ятому завданні з уже записаними на живий хост налаштуваннями swap.</title>
      <link>https://platform.engineer.company/uk/portfolio/added-a-preflight-play-for-secrets-117/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/added-a-preflight-play-for-secrets-117/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Секрет, який не розв&#39;язується, тепер коштує двосекундної відмови на ноутбуці замість частково застосованої зміни на живому сервері.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Експлуатаційні секрети щойно було розділено так, щоб кожен хост ніс власний репозиторій резервних копій, парольну фразу та перемикач тривоги. Код репозиторію був правильним. Зашифроване сховище оператора досі тримало попереднє значення для одного хоста, і ніщо не могло побачити цієї розбіжності, бо сховище навмисно є локальним для машини оператора й невидимим для власної перевірки якості репозиторію.</p>
<p><strong>Завдання.</strong> Цьому класові відмов потрібне було місце, де він міг би відмовляти дешево, бо він щойно відмовив дорого.</p>
<p><strong>Дія.</strong> Перше зведення після зміни під&rsquo;єдналося до живого хоста, виконало вісім завдань і відмовилося на дев&rsquo;ятому — правильно, але зсередини прогону, що вже записав налаштування підкачування до робочої системи. Наполовину застосоване зведення є гіршою відповіддю за відмову, тож було написано попередню перевірочну п&rsquo;єсу: вона не дістається жодного хоста, виконується локально, не збирає фактів і виконує ті самі два файли завдань, які використовує справжнє зведення, проти сховища оператора. Вона відповідає приблизно за секунду, і розгортання виконує її першою. Несучим рішенням є те, що це той самий код, а не друга реалізація того самого правила, бо перевірка, яка переказує правило іншою мовою, зрештою починає з ним розходитися, і розходиться мовчки. Її написання виявило пастку, яку вона мало не створила: факти, встановлені під час п&rsquo;єси, переживають цю п&rsquo;єсу, тож зчеплення попередньої перевірки та зведення в один виклик передало б справжній ролі парольну фразу, яку попередня перевірка вже розв&rsquo;язала, і перевірка пройшла б на сховищі, що досі було хибним. Це відтворили, перш ніж від цього захистилися, в обох файлах завдань.</p>
<p><strong>Результат.</strong> Секрет, який не розв&rsquo;язується, тепер коштує двосекундної відмови на ноутбуці замість частково застосованої зміни на живому сервері. Попередню перевірку навмисно не позначено на безумовне виконання й навмисно не серіалізовано, і обидва ці факти записано як рішення, а не як усталені значення.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Звірила зону DNS із 20 записів декларативно з API Cloudflare, з окремими входами для аудиту та експорту в BIND, і вимкнула проксі CDN назад із міркувань приватності після того, як його побудувала.</title>
      <link>https://platform.engineer.company/uk/portfolio/reconciled-a-dns-zone-declaratively-118/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/reconciled-a-dns-zone-declaratively-118/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Зона версіонована, порівнювана та експортована, а те єдине рішення, що пішло проти очевидного усталеного вибору, записано разом із його обґрунтуванням, аби…</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Мережі та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> DNS компанії ніс близько двадцяти записів на вебприсутність, git‑піддомен, два особисті перенаправлення, поштову маршрутизацію через хостованого постачальника скриньок, домен транзакційної відправки та записи автентифікації для обох. Усе це жило у вебконсолі провайдера, а це означає, що поточним станом було те, що залишила по собі остання людина, яка клацала.</p>
<p><strong>Завдання.</strong> Зона мала стати оголошенням у репозиторії, зі способом порівняти це оголошення з тим, що провайдер насправді віддає.</p>
<p><strong>Дія.</strong> Зону записано як дані — живі записи, записи застосунків, записи транспортної політики та окремий перелік записів, що очікують на вилучення, і це чесний спосіб зафіксувати видалення, яке ще не сталося. Одна п&rsquo;єса узгоджує її з API провайдера. Ще дві точки входу стоять за явними позначками згоди: перевірка, що звітує про різницю, нічого не змінюючи, і експорт, що виписує зону в стандартному форматі файлу зони, аби її могло прочитати щось, що не є цим репозиторієм. Найцікавішим рішенням було скасування. Пропускання двох вебоблич через мережу доставлення контенту провайдера було збудовано, воно працювало, а потім його вимкнули — бо воно коштує того єдиного речення, заради якого існує сторінка приватності компанії. З проксі попереду інша компанія обробляє адресу кожного відвідувача та кожну URL‑адресу, яку той запитує, раніше за нас, за їхньою політикою, а не за нашою. Для бізнесу, чия відмітна заява полягає в тому, що ніхто не спостерігає, це гірший обмін, ніж атаки, від яких він захищає.</p>
<p><strong>Результат.</strong> Зона версіонована, порівнювана та експортована, а те єдине рішення, що пішло проти очевидного усталеного вибору, записано разом із його обґрунтуванням, аби ніхто не переглянув його випадково. Шлях перевірки використовується найчастіше, бо знати різницю потрібно частіше, ніж її усувати.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Зменшила експозицію пісочниці systemd на кожному юніті, який встановлює сама платформа, — служба сигналу живучості з 9,6 UNSAFE до 1,5, звернений до інтернету git‑форж із 8,3 EXPOSED до 1,5 — і додала перевірку парсером під час зведення, знайшовши директиву з помилкою, яку мовчки ігнорували у трьох шаблонах юнітів.</title>
      <link>https://platform.engineer.company/uk/portfolio/cut-systemd-sandbox-exposure-across-every-unit-119/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/cut-systemd-sandbox-exposure-across-every-unit-119/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Кожен модуль працює з тими правами, які йому потрібні, і без тих, які не потрібні, числа виміряно, а не заявлено, і клас дефектів, у якому одруківка стає…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Контейнери (Docker/Kubernetes)</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Контейнеризація та оркестрація</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Тринадцять файлів модулів встановлювалися цим репозиторієм і виконувалися на робочому хості з тими правами, які наглядач дає усталено, а це майже всі. Оцінка захищеності поставила службі перемикача мертвої руки 9,6 і назвала її небезпечною; git‑форджа, обернена до інтернету, дістала 8,3 і була визнана відкритою. Обидва числа були точними, і жодне нічого не спонукало, бо оцінка без прив&rsquo;язаного порога — це число, яке люди привчаються пропускати.</p>
<p><strong>Завдання.</strong> Кожному модулю потрібна була пісочниця, пропорційна до того, що він насправді робить, а пісочницям потрібна була перевірка, бо режим відмови хибної пісочниці полягає в тому, що модуль запускається, а потім ламається там, де парсер цього не бачить.</p>
<p><strong>Дія.</strong> Обмеження прав потрапили до кожного шаблону модуля — стеля привілеїв, закріплена на власній стелі модуля, фільтр системних викликів, обмежені родини адрес і пам&rsquo;ять, що є записуваною або виконуваною, але ніколи водночас. Виміряні результати: перемикач мертвої руки пішов з 9,6 на 1,5, форджа з 8,3 на 1,5, а обидва модулі резервного копіювання з 9,6 на 2,3 і 2,5. Їх написання виявило дещо краще за оцінки. Одну директиву було написано з помилкою у трьох шаблонах модулів відтоді, як ті ролі існували, — правдоподібне на вигляд ім&rsquo;я, якого не існує, на що наглядач відповідає записом у журнал про те, що не розпізнає ключ, і все одно запускає модуль. Пошук директиви доводить, що її було записано; лише парсер доводить, що вона набула чинності. Тож роль верифікації тепер проганяє кожен модуль через власний перевіряч наглядача під час зведення й включається кожною роллю, що встановлює модуль. Те, чого це досі не бачить, викладено прямо в тих самих документах: кожна директива, здатна зламати ці модулі, ламає їх під час виконання, а не під час розбору, і оцінка не може сказати, чи доходить скрипт досі до свого останнього рядка.</p>
<p><strong>Результат.</strong> Кожен модуль працює з тими правами, які йому потрібні, і без тих, які не потрібні, числа виміряно, а не заявлено, і клас дефектів, у якому одруківка стає мовчки відсутнім засобом контролю, тепер валить прогін. Межі вимірювання записано поруч із ним, і саме ця частина стримує наступного читача від надмірної довіри до зеленої смуги.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала сім ролей звітування лише для читання, які подають живий хост як Markdown — факти, доступ, git, метрики, трафік, безпека та інвентар провайдера — за правилом, що не друкується жодне число, якого запуск не виміряв.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-seven-read-only-host-reporting-roles-120/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-seven-read-only-host-reporting-roles-120/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Господарство можна описати з репозиторію на вимогу, і звіти виявили справжні речі: два мертві засоби безпеки, неоголошений слухаючий порт і спостереження, що…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Стейкхолдери та звітність</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Хост не мав панелі й не збирався її отримати, бо стек метрик не вміщується в 464 МБ і не вартував би своєї ціни, навіть якби вмістився. Це лишало чесну прогалину: не було способу відповісти на питання на кшталт того, хто має доступ, наскільки виріс цей репозиторій, який вигляд має трафік або чи справді посилення захисту примусово застосовується.</p>
<p><strong>Завдання.</strong> Ці питання потребували відповідей, які можна виробити на вимогу, які нічого не коштують хостові, поки ніхто не питає, і які ніколи не здатні змінити те, що описують.</p>
<p><strong>Дія.</strong> Сім ролей лише для читання, кожна з яких подає живий хост у Markdown усередині репозиторію. Знімок фактів, що охоплює операційну систему, обладнання, сховище, мережу, служби, пакунки, слухаючі сокети та завантаження процесора, обчислене з двох зразків власного лічильника ядра. Звіт про доступ, що охоплює облікові записи, обсяг sudo, відбитки ключів, користувачів форджі та ролі бази даних. Git‑звіт для кожного репозиторію. Звіт метрик за зібраними за добу зразками. Звіт про трафік, побудований із замаскованого задля приватності журналу вебсервера. Опис провайдерів на чотирьох провайдерських поверхнях — DNS, два хмарні API та API виділених серверів. І звіт з безпеки, що відповідає, чи посилення захисту примусово застосовується, а не лише налаштоване, друкуючи правила брандмауера в порядку збігу та живий набір правил блокування. Керівним правилом для всіх семи є те, що не друкується жодне число, якого прогін не виміряв, — звіт, який заповнює прогалину правдоподібним числом, гірший за той, що лишає її порожньою, бо вірять саме правдоподібному.</p>
<p><strong>Результат.</strong> Господарство можна описати з репозиторію на вимогу, і звіти виявили справжні речі: два мертві засоби безпеки, неоголошений слухаючий порт і спостереження, що архів трафіку не старший за той момент, коли хтось востаннє згадав його зібрати. Останнє описано як обмеження з зафіксованою конкретною ціною — шістнадцять днів історії одного сайту, які проротувалися між збираннями і не існують ніде.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Розгорнула власний git‑форж компанії на Soft Serve, приватний за замовчуванням і без вебпанелі, з портом SSH, прив&#39;язаним до loopback за хостом‑переходом, і зробила посадкову сторінку перед ним артефактом збірки основного сайту, а не копією, яку тримають руками.</title>
      <link>https://platform.engineer.company/uk/portfolio/deployed-the-companys-own-git-forge-121/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/deployed-the-companys-own-git-forge-121/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Компанія тримає власний код на власному обладнанні, а сторінка перед ним успадковує кожну перевірку, яку проходить головний сайт, замість того щоб відходити…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Веброзробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка вебсайтів та CMS</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Початковий код компанії жив на сторонній хостинговій службі, що є розумним місцем для нього і поганим для бізнесу, чий аргумент перед клієнтами полягає в тому, що він не передає їхніх даних посередникам. Натомість тримати форджу означає тримати форджу: автентифікація, контроль доступу, сховище, резервні копії та публічне обличчя для всього цього.</p>
<p><strong>Завдання.</strong> Канонічний git‑сервер треба було підняти на наявному хості, з якнайменшою поверхнею атаки й без вебпанелі адміністрування, і поставити перед ним посадкову сторінку, що не гниє.</p>
<p><strong>Дія.</strong> Форджа — це єдиний двійковий файл під наглядом операційної системи, встановлений із пакункового репозиторію постачальника, свідомо обраний за те, що він передусім працює через SSH і не має адміністративного вебінтерфейсу: що менше інтерфейсу, то менше треба захищати. Він приватний усталено: анонімний доступ відхиляється, доступ без ключа відхиляється, і кожен оголошений репозиторій позначено як приватний, а не покладено на невідомість. Його слухач SSH прив&rsquo;язується лише до інтерфейсу зворотної петлі на порту 23231 і досяжний ззовні через хост‑перехід, тож оголошена поверхня брандмауера не зростає. Мультиплексор протоколів, що поставив би HTTPS і git‑SSH на один публічний порт, оглядаючи перші байти з&rsquo;єднання, написано й готово за головним вимикачем, і цей вимикач вимкнено: багатокористувацький git через публічний порт поки не потрібен, а слухач, яким ніхто не користується, є поверхнею. Посадкова сторінка перед ним була цікавішою задачею. Вона була рукотворною копією оформлення головного сайту у власному репозиторії, і кожна знайдена між ними відмінність виявилася випадковістю, а не рішенням: шкала розмірів, що подавала словесний знак приблизно на дев&rsquo;ять відсотків завеликим, оголошення шрифту, що зводило дві насиченості до однієї на будь‑якій машині зі встановленою гарнітурою, оздоби, приховані нижче певної ширини, тож відсутні на кожному телефоні, насиченість, використана без постаченого для неї шрифту, і жодного головного орієнтира чи заголовка верхнього рівня на жодній сторінці. П&rsquo;ять із п&rsquo;яти, і жодної видимої на знімку екрана. Копію видалено; посадкову сторінку тепер будують власні шаблони головного сайту й доставляють як артефакт.</p>
<p><strong>Результат.</strong> Компанія тримає власний код на власному обладнанні, а сторінка перед ним успадковує кожну перевірку, яку проходить головний сайт, замість того щоб відходити від нього так, як здатне побачити лише вимірювання. Розходження досі доступне, і тепер його треба записати.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Розгорнула контейнерний рівень на Podman і Quadlet під systemd, а не на Docker, бо Docker публікує порти контейнерів над власними правилами фаєрвола хоста, — і дала розгортанням непривілейованого користувача з однією фіксованою командою замість root.</title>
      <link>https://platform.engineer.company/uk/portfolio/deployed-a-container-plane-on-podman-and-quadlet-122/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/deployed-a-container-plane-on-podman-and-quadlet-122/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Контейнери працюють під наглядачем, якому вже довіряли, за брандмауером, який уже було оголошено, а звичайний реліз не потребує привілейованого доступу.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Контейнери (Docker/Kubernetes)</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Контейнеризація та оркестрація</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформі потрібне було місце для запуску контейнерів застосунків. Очевидним вибором був галузевий усталений варіант, і очевидний вибір був хибним для цього хоста в конкретний спосіб: він переписує правила фільтра пакетів ядра та публікує порти контейнерів вище за правила брандмауера, які встановлює роль посилення захисту, тож контейнер тихо стає досяжним з інтернету незалежно від того, що сказали брандмауерові.</p>
<p><strong>Завдання.</strong> Треба було обрати контейнерну площину, що не обходить брандмауер, не додає другого наглядача поруч із тим, якому вже довіряють, і не вимагає бути root, щоб випустити реліз.</p>
<p><strong>Дія.</strong> Площиною є бездемонний контейнерний рушій, що керує модулями, згенерованими власним наглядачем операційної системи. Другого менеджера процесів немає: контейнери є службами, вони запускаються так, як запускаються служби, і описані в тій самій декларативній формі, що й усе інше. Контейнери використовують мережу хоста без жодних опублікованих портів, що усуває питання обходу брандмауера, а не пом&rsquo;якшує його. Модулі виконуються на системному рівні, а не безкореневими, і це записано як обмін — так автоматизація лишається простою та звичною, ціною суворішої ізоляції, яку дав би безкореневий режим, і примітка каже, у який бік рухатися, якщо втеча з контейнера колись важитиме більше за простоту автоматизації. Розгортання відокремлено від конфігурування: root один раз налаштовує шлях розгортання, а далі непривілейований користувач перерозгортає, виконуючи один незмінний скрипт через обмежене правило, що дозволяє саме цю команду й жодних аргументів. Зібрати образ, перезапустити службу. Жодної кореневої оболонки, жодних довільних команд.</p>
<p><strong>Результат.</strong> Контейнери працюють під наглядачем, якому вже довіряли, за брандмауером, який уже було оголошено, а звичайний реліз не потребує привілейованого доступу. Вибір проти усталеного варіанта записано разом із його причиною, і це важить більше за сам вибір — наступній людині кожна стаття, яку вона прочитає, радитиме взяти усталений.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Автоматизувала провізіювання другого сервера в другого хмарного провайдера, створивши фаєрвол перед машиною, щоб вона народжувалася за ним, із фаєрволами обох провайдерів, написаними прямо до їхніх REST API, щоб уникнути сторонньої колекції.</title>
      <link>https://platform.engineer.company/uk/portfolio/provisioned-a-second-server-from-code-123/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/provisioned-a-second-server-from-code-123/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Другий хост можна створити або прийняти повторно з репозиторію, за брандмауером, який уже існує, за ціною, яку зазначає файл.</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Cloud</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Налаштування мереж та VPN</category>
      <category domain="https://platform.engineer.company/uk/services/">Хмарна інфраструктура та міграція</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Для рівня застосунків потрібна була друга машина, в іншого провайдера, ніж перша, і власна історія першої машини була аргументом на користь того, як це зробити: її створювали вручну, а брандмауер додали згодом, що лишає вікно, у якому свіжий хост із усталеною політикою паролів досяжний з інтернету.</p>
<p><strong>Завдання.</strong> Машина мала створюватися з репозиторію і мала народжуватися за своїм брандмауером, а не набувати його трохи згодом.</p>
<p><strong>Дія.</strong> Порядок ніс на собі весь задум. П&rsquo;єса брандмауера виконується перед п&rsquo;єсою сервера, тож набір правил існує ще до того, як з&rsquo;явиться що захищати; в іншого провайдера позначення виконується перед хмарним брандмауером, бо брандмауерові, який націлюється на позначки, потрібно, щоб ці позначки спершу існували. Брандмауери обох провайдерів написано безпосередньо проти їхніх REST API через узагальнене HTTP‑завдання, а не через колекцію постачальника, що усуває залежність і її версійний дрейф ціною ручного написання форм запитів. Роль, що створює машину, приймає наявну замість того, щоб її дублювати, якщо та вже є, тож повторний запуск безпечний. Її також задокументовано, в окремому файлі, як єдину роль у репозиторії, що витрачає гроші, — тип примірника, регіон, специфікацію та місячну вартість у євро записано, бо п&rsquo;єса, що комусь виставляє рахунок, має сказати про це там, де це прочитають. Ця ж п&rsquo;єса є тією, яку не можна відрепетирувати звичним способом: узагальнене HTTP‑завдання не оголошує підтримки режиму перевірки, тож пробний прогін пропускає в ній кожне завдання. Репетицію натомість роблять проти п&rsquo;єси брандмауера, що безкоштовно й оборотно.</p>
<p><strong>Результат.</strong> Другий хост можна створити або прийняти повторно з репозиторію, за брандмауером, який уже існує, за ціною, яку зазначає файл. Те єдине, чого пробний прогін не покриває, названо в тому самому файлі, а не залишено несподіванкою.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Записала правило обсягу в репозиторій після того, як реструктуризація занесла до нього інвентар, дозволи фаєрвола та прозу іншої компанії, — і втримала карантинований залишок під сканером секретів, замість виключити його.</title>
      <link>https://platform.engineer.company/uk/portfolio/wrote-a-scope-rule-after-a-credential-leak-124/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/wrote-a-scope-rule-after-a-credential-leak-124/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Межа обсягу є записаним правилом із зазначеною перевіркою, залишки видимі, а не поховані, і та конкретна форма облікових даних, що прослизнула, тепер валить…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Data Governance</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/services/">Data Governance та якість даних</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Робота, зроблена для іншої компанії, проїхала разом із перебудовою репозиторію та лишилася. Те, що прибуло разом із нею, не було абстрактним: чорновий журнал із живими обліковими даними відкритим текстом, який лежав у дереві повз кожен захист більшу частину історії репозиторію; застарілий інвентар, що називав хост тієї компанії; і файл завдань брандмауера, що відкривав порти шістнадцяти її клієнтським мережам. Нічого з цього не виконувалося. Саме тому воно й вижило — те, що ніде не виконується, більше ніколи не переглядають.</p>
<p><strong>Завдання.</strong> Межа мала стати правилом із прикріпленою перевіркою, а не наміром, а залишки треба було прибрати так, щоб не просто їх сховати.</p>
<p><strong>Дія.</strong> Правило тепер є відкривним розділом набору інструкцій репозиторію: цей репозиторій керує інфраструктурою однієї компанії і тільки нею, і хост, інвентар, дозвіл брандмауера, DNS‑зона чи облікові дані іншої сторони йому не належать — навіть вимкнені, закоментовані чи припарковані у файлі, якого не імпортує жоден плейбук. Практичну перевірку записано поруч: чи відповідала б ця компанія за це, якби стосунки скінчилися. Залишки поміщено до карантину в чітко названому каталозі, а не видалено, тож історія лишається читною, і карантин навмисно неповний — два структурні лінтери його пропускають, а сканер секретів, вартовий сховища та перевірка емодзі навмисно й далі його читають, бо саме ці три спіймали б те, що потрапило всередину. Сам витік породив правило лінтера: власний взірець, що позначає облікові дані, передані як прапорець командного рядка, — а це саме та форма, яку мали витеклі дані і яка не збігалася зі стандартним набором правил.</p>
<p><strong>Результат.</strong> Межа обсягу є записаним правилом із зазначеною перевіркою, залишки видимі, а не поховані, і та конкретна форма облікових даних, що прослизнула, тепер валить коміт. Урок, записаний поруч, є загальним: небезпечний артефакт — не той, що виконується, а той, що не виконується, бо саме його ніхто більше не читає.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Розділила чотири секрети, що належать окремому хосту, після встановлення, що два хости зі спільним сигналом живучості сповіщають менше, ніж два сигнали, а не більше, і що спільна парольна фраза резервних копій робить два хости одним репозиторієм.</title>
      <link>https://platform.engineer.company/uk/portfolio/split-every-operational-secret-per-host-125/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/split-every-operational-secret-per-host-125/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Секрети є похостовими за побудовою, а два режими відмови, що випливли б зі спільного використання, записано там, де наступна людина редагуватиме файл.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Резервне копіювання та відновлення</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Платформу було збудовано для одного хоста, а невдовзі мало стати два. Кілька експлуатаційних секретів було записано як поодинокі значення саме з цього припущення: один репозиторій резервних копій, одна парольна фраза, один перемикач тривоги. Поширити їх на другий хост, зробивши спільними, — шлях найменшого опору, і він хибний у два окремі способи, обидва з яких відмовляють тихо.</p>
<p><strong>Завдання.</strong> Кожен секрет мав стати відображенням із ключем за хостом, а причину треба було записати, бо спільна версія має правильний вигляд і нічого не коштує аж до того дня, коли це важить.</p>
<p><strong>Дія.</strong> Справу вирішили два аргументи, і обидва записано поруч із налаштуванням. Перемикач мертвої руки, спільний для двох хостів, б&rsquo;є на сполох менше, ніж два перемикачі, а не більше: будь‑який хост, що досі пінгує, тримає перевірку зеленою, поки другий мертвий, тож додавання хоста до спільного перемикача активно зменшує покриття того, що вже там був. А рядок репозиторію резервних копій є лише розташуванням — парольна фраза є всім шифруванням, тож два хости зі спільною парольною фразою є не двома репозиторіями зі спільним секретом, а одним репозиторієм із двома каталогами всередині. Кожне значення стало відображенням із ключем за іменем хоста в інвентарі, розв&rsquo;язуваним для кожного хоста спільним файлом завдань, який виконують і зведення, і попередня перевірка. Наявний хост потім названо в усіх чотирьох відображеннях, із його репозиторієм і обома порожніми перемикачами, і це правдивий стан, що тримає дві відкриті ініціативи чесними щодо того, що вони винні операторові половину роботи, а не коду.</p>
<p><strong>Результат.</strong> Секрети є похостовими за побудовою, а два режими відмови, що випливли б зі спільного використання, записано там, де наступна людина редагуватиме файл. Порожні записи є тією частиною, яку варто зберегти: вони кажуть, що обв&rsquo;язка існує, а значення — ні, і це інше й корисніше твердження, ніж відсутній ключ.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Побудувала ворота коміту з 22 однорядкових лінтерів плюс п&#39;ятьох, що заслуговують на абзац, без рівня попереджень і без дозволених вбудованих придушень, з покриттям HTML, CSS, JavaScript, Python, YAML, Markdown, shell, посилань, орфографії, секретів і типографіки.</title>
      <link>https://platform.engineer.company/uk/portfolio/built-a-22-linter-commit-gate-127/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/built-a-22-linter-commit-gate-127/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Механічні заперечення висуває машина ще до того, як коміт існує, і ця перевірка є єдиним рецензентом, що має цей проєкт.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Продуктова стратегія та вимоги</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Посібник для учасників — це набір порад. Усі з ним погоджуються, а потім настає п&rsquo;ятниця, зміна мала, і посібник програє. У проєкті з однієї людини це радше гірше, ніж краще, бо рецензента немає взагалі — єдине, що стоїть між поганою зміною та робочою системою, це людина, яка її написала, у ту мить, коли вона найменш схильна сперечатися сама із собою.</p>
<p><strong>Завдання.</strong> Стандарти мали стати виконуваними, щоб порушення одного з них валило коміт, а не чекало, доки його помітять.</p>
<p><strong>Дія.</strong> Виросла перевірка з 22 лінтерів без рівня попереджень: кожна діагностика є помилкою, а сам генератор сайту працює з попередженнями, піднятими до відмов, тож навіть застаріла можливість спиняє збирання. Очевидні присутні — перевірка HTML, CSS, JavaScript, Python, YAML, Markdown, оболонки, орфографії, секретів, мертвих посилань. Цікавими є специфічні для проєкту перевірки, про які жоден готовий інструмент не має думки: що обидві колірні теми фарбують кожну шарувату поверхню однаковою кількістю шарів, що жодну світлину не показано ширшою за половину її вихідних пікселів, що розгорнуте дерево не містить приватного шляху чи імені хоста, що проза дотримується правил тону всіма трьома мовами, що сторінка має двійник у Markdown і чинне подання альтернативним протоколом. Вбудовані придушення заборонено цілком — жодного коментаря ігнорування, жодної директиви вимкнення, жодного обходу хука і жодного перейменування файлу заради ухилення від збігу. Правилом, що тримає це чесним, є те, що наперед наявна відмова не є виправданням: перевірка, що виявляє дефект, якого ніхто не вносив, виправляється тим самим проходом.</p>
<p><strong>Результат.</strong> Механічні заперечення висуває машина ще до того, як коміт існує, і ця перевірка є єдиним рецензентом, що має цей проєкт. Ціну зазначено, а не приховано: комітити повільно, а погано написаний вартовий справді нестерпний в обході, і саме тому самих вартових згодом підвели під власний форматувальник і власний лінтер.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Скоротила керовані браузером ворота якості сайту з 1 636 секунд до 615, плануючи їхні перевірки від найдовшої через пул воркерів, обмежений чотирма смугами, вимірявши, що абеткова черга коштувала 320 секунд проти 224.</title>
      <link>https://platform.engineer.company/uk/portfolio/cut-the-visual-quality-gate-to-ten-minutes-128/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/cut-the-visual-quality-gate-to-ten-minutes-128/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Перевірка пішла з 1 636 секунд на 615, тоді як самі перевірки стали ширшими, а не тоншими — послідовна вартість зросла, а час за годинником упав.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Одинадцять перевірок сайту керують браузером без вікна: розкладка за кожної форми вікна, яку малює дизайн, шкала розмірів, розширення перекладеного тексту, контраст, правила доступності, примусові кольори, розміри маскота, рух, друк у шести комбінаціях паперу, помилки консолі та візуальна регресія. Виконувані по одній, вони брали 1 636 секунд, трохи більш ніж двадцять сім хвилин. Перевірка, що триває двадцять сім хвилин, — це перевірка, яку пропускають, а пропущену перевірку не відрізнити від пройденої.</p>
<p><strong>Завдання.</strong> Час за годинником мав опуститися настільки, щоб їх запуск був усталеним варіантом, а не рішенням, і жодну з них при цьому не можна було послабити.</p>
<p><strong>Дія.</strong> Робота почалася з вимірювання. Кожну перевірку заміряно окремо на дванадцятиядерній машині: розкладка на 405 секундах, шрифт на 301, переклад на 282, контраст на 189, доступність на 178 і далі вниз аж до сімнадцяти. Відповідь сформували два висновки. Виконувати всі одразу було повільніше, ніж по чотири за раз, — 265 секунд проти 224, — бо кожна перевірка сама є браузером, що виконує паралельну роботу, і надмірне навантаження машини коштує більше, ніж виграє паралельність. А впорядкування за найдовшим часом обробки спершу перемогло абеткове майже на третину, 224 секунди проти 320, і це класичний результат теорії розкладів, який виявляється тут тому, що перевірки різняться у вартості в двадцять разів. Тож виконавцем є обмежений пул робітників, розмір якого береться з кількості ядер із підлогою в два та стелею в чотири, і який годують найдовшим спершу. Поряд із цим перевірки радше розширили, ніж звузили: вони тепер спільно використовують одну таблицю з двадцяти двох форм вікна, виведену з кожного медіазапиту, який насправді містить таблиця стилів, і це саме лише підняло перевірку розкладки з 95 секунд до 405.</p>
<p><strong>Результат.</strong> Перевірка пішла з 1 636 секунд на 615, тоді як самі перевірки стали ширшими, а не тоншими — послідовна вартість зросла, а час за годинником упав. Вимірювання є тією частиною, яку варто зберегти: два розумні на слух вибори, виконувати все одразу й виконувати в порядку написання, кожен виявився вимірювано гіршим за альтернативу.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Віддзеркалила весь сайт як 777 документів Gemini і 777 документів Gopher з того самого розгорнутого дерева, з нульовою зміною байтів у HTML.</title>
      <link>https://platform.engineer.company/uk/portfolio/mirrored-the-site-to-gemini-and-gopher-137/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/mirrored-the-site-to-gemini-and-gopher-137/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Сайт читний чотирма протоколами з одного збирання, по 777 документів на кожен і з нульовою зміною HTML, а альтернативні подання коштують приблизно дванадцять…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Веброзробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інтернаціоналізація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Інтернаціоналізація та локалізація</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка вебсайтів та CMS</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Сайт статичний, не має ні стеження, ні бекенду часу виконання, і його аргумент полягає в тому, що документові не потрібен мегабайт JavaScript, аби його прочитали. Цей аргумент легко висловити й важко продемонструвати. Два невеликі інтернет‑протоколи демонструють його безпосередньо, бо жоден із них узагалі не здатен нести скрипт.</p>
<p><strong>Завдання.</strong> Увесь сайт мав публікуватися через Gemini і Gopher із того самого вмісту, без другого дерева вмісту й без змін у HTML.</p>
<p><strong>Дія.</strong> Обидва є форматами виводу того самого збирання, а не окремим конвеєром. Генераторові сайту надали власні типи носіїв і формати виводу, і кожна сторінка, розділ та термін таксономії дістали ще по два подання поруч зі своїм HTML і двійником у Markdown. Результатом є 777 документів Gemini і 777 меню Gopher, вироблені з того самого джерела, розгорнуті в те саме дерево й віддавані двома невеликими демонами на тому самому хості. Дві властивості зробили це вартим роботи, а не дивиною. Обидва формати позначено як неальтернативні подання, тож у HTML не змінилося нічого — жодного байта, і це виміряли, а не припустили. А формат Gopher не має способу вкласти посилання всередину речення, бо рядок меню є полями, розділеними табуляціями, тож прозу жорстко переносять на шістдесят восьмому стовпчику під час збирання; це обмеження вигострило письмо так, як HTML ніколи не вимагав. Поруч із ними стоїть onion‑дзеркало Tor, і це єдине публічне обличчя, яке платформа могла додати, не відкриваючи порту брандмауера, бо демон додзвонюється назовні, а всередину не дзвонить ніхто.</p>
<p><strong>Результат.</strong> Сайт читний чотирма протоколами з одного збирання, по 777 документів на кожен і з нульовою зміною HTML, а альтернативні подання коштують приблизно дванадцять відсотків від власної ваги HTML на диску. Лише один із чотирьох вимірюється щодо трафіку, і це зазначено у власному документі статистики платформи, а не тихо проігноровано.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Виправила мапу сайту, де 172 з 176 URL мали одну позначку часу зміни, взявши дату з історії git після встановлення, що експорт переписує кожен файл при кожному запуску.</title>
      <link>https://platform.engineer.company/uk/portfolio/fixed-a-sitemap-with-one-shared-timestamp-140/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/fixed-a-sitemap-with-one-shared-timestamp-140/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Повторна синхронізація після місяця редагування вмісту тепер торкається восьми файлів зі 186 замість усіх, і мапа сайту каже щось правдиве.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бренд і маркетинг</category>
      <category domain="https://platform.engineer.company/uk/categories/">Веброзробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Бренд, маркетинг та SEO</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка вебсайтів та CMS</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Мапа сайту казала пошуковим системам, що 172 з його 176 сторінок востаннє змінилися тієї самої миті. Це не тонка неточність — дата зміни є обіцянкою повзунові, що вміст сторінки змінився, і сайт, який дає цю обіцянку 172 рази одночасно, або каже правду про повне переписування, або не каже нікому нічого корисного.</p>
<p><strong>Завдання.</strong> Дати мали описувати вміст, а не файл, не вигадуючи точності, якої репозиторій не має.</p>
<p><strong>Дія.</strong> Причиною було те, що дата бралася з часу зміни файлу, а експорт вмісту переписує кожен файл за кожного прогону, тож одна синхронізація штампувала весь корпус. Виправлення переносить джерело до історії версій, із ланцюжком запасних варіантів, що пробує спершу явне поле, потім історію комітів, потім файл. Пастка в цьому виправленні варта запису: буквальна назва поля має з&rsquo;явитися в переліку, інакше генератор ніколи його не прочитає, тож налаштування, що на вигляд віддає перевагу авторській даті, але пропускає назву, мовчки ігнорує кожну авторську дату. З тієї самої роботи вийшли ще два рішення про дати. База даних тепер несе, коли кожен запис було написано й востаннє переглянуто, і це навмисно тримають окремо від того, коли відбулася сама робота, — вони віддалені на роки, і злиття їх датувало б сторінку, написану цього року, десятиліттям тому. А рядки в тому файлі є необов&rsquo;язковими, і нічого не виводиться, бо власна історія репозиторію починається пізніше за вміст: відсутня дата лишає поле порожнім, а не фіксує міграцію, за принципом, що точне хибне число гірше за відсутнє, бо вірять саме хибному.</p>
<p><strong>Результат.</strong> Повторна синхронізація після місяця редагування вмісту тепер торкається восьми файлів зі 186 замість усіх, і мапа сайту каже щось правдиве. Загальне правило потрапило до документа з метаданими поруч, бо та сама пастка стосується кожного поля, що має ланцюжок запасних варіантів.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Підвела 10 242 рядки JavaScript воріт якості під форматувальник і лінтер, встановивши, що це найбільший обсяг коду в репозиторії й єдиний, якого ніщо не читало, виправила 13 знахідок і не придушила жодної.</title>
      <link>https://platform.engineer.company/uk/portfolio/brought-the-quality-gate-code-under-a-linter-143/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/brought-the-quality-gate-code-under-a-linter-143/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Найбільший і найбільш несучий код у репозиторії тепер відформатовано, перевірено лінтером і перевірячем типів, із тринадцятьма виправленими висновками й нулем…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Перевірка якості сайту — це тридцять два скрипти загальним обсягом 10 242 рядки JavaScript. Це був із великим відривом найбільший масив коду в репозиторії, і це був єдиний масив коду, якого ніщо не читало — ані форматувальник, ані лінтер, ані перевірка типів. Програми, що примусово застосовували кожне правило в проєкті, були єдиними програмами, на які не поширювалося жодне з них.</p>
<p><strong>Завдання.</strong> Перевіряльників треба було підвести під той стандарт, заради примусового застосування якого вони існують, і форматувальник треба було припасувати до них, а не навпаки.</p>
<p><strong>Дія.</strong> Форматувальник ішов першим, і ширина відступу була цікавим рішенням. Усталеним значенням репозиторію є чотири пробіли; за чотирьох пробілів форматувальник переписав би 2 173 рядки найбільшого перевіряльника. Перевизначення на два пробіли для цих файлів звело це до 38 рядків справжнього розходження. Записаний із цим принцип полягає в тому, що форматувальник припасовують до коду, а не код до форматувальника — переформатування двох тисяч рядків заради вподобання знищує здатність читати історію файлу. Далі лінтер, що дав тринадцять справжніх висновків, усі виправлено й жодного не придушено. Перевіряльники на Python дістали те саме поводження через перевіряч типів, налаштований на середню суворість із тридцятьма окремими правилами суворого рівня, увімкненими понад це й обраними за вимірюванням: за цього налаштування дерево мовчить, і з тридцяти кандидатів двадцять дев&rsquo;ять уже мовчали, а один спрацював — і його виправили, а не звільнили. Перевіряч типів знайшов два справжні дефекти, які лінтер пропустив чистими, обидва про форму значення, а не про його синтаксис.</p>
<p><strong>Результат.</strong> Найбільший і найбільш несучий код у репозиторії тепер відформатовано, перевірено лінтером і перевірячем типів, із тринадцятьма виправленими висновками й нулем придушень. Причина, чому це важить більше, ніж підказує кількість рядків, зазначена в плані: дефект у таблиці стилів сайту виявляється як сторінка, що виглядає хибно, а дефект у перевіряльнику виявляється як перевірка, що проходить тоді, коли не мала б.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Втримала генератор на 981 тестовому випадку із порогом покриття гілок 92% і попередженнями як помилками та ствердила ідемпотентність, запустивши весь конвеєр збірки двічі з порожнього файлу й вимагаючи, щоб другий прохід нічого не змінив.</title>
      <link>https://platform.engineer.company/uk/portfolio/held-the-generator-to-964-tests-and-a-coverage-floor-145/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/held-the-generator-to-964-tests-and-a-coverage-floor-145/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Конвеєр можна повторно виконати проти живої бази даних без страху, і саме це взагалі уможливлює поступову роботу з вмістом.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Генератор, що збирає базу даних з нуля, має особливий різновид вади: він працює першого разу й псує другого. Кроки, що вставляють без перевірки, кроки, що залежать від порядку виводу попереднього кроку, кроки, безпечні поодинці й не разом. Нічого з цього не виявляється в тесті, що починає з нічого й виконується один раз.</p>
<p><strong>Завдання.</strong> Збирання треба було довести як повторюване, а не просто робоче, а набір тестів мав бути достатньо великим і суворим, щоб регресія не змогла тихо крізь нього пройти.</p>
<p><strong>Дія.</strong> Тест ідемпотентності є прямолінійним і найкориснішим: зібрати всю базу даних із порожнього файлу, зробити знімок, виконати весь дев&rsquo;ятнадцятикроковий конвеєр знову поверх результату й вимагати, щоб другий прохід нічого не змінив. Кількості рядків, вміст та ідентифікатори мають збігатися. Довкола нього стоять 383 тестові функції — 981 випадок, коли параметризовані розгортаються, — у сорока п&rsquo;яти файлах і 7 944 рядках, що охоплюють конвеєр, рендерери, завантажувачі вмісту, логіку націлювання та перевіряльників. Покриття гілок несе підлогу в дев&rsquo;яносто два відсотки, примусово застосовану в збиранні, а не подану в підсумку, і набір наразі показує близько 95 відсотків, тож підлога має запас і не є декоративною. Попередження налаштовано як відмови, і саме це налаштування на практиці важить найбільше — сповіщення про застарілість, що друкується два роки, є сповіщенням, якого ніхто не читає, а прогін, що перетворює його на червоний тест, є тим прогоном, після якого його виправлять.</p>
<p><strong>Результат.</strong> Конвеєр можна повторно виконати проти живої бази даних без страху, і саме це взагалі уможливлює поступову роботу з вмістом. Підлога є підлогою, а не ціллю, і варто сказати, що дев&rsquo;яносто два відсотки покриття гілок усе одно лишають гілки, якими ніщо ніколи не проходило, — число обмежує ризик, а не усуває його, і два дефекти, знайдені в проєкті згодом, були в коді, який звіт про покриття показував як покритий.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Обрала кожне правило, яке має лінтер Python, як помилку й опрацювала 1 815 знахідок до нуля, де кожен із небагатьох винятків несе письмову причину, а два з них підперті перевіркою, а не коментарем.</title>
      <link>https://platform.engineer.company/uk/portfolio/enabled-every-python-linter-rule-as-an-error-147/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/enabled-every-python-linter-rule-as-an-error-147/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Лінтер працює на повну силу з нулем висновків, і кожне відхилення задокументовано в тому рядку, де його взято.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Більшість проєктів обирає зручну підмножину правил свого лінтера, і цю підмножину обирають ті правила, що мовчали того дня, коли його налаштовували. Це робить налаштування записом наявних звичок коду, а не стандартом, якого код дотримується, і кожне лишене вимкненим правило є класом дефектів, про який нікому ніколи не скажуть.</p>
<p><strong>Завдання.</strong> Усталений вибір треба було обернути — кожне правило, яке реалізує інструмент, увімкнене як помилка, — а отриманий доробок відпрацювати до нуля, а не виторгувати вниз, вимикаючи правила назад.</p>
<p><strong>Дія.</strong> Вибір повного набору правил дав 1 815 висновків на першому прогоні. Їх опрацьовували за категоріями, а не за файлами, бо категорії про щось кажуть: невживані аргументи та затінені вбудовані імена є шумом, а категорія безпеки, категорія змінюваних усталених значень і категорія обробки винятків кожна вказувала на справжню поведінку. Справжні несумісності існують — форматувальник і лінтер можуть розходитися щодо того самого рядка, а кілька правил суперечать власним свідомим виборам проєкту, — і кожне з невеликої кількості звільнень несе письмову причину в тому місці, де звільнення береться, і каже, чого хотіло правило й чому цей код робить інакше. Два з них ідуть далі й підперті перевіркою, а не коментарем, тож звільнення не може тихо розширитися: правило вимкнено, а тест стверджує саме ту властивість, яку правило примусово застосувало б. Поряд працює перевірка типів у суворому режимі, а це окремий і жорсткіший стандарт, і саме вона спіймала дефекти, яких лінтер не бачив, бо вони про те, чим значення є, а не про те, як його записано.</p>
<p><strong>Результат.</strong> Лінтер працює на повну силу з нулем висновків, і кожне відхилення задокументовано в тому рядку, де його взято. Ціна реальна й варта називання: найсуворіше налаштування дає висновки, на які щиро не варто зважати, і хтось має ухвалювати це рішення 1 815 разів, а не один раз.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Написала тести для самих перевірок після встановлення, що перевірка, якій дають лише чистий вхід, одного дня відзвітує чисто, бо нічого не прочитала, — підклавши помилку правопису, щоб підтвердити, що перевірка орфографії її знаходить, і взявши діапазон ідентифікаторів із бази даних, а не з числа в тесті.</title>
      <link>https://platform.engineer.company/uk/portfolio/wrote-tests-for-the-checkers-themselves-149/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/wrote-tests-for-the-checkers-themselves-149/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Кожен перевіряльник у проєкті тепер має тест, що доводить його падіння на поганих вхідних даних, а твердження про діапазон читаються з джерела істини.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Data Governance</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Бази даних</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Data Governance та якість даних</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Проєкт проганяє набір власних перевіряльників над власним вмістом — перевірку орфографії, перевірку діапазону ідентифікаторів, перевірку голосу, перевірку узгодженості чисел. Кожен із них місяцями показував зелене. Перевіряльник, що бачив лише чисті вхідні дані й лише звітував про чистоту, не відрізнити від перевіряльника, що не читає нічого, і в наборі не було тесту, здатного розрізнити цих двох.</p>
<p><strong>Завдання.</strong> Перевіряльників треба було змусити довести, що вони здатні завалитися, а фікстури, проти яких вони перевіряють, мали перестати бути рукотворними копіями того, що вони описують.</p>
<p><strong>Дія.</strong> Взірцем, застосованим усюди, є посадити саме той дефект, заради пошуку якого перевіряльник існує, і вимагати, щоб перевіряльник його знайшов. Перевірці орфографії згодовують навмисно неправильно написане слово, і тест валиться, якщо прогін повертається чистим. Перевірці голосу згодовують прозу в першій особі, і вона має її відхилити. Перевірці модних слів згодовують заборонене слово. Кожне з цього є маленьким тестом, і кожен закрив справжню сліпу пляму, бо два перевіряльники, як виявилося, читали вужчий набір файлів, ніж заявляла їхня документація, і мовчки пропускали вміст. Друга зміна стосується того, звідки тест бере свої очікування: перевірка діапазону ідентифікаторів раніше порівнювала з числом, записаним у тестовому файлі, а це означало, що кожне додавання вмісту вимагало редагування тесту, і редактор, який оновив число, не подивившись, вимикав перевірку. Тепер вона виводить діапазон із бази даних, тож перевірка описує дані, а не застарілий спогад про них.</p>
<p><strong>Результат.</strong> Кожен перевіряльник у проєкті тепер має тест, що доводить його падіння на поганих вхідних даних, а твердження про діапазон читаються з джерела істини. Незручним є те, що це виявило: зелена перевірка була беззмістовною щонайменше у двох місцях протягом невідомого часу, і немає способу дізнатися заднім числом, що крізь неї пройшло.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Виявила, що хуки коміту та ворота якості виконують різні перевірки, поки документ обіцяв, що вони однакові, порівнявши два переліки в тесті, — п&#39;ять, які виконувалися лише вручну, були тими, що читали прозу CV.</title>
      <link>https://platform.engineer.company/uk/portfolio/found-the-commit-hooks-and-the-gate-disagreeing-150/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/found-the-commit-hooks-and-the-gate-disagreeing-150/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Хук і повна перевірка доведено виконують ті самі перевірки, а перевірки прози тепер виконуються за кожного коміту.</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Проєкт мав хук на коміт, що виконує перевірки до прийняття коміту, і повну перевірку якості, яку запускають на вимогу. Документ стверджував, що хук виконує ту перевірку, тож ніщо не могло потрапити до історії, не пройшовши всього. Обидва переліки підтримувалися вручну, у двох різних файлах, і ніщо їх не порівнювало.</p>
<p><strong>Завдання.</strong> Заяву треба було перетворити на твердження, а це означало перелічити обидві множини програмно й валитися, коли вони розходяться.</p>
<p><strong>Дія.</strong> Тест читає налаштування хука та визначення завдань перевірки, розв&rsquo;язує кожне з них у множину перевірок, які воно насправді викликає, і порівнює. Вони не збіглися. П&rsquo;ять перевірок існували лише в повній перевірці й ніколи не виконувалися на коміті, і ці п&rsquo;ять не були випадковими — це були ті, що читають саму прозу CV: перевірка голосу, яка тримає відгуки безособовими, перевірка модних слів, перевірка узгодженості чисел між мовами, перевірка нотації та перевірка орфографії вмісту. Інакше кажучи, кожна перевірка, що захищає код, виконувалася автоматично, а кожна перевірка, що захищає письмо, виконувалася лише тоді, коли хтось згадував. Оскільки письмо є всім продуктом, вразливість була оберненою щодо того, де її хтось припустив би. Виправленням було внести ці п&rsquo;ять до хука, що вимагало зробити дві з них досить швидкими, аби пережити бюджет часу до коміту, а потім лишити тест порівняння на місці, щоб два переліки більше не могли розійтися. Документ, що описував намір, тепер описує щось примусово застосоване.</p>
<p><strong>Результат.</strong> Хук і повна перевірка доведено виконують ті самі перевірки, а перевірки прози тепер виконуються за кожного коміту. Компромісом є час виконання хука на коміт, який зріс і зростатиме далі, поки зростає вміст, і існує точка, у якій повільний хук починають обходити, — тож у цього виправлення є термін придатності, вимірюваний тим, як довго перевірки лишатимуться швидкими.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Відрепетирувала CI‑хук на боці форжу й знайшла два дефекти, недосяжні читанням файлу: запасний варіант, який клав нерозв&#39;язний аргумент на вхід хука, і власну змінну середовища git, яка йшла за воротами у checkout і робила 19 тестів червоними.</title>
      <link>https://platform.engineer.company/uk/portfolio/rehearsed-the-forge-side-ci-hook-151/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/rehearsed-the-forge-side-ci-hook-151/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Хук працює на обох шляхах, і обидва дефекти знайдено раніше, ніж їх зустрів справжній пуш. Обмеження в тому, що репетиція все одно є симуляцією: вона доводить,…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Самостійно розміщена git‑форджа приймає пуші й може виконати хук на боці сервера, аби відхилити роботу, що не проходить перевірку. Хук на боці сервера є тим єдиним шматком автоматизації, який не можна випробувати, запустивши його локально: він виконується в голому репозиторії, без робочого дерева, у середовищі, яке задає форджа, читаючи запушені посилання зі свого стандартного входу. Прочитати скрипт і виснувати, що він правильний, — це здогад.</p>
<p><strong>Завдання.</strong> Хук треба було відрепетирувати проти справжнього голого репозиторію та справжнього пушу, перш ніж йому довіряти, а не розгорнути й дізнатися.</p>
<p><strong>Дія.</strong> Репетиція створює голий репозиторій, встановлює хук, клонує його, комітить, пушить і стверджує і на шляху прийняття, і на шляху відхилення. Вона знайшла два дефекти, жоден із яких не був видимий у файлі. Першим був запасний варіант в обробці аргументів: коли хук не міг визначити посилання, він підставляв заповнювач, що не був розв&rsquo;язуваним об&rsquo;єктом, і оскільки значення приходить на стандартний вхід хука, а не як параметр, відмова спливала як неспоріднена помилка значно нижче. Другий вартий запам&rsquo;ятовування. Git експортує змінну середовища, що називає каталог репозиторію, коли викликає хук, і цю змінну успадковує все, що хук запускає. Перевірка вивантажує запушену ревізію й виконує в ній набір тестів, а набір тестів успадкував вказівник на голий репозиторій — тож дев&rsquo;ятнадцять тестів, що торкаються git, розв&rsquo;язувалися проти хибного репозиторію й почервоніли на коді, що був правильним. Середовище треба очищати на межі, і ця межа невидима, доки річ насправді не запустять.</p>
<p><strong>Результат.</strong> Хук працює на обох шляхах, і обидва дефекти знайдено раніше, ніж їх зустрів справжній пуш. Обмеження в тому, що репетиція все одно є симуляцією: вона доводить, що хук переживає одну форму пушу, а форджа в роботі бачить пуші, яких ця репетиція не конструює, зокрема примусові оновлення та видалення гілок.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Спинила застосунок, що наповнював пам&#39;ять зі швидкістю 41 МБ за секунду — зафіксовані 111 ГБ стиснених сторінок на машині з 36 ГБ, — обмеживши кожен потік подій, підписуючись за типом події та поклавши бюджет швидкості на журналювання, що звело 610 996 рядків журналу до 1 411.</title>
      <link>https://platform.engineer.company/uk/portfolio/stopped-an-application-filling-memory-at-41mb-a-second-155/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/stopped-an-application-filling-memory-at-41mb-a-second-155/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Пам&#39;ять лишається рівною під тривалим навантаженням, і той самий сеанс, що давав 610 996 рядків журналу, дає 1 411.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Архітектура рішень</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Frontend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">Архітектура платформи та рішень</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Програма наповнювала пам&rsquo;ять, доки операційна система її не вбивала. Зафіксований інцидент сягнув 111 ГБ стиснутих сторінок на машині з 36 ГБ, зростаючи приблизно на 41 МБ за секунду, а файл журналу за один короткий сеанс тримав 610 996 рядків. Машина в такому стані не повільна, вона непридатна — вбивство приходить після того, як підкачування вже змусило все інше на робочому столі перестати відповідати.</p>
<p><strong>Завдання.</strong> Зростання треба було знайти, а не вгадати, і кожному необмеженому шляху треба було дати межу, бо одна обмежена черга поруч із трьома необмеженими не є виправленням.</p>
<p><strong>Дія.</strong> Причин‑множників було три, і саме множення пояснює, чому це відбувалося так швидко. Потік подій із ядра споживався без жодної межі, тож події надходили швидше, ніж інтерфейс міг їх застосувати, і доробок утримувався, а не відкидався. Кожен передплатник отримував кожну подію й фільтрував після цього, тож вартість однієї події множилася на кількість слухачів, і фільтрування кожного слухача виділяло пам&rsquo;ять. А журналювання було небюджетованим, тож кожна подія породжувала рядки журналу — і це складений доданок, бо обсяг журналювання був пропорційним до обсягу того, що йшло не так. Виправлення взялося за всі три: обмежені буфери з явною політикою того, що стається за їх заповнення, передплата за типом події, тож слухача будять лише для подій, яких він хоче, і бюджет швидкості на журналювання, що згортає повтори, а не пише кожен. Регресійний тест жене високу швидкість подій і стверджує, що стеля пам&rsquo;яті тримається, тож межа є властивістю збирання, а не коментарем.</p>
<p><strong>Результат.</strong> Пам&rsquo;ять лишається рівною під тривалим навантаженням, і той самий сеанс, що давав 610 996 рядків журналу, дає 1 411. Чесним зауваженням є те, що бюджет швидкості на журналювання відкидає інформацію: коли щось іде не так швидко, запис про це тепер навмисно неповний, і це обмін, зроблений свідомо проти альтернативи, якою є машина, що спиняється.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Написала парсер, який читає справжній C‑заголовок на 7 308 рядків і перевіряє кожне місце виклику, кожну константу переліку й те, що кожен клас‑власник вказівника є final, після того як рукописний заголовок‑заглушка дозволив викликам до трьох вилучених функцій скомпілюватися, злінкуватися й впасти.</title>
      <link>https://platform.engineer.company/uk/portfolio/wrote-a-parser-that-verifies-every-ffi-call-site-157/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/wrote-a-parser-that-verifies-every-ffi-call-site-157/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Клас дефектів, що спричинив початкову аварію, не може повторитися, бо застаріле посилання тепер є відмовою збирання, а не відмовою під час виконання.</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> На початку проєкту C‑інтерфейс представляв рукописний заголовний файл, що описував функції, яких очікувала програма. Той заголовок компілювався, програма зв&rsquo;язувалася, а виклики трьох функцій, яких у ядрі більше не існувало, доходили до моменту виклику й аварійно завершувалися. І компілятор, і компонувальник задовольнилися описом бібліотеки замість самої бібліотеки, а розрив виявився лише під час виконання.</p>
<p><strong>Завдання.</strong> Справжній заголовок — 7 308 рядків і 268 оголошень — мав стати авторитетом, і кожне його використання в коді Swift треба було звіряти з ним автоматично, а не переглядом.</p>
<p><strong>Дія.</strong> Перевіркою є розбирач, що читає справжній висхідний заголовок і будує множину функцій, констант переліку й типів, які той оголошує, а потім читає код Swift і розв&rsquo;язує кожне місце виклику та кожне посилання на константу проти цієї множини. Виклик функції, якої заголовок не оголошує, валить збирання. Посилання на константу переліку, яку перейменували, валить збирання. Поточне число — 132 з 268 оголошень, на які є посилання, і знати, які 136 не використовуються, саме собою корисно, бо це каже точно, якої частини ядра клієнт не досяг. Розбирач також примусово застосовує правило, якого не може компілятор: кожен клас Swift, що володіє вказівником у ядро, має бути фінальним. Нефінальний клас, що володіє вказівником, можна успадкувати, а підклас, що перевизначає деініціалізацію або додає власний час життя, змінює момент звільнення вказівника — використання після звільнення без жодного небезпечного ключового слова поблизу. Правило перевіряють за іменем по всьому дереву.</p>
<p><strong>Результат.</strong> Клас дефектів, що спричинив початкову аварію, не може повторитися, бо застаріле посилання тепер є відмовою збирання, а не відмовою під час виконання. Обмеженням є те, що розбирач розуміє оголошення заголовка, а не його семантику: він доводить, що функція існує з відповідним іменем, а функція, чиє значення чи правило володіння змінилося вище за течією зі збереженням сигнатури, проходить без зауважень.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Звела набір тестів із шести тестів понад межу в шістдесят секунд до 135 успішних за 8,9 секунди, профілюючи головний потік і прибравши два виклики, всередині яких він сидів у 3 989 із 4 017 вибірок.</title>
      <link>https://platform.engineer.company/uk/portfolio/took-the-test-suite-under-nine-seconds-158/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/took-the-test-suite-under-nine-seconds-158/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Набір пішов із шести тестів понад шістдесят секунд — 74 секунди за годинником — до 135 тестів, що проходять за 8,9, і це вкладає його у вікно, в якому він…</description>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Оптимізація продуктивності</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Набір тестів мав межу в шістдесят секунд, і шість тестів були понад неї. Набір тестів, що триває понад хвилину, перестають запускати перед кожною зміною, а набір, який не запускають перед кожною зміною, є звітом про минуле. Інстинкт у цій ситуації — підняти межу, а піднімання межі є тим, як набір доходить до десяти хвилин.</p>
<p><strong>Завдання.</strong> Час треба було знайти, а не закласти в бюджет, а це означало профілювати набір замість міркувати, які тести мають дорогий вигляд.</p>
<p><strong>Дія.</strong> Профіль знімали з головного потоку, поки набір виконувався, і результат суперечив здогаду. Головний потік сидів усередині двох викликів у 3 989 зразках із 4 017 — тож повільними були не ті тести, що робили найбільше роботи, і майже кожен тест проходив через ті самі два місця. Першим було фіксоване очікування, вжите, щоб дати асинхронній роботі влягтися перед твердженням, — по суті сон, оплачуваний кожним тестом, що торкався шляху подій, незалежно від того, чи робота вже скінчилася. Його замінили на очікування самої умови з тайм‑аутом, тож тест, готовий за п&rsquo;ять мілісекунд, бере п&rsquo;ять мілісекунд, і повне очікування платить лише той тест, що справді застряг. Другим було налаштування на кожен тест, що щоразу перебудовувало дорогу фікстуру, тоді як фікстура була лише для читання й могла будуватися один раз на весь набір. Жодне з них не було в тесті, який хтось назвав би повільним; обидва були в спільному шляху, і саме тому весь набір був рівномірно повільним, а не кілька тестів були викидами.</p>
<p><strong>Результат.</strong> Набір пішов із шести тестів понад шістдесят секунд — 74 секунди за годинником — до 135 тестів, що проходять за 8,9, і це вкладає його у вікно, в якому він виконується за кожного збереження. Застереження в тому, що спільна фікстура лише для читання тепер є точкою зчеплення: тест, що його змінить, дасть падіння в іншому тесті, і швидкість набору залежить від дисципліни, якої компілятор не примушує.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Дістала ту половину ядра обміну повідомленнями, якої застосунок ніколи не використовував, — передавання резервної копії, зникомі повідомлення, редагування та повторне надсилання, підтверджені запрошення, проксі та політику шифрування, — ведучи кожен тест проти справжньої бібліотеки без заглушок.</title>
      <link>https://platform.engineer.company/uk/portfolio/reached-the-unused-half-of-the-messaging-core-161/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/reached-the-unused-half-of-the-messaging-core-161/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Раніше недосяжну половину ядра тепер ганяють тести проти справжньої бібліотеки, а обгортка несе найвищу підлогу в проєкті.</description>
      <category domain="https://platform.engineer.company/uk/categories/">API та інтеграції</category>
      <category domain="https://platform.engineer.company/uk/categories/">Backend‑розробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Backend- та API‑розробка</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Клієнт використовував приблизно половину того, що пропонує ядро обміну повідомленнями. Невикористана половина не була маловідомою — перенесення резервних копій між пристроями, зникомі повідомлення, редагування та повторне надсилання повідомлень, перевірені запрошувальні посилання, налаштування проксі та політика шифрування для розмови. Кожне з цього є можливістю, якої очікував би користувач, і кожне було невипробуваною ділянкою C‑інтерфейсу, а це небезпечніший факт, бо невипробувана ділянка C‑інтерфейсу — саме там, де живуть помилки володіння.</p>
<p><strong>Завдання.</strong> Недосяжну спроможність треба було задіяти й покрити, і тести мали виконуватися проти справжньої бібліотеки, а не проти заміщувача.</p>
<p><strong>Дія.</strong> Прийнятим правилом було жодних імітацій для ядра. Імітація C‑інтерфейсу кодує переконання розробника про те, що робить бібліотека, а кожен вартий пошуку дефект тут є місцем, де це переконання хибне, — тож пройдений тест на імітації є свідченням про імітацію. Натомість тести створюють справжні облікові записи в тимчасових каталогах, ганяють справжню бібліотеку і стверджують про те, що вона насправді повертає, і кожен набір прибирає власний стан. Саме це зробило покриття змістовним: задіяти перенесення резервних копій означало обробити машину станів справжнього перенесення та її шляхи відмов, а задіяти перевірені запрошення означало сконструювати справжній формат посилання й дати бібліотеці його розібрати. Підлоги покриття задано на кожен шар окремо, а не одним числом: вісімдесят чотири відсотки для обгортки ядра, сімдесят п&rsquo;ять для допоміжних функцій і шістдесят п&rsquo;ять для моделей, з тим міркуванням, що шар, який торкається сирих вказівників, слід тримати найвище, а модель, яка здебільшого складається зі збережених властивостей, не варто набивати тестами заради середнього.</p>
<p><strong>Результат.</strong> Раніше недосяжну половину ядра тепер ганяють тести проти справжньої бібліотеки, а обгортка несе найвищу підлогу в проєкті. Ціною є швидкість і передбачуваність: тести проти справжньої бібліотеки повільніші за імітації, і вони можуть падати з причин середовища, а це ціна за їхню здатність падати зі справжніх.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Проаудитувала 644 крейти Rust на сумісність ліцензій при кожній збірці й довела, що перевірка спрацьовує, переписавши ліцензію одного крейта й перемістивши зафіксовану ревізію ядра без перегенерації.</title>
      <link>https://platform.engineer.company/uk/portfolio/audited-644-rust-crates-for-licence-compatibility-163/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/audited-644-rust-crates-for-licence-compatibility-163/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Становище щодо поширення перевіряють за кожного збирання, і про перевірку відомо, що вона працює, бо її змусили впасти, а не бо вона ніколи нічого не сказала.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Data Governance</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/services/">Data Governance та якість даних</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Вкомпонувати ядро на Rust у програму, яку випускають, означає випускати все, від чого те ядро залежить. Граф залежностей налічує 644 крейти. Кожен несе ліцензію, деякі несуть більш ніж одну, а єдиний копілефтний крейт, що прибуває на три рівні нижче через рутинне підняття версії, змінює те, за якими умовами можна поширювати програму в цілому, — мовчки, у файлі блокування, якого ніхто не читає рядок за рядком.</p>
<p><strong>Завдання.</strong> Ліцензійне становище треба було перевіряти за кожного збирання, а не переглянути один раз, з явним переліком дозволеного, щоб зміна в графі була відмовою збирання, а не відкриттям, яке хтось зробить згодом.</p>
<p><strong>Дія.</strong> Перевірка розв&rsquo;язує повний транзитивний граф і звіряє ліцензійний вираз кожного крейта з переліком умов, які проєкт приймає, належно обчислюючи булеві вирази — крейт, що пропонує вибір із двох ліцензій, прийнятний, якщо в переліку є будь‑яка з них, а крейт, що вимагає обох, прийнятний, лише якщо в переліку є обидві. Усе, що не збіглося, валить збирання, а не попереджає, і додавання умови до переліку дозволеного є свідомим редагуванням із причиною. Перевірку, що ніколи не падала, не відрізнити від тієї, що падати не здатна, тож її змусили впасти навмисно, двічі. Один раз переписавши ліцензійний вираз крейта на те, чого перелік не приймає, а це є формою крейта, що змінює свої умови вище за течією між версіями, — випадок, якого не ловить жоден людський перегляд, бо сам крейт не новий. Один раз зсунувши закріплену ревізію ядра без перегенерації перевірки, а це є формою підняття ядра, що тихо приносить із собою нову залежність. Обидві провокації завалили збирання, як і задумано, і перевірку лишили на місці, а не розширили.</p>
<p><strong>Результат.</strong> Становище щодо поширення перевіряють за кожного збирання, і про перевірку відомо, що вона працює, бо її змусили впасти, а не бо вона ніколи нічого не сказала. До того, як вона з&rsquo;явилася, і пакет, і файл ліцензії, і власний README проєкту робили заяву про 644 крейти, якої ніщо не перевіряло. Межа точна, і її не слід перебільшувати: перевірка читає оголошені ліцензійні метадані, а метадані можуть бути хибними чи неповними. Вона не доводить нічого про крейт, що оголошує себе хибно, і вона не є юридичною порадою.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Втримала чотири репозиторії на одному стандарті історії — конвенційному, без емодзі, без рядків атрибуції, із примусом через хук повідомлення коміту — поряд із 48 документами інструкцій, що керують тим, як виконується робота.</title>
      <link>https://platform.engineer.company/uk/portfolio/held-five-repositories-to-one-history-standard-165/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/held-five-repositories-to-one-history-standard-165/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Чотири репозиторії поділяють один формат історії та одну структуру інструкцій, обидва примусово застосовані хуками, а не дисципліною.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Agile та Scrum</category>
      <category domain="https://platform.engineer.company/uk/categories/">DevOps</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Технічне лідерство</category>
      <category domain="https://platform.engineer.company/uk/categories/">Управління проєктами</category>
      <category domain="https://platform.engineer.company/uk/services/">DevOps та автоматизація CI/CD</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічне лідерство та консалтинг</category>
      <category domain="https://platform.engineer.company/uk/services/">Управління проєктами (Agile)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Чотири репозиторії, збудовані за вісімнадцять місяців однією людиною, — це та ситуація, у якій процес найлегше пропустити, бо немає з ким координуватися, а ціну нечитної історії цілком платить майбутнє я, яке ще не скаржилося. Це також та ситуація, у якій неузгоджена історія найімовірніша, бо кожен репозиторій може зісковзнути у власні звички без нічого, що тягнуло б їх докупи.</p>
<p><strong>Завдання.</strong> Один стандарт для історії та один стандарт для інструкцій мали діяти в кожному репозиторії, де пишеться робота, і його треба було примусово застосовувати машинно, а не пам&rsquo;ятати.</p>
<p><strong>Дія.</strong> Стандартом комітів є конвенційний префікс, що називає різновид зміни, і область, тема під сталою довжиною, жодних емодзі й жодних рядків приписування будь‑якого штибу — останнє тому, що рядок, який дякує інструментові, не є фактом про зміну, а історія існує для фактів про зміни. Хук на повідомлення коміту відхиляє все, що не відповідає, у кожному репозиторії, що несе роботу, тож стандарт є властивістю репозиторію, а не того, хто комітить. Розподіл у найбільшому репозиторії показує, чим робота була насправді: 156 комітів із можливостями, 133 виправлення, 128 документації, 81 господарський, 26 переробок, 20 стилю, 5 продуктивності та 3 тестові. Документація достатньо близька до виправлень, щоб це помітити, і це наслідок другої половини всього цього — 48 інструкційних документів у чотирьох, кожен покриває одну область, кожен написано як правила, а не опис, і всі досяжні з єдиного вхідного документа на репозиторій, тож є одне місце, з якого почати. Лінтер документації примусово застосовує пофайлові бюджети розміру та належність до індексу, тож набір лишається придатним для навігації, а не розростається в архів.</p>
<p><strong>Результат.</strong> Чотири репозиторії поділяють один формат історії та одну структуру інструкцій, обидва примусово застосовані хуками, а не дисципліною. Чого це не робить, так це не робить історію доброю: формат перевіряють, а вміст — ні, тож тема, що відповідає формату й не описує нічого, проходить точнісінько так само добре, як та, що пояснює зміну.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Виміряла тринадцять адрес лише за власним журналом доступу вебсервера — без кукі, без трекерів і без сторонніх сервісів — маскуючи мережу клієнта в момент запису рядка та згортаючи результат у постійний архів із 21 денного показника та 20 місячних фасетів.</title>
      <link>https://platform.engineer.company/uk/portfolio/measured-thirteen-addresses-from-the-access-log-alone-166/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/measured-thirteen-addresses-from-the-access-log-alone-166/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Так вимірюються тринадцять адрес, і сайт не надсилає ні кукі, ні трекера, ні стороннього запиту, тож немає на що давати згоду й немає де виконатися тегу.</description>
      <category domain="https://platform.engineer.company/uk/categories/">Data Governance</category>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/services/">Data Governance та якість даних</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Сайт не мав жодного способу дізнатися, чи його хтось читає. Кожна звична відповідь на це коштує читачеві чогось &ndash; кукі, скрипт, піксель, хостована служба, що дізнається про відвідувача мимохідь, &ndash; і кожну з них було відхилено ще до першого рядка цієї роботи. Лишався власний журнал доступу вебсервера, єдиний запис, який існує й так, бо на запит треба відповісти.</p>
<p><strong>Завдання.</strong> Питання було в тому, чи можна збудувати корисний запис про читацьку аудиторію з рядка журналу, з якого вже вилучено ідентифікаційні частини, і чи можна це вилучення довести, а не пообіцяти.</p>
<p><strong>Дія.</strong> Маскування відбувається в момент запису рядка, а не під час прибирання потім, бо обіцянку не зберігати щось порушують, зберігши це й прибравши згодом. Сервер виводить адресу клієнта під двома іменами, і маскуються обидва &ndash; замаскувати одне читається в конфігурації як правильне, доки повна адреса лежить на диску під іншим, і це знайшла лише жива перевірка. Сім заголовків із переадресованими адресами відкидаються цілком, бо кодувальник пише мапу заголовків точно так, як її надіслав клієнт, і відвідувач за корпоративним проксі інакше заніс би власну повну адресу у файл під іменем, на яке жодна маска не дивилася. Заголовок кукі, заголовок авторизації та ефемерний порт джерела йдуть тим самим шляхом, а рядки запиту відрізаються, перш ніж будь‑що прочитає шлях, тож ані слова, набрані в пошуковій системі, ані слова, набрані у власному пошуку сайту, не можуть дістатися жодного файлу. Збір &ndash; це витягування: скрипт лише на стандартній бібліотеці читає потоком живий журнал і його згорнутих побратимів на хості й друкує підрахунки, а не рядки, обмежений кількістю різних шляхів, а не розміром журналу, бо машина має 464 МБ. Зберігання вимагало двох механізмів, а не одного, після того як стеля за розміром і стеля за часом на одній полиці означали, що менша перемагає мовчки &ndash; жвавий сайт тримав десять днів замість тридцяти, а тихий не видаляв нічого. Журнал переживає архів із 21 підрахунку на день і 20 фасетів на місяць, злитих, а не дописаних, за правилом, що вікно може лише недоспостерігати, із сумою поряд із кожним рейтингом, щоб урізана таблиця сама казала, скільки вона відкинула.</p>
<p><strong>Результат.</strong> Так вимірюються тринадцять адрес, і сайт не надсилає ні кукі, ні трекера, ні стороннього запиту, тож немає на що давати згоду й немає де виконатися тегу. Задум відмовляє більше, ніж відповідає &ndash; унікальні відвідувачі, пошукові запити, шлях відвідувача сайтом, час на сторінці, кліки, географія та пристрій тут усі без відповіді й самі про це кажуть, &ndash; а межі друкуються поряд із числами, а не ховаються дрібним шрифтом, бо грубе число, прочитане як точне, гірше за відсутнє.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Змусила шість збирачів звітів повідомляти ту частину свого входу, яку вони так і не прочитали — файли, що лишилися закритими, непроінстальовані проби, нерозпізнані рядки журналу, — і підігнала пороги до 116 виміряних зразків, з&#39;ясувавши, що сліпий збір і здоровий хост дають ту саму сторінку.</title>
      <link>https://platform.engineer.company/uk/portfolio/made-six-collectors-state-what-they-never-read-167/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/made-six-collectors-state-what-they-never-read-167/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Сторінка чисел цієї платформи тепер несе власні сліпі зони поряд зі своїми знахідками. Жоден із самовимірів не є ґейтом, і це сказано, а не мається на увазі:…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Python</category>
      <category domain="https://platform.engineer.company/uk/categories/">Автоматизація та CI/CD</category>
      <category domain="https://platform.engineer.company/uk/categories/">Документація</category>
      <category domain="https://platform.engineer.company/uk/categories/">Моніторинг та observability</category>
      <category domain="https://platform.engineer.company/uk/categories/">Надійність і резервне копіювання</category>
      <category domain="https://platform.engineer.company/uk/categories/">Тестування та QA</category>
      <category domain="https://platform.engineer.company/uk/services/">Надійність та моніторинг (SRE)</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Технічна документація</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Шість збирачів лише для читання перетворювали живий хост на Markdown, і жоден із них не фіксував ані власного часу роботи, ані файлів, які не зміг відкрити, ані вхідних даних, які пропустив. Кілька мали шляхи помилок, що ковтали помилку цілком, а це дає певну й небезпечну форму звіту: сторінку чисел, яка виглядає повною та здоровою незалежно від того, чи щось узагалі було прочитано. Згорнутий журнал, що надходить обрізаним, прибирає весь свій проміжок з кожного числа на сторінці, а тиждень відсутнього трафіку читається точно як тихий тиждень. Дзеркало, чий демон змінив формат журналу, дає той самий нуль, що й дзеркало, якого ніхто не відвідував. Кожна проба у звіті безпеки стоїть за перевіркою наявності інструмента, тож хост без інструментів фаєрвола, сокетів і блокувань не показував ані правил, ані сокетів, ані в&rsquo;язниць &ndash; візуальний підпис замкненого хоста, а насправді сліпого.</p>
<p><strong>Завдання.</strong> Дві речі мали стати неможливими для сплутування зі здоров&rsquo;ям. Звіт мав казати, що вважається поганим, а не лишати це на людину, і кожен збирач мав казати, скільки коштував його власний збір і якої частки свого входу він не зміг використати.</p>
<p><strong>Дія.</strong> Пороги підігнали до 116 зразків, які звіт метрик уже виміряв, і ніколи до здогадки, а поряд із межами записали спостережені діапазони. Оцінювання знаходить кожен стовпець за іменем, а не за позицією, і відмовляється оцінювати рядок, у якому кількість значень не збігається з кількістю підписів, &ndash; саме це захищає його від зміни формату годинника, що зсуває кожен підпис на один. Далі звіт розрізняє три наслідки замість двох: порушення, відсутність порушення і неоцінено, бо ніщо цього не виміряло. З боку збору кожен тепер повідомляє свій час роботи і свою сліпоту &ndash; файли прочитані проти файлів нечитних, рядки журналу прочитані проти рядків розпізнаних, репозиторії, які git відмовився читати, пораховані, а не показані нулем, джерела опитані проти джерел, що відповіли, проби запитані проти проб непроінстальованих, &ndash; і кожен такий рядок друкується навіть тоді, коли відповідь нуль, бо рядок, що зникає, коли порожній, &ndash; це та сама тиша в іншій формі. Кожен шаблон отримав явну гілку для виводу, написаного збирачем, старшим за нього самого.</p>
<p><strong>Результат.</strong> Сторінка чисел цієї платформи тепер несе власні сліпі зони поряд зі своїми знахідками. Жоден із самовимірів не є ґейтом, і це сказано, а не мається на увазі: до часу роботи збирача не підігнано жодної межі, тож збір, що подвоївся, видно, і він нікого не спинить, а щоб підігнати таку межу, потрібна база з реального хоста, якої ця робота свідомо не вигадувала. Наявні межі &ndash; це денні середні, тож хост, що торкається стелі на хвилину, тут нічого не перетинає: це ловить перемикач кожні чверть години, жоден не замінює іншого, і обидва звіти кажуть про це на сторінці.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Опублікувала сайт як onion‑дзеркало в Tor на читабельній адресі, що починається з engineer, з ключем, згенерованим поза хостом, тож він ніколи не потрапив ні до цього репозиторію, ні на ноутбук, і лишила ці двері єдиними з чотирьох, які ніколи не рахують.</title>
      <link>https://platform.engineer.company/uk/portfolio/published-the-site-as-a-tor-onion-mirror-on-a-readable-168/</link>
      <guid isPermaLink="true">https://platform.engineer.company/uk/portfolio/published-the-site-as-a-tor-onion-mirror-on-a-readable-168/</guid>
      <pubDate>Fri, 09 Oct 2026 14:31:15 +0200</pubDate>
      <description>Сайт має четверо дверей до однієї збірки, і ці -- єдині, яких ніколи не рахують. Запити Gemini та з&#39;єднання Gopher підраховують щодня без адреси й без шляху; в…</description>
      <category domain="https://platform.engineer.company/uk/categories/">Linux та сервери</category>
      <category domain="https://platform.engineer.company/uk/categories/">Безпека</category>
      <category domain="https://platform.engineer.company/uk/categories/">Веброзробка</category>
      <category domain="https://platform.engineer.company/uk/categories/">Інфраструктура</category>
      <category domain="https://platform.engineer.company/uk/categories/">Системне адміністрування</category>
      <category domain="https://platform.engineer.company/uk/services/">Infrastructure as Code</category>
      <category domain="https://platform.engineer.company/uk/services/">Безпека та керування доступом</category>
      <category domain="https://platform.engineer.company/uk/services/">Розробка вебсайтів та CMS</category>
      <category domain="https://platform.engineer.company/uk/services/">Системне адміністрування</category>
      <content:encoded><![CDATA[<p><strong>Ситуація.</strong> Сайт уже відповідав на трьох протоколах з однієї збірки. Читач, якому треба було дістатися до нього, не виказуючи, що він дістався, усе ще робив гак через вихідний вузол до звичайної адреси, а це слабше за власні двері. Очевидне заперечення проти четвертих дверей &ndash; це фаєрвол, і воно не діє: демон анонімності виходить у мережу, будуючи вихідні ланцюги, тож ніхто не дзвонить усередину, жоден порт не відкривається, і жодному з двох шарів фаєрвола нема чого узгоджувати.</p>
<p><strong>Завдання.</strong> Дзеркало мало віддавати ті самі сторінки, що й звичайна адреса, бути опублікованим там, де опубліковані інші дзеркала, нести адресу, яку людина може прочитати вголос, а не випадковий рядок, і ніколи не дозволити приватному ключу, який і є адресою, торкнутися цього репозиторію чи ноутбука.</p>
<p><strong>Дія.</strong> Роль встановлює демон із власного пакета дистрибутива, пише конфігурацію з вимкненим вихідним портом проксі й відмовляється перезаписувати особу, якої не генерувала, &ndash; тож ключ, покладений рукою, просто використовується. Читабельну адресу не можна обрати, лише знайти: адреса &ndash; це відкритий ключ у base32, тож префікс купують, генеруючи пари ключів, доки одна з них випадково не закодує потрібні літери, і кожен символ коштує в тридцять два рази більше за попередній. Куплений префікс читається як власна назва компанії. Адреса &ndash; це оголошене значення в інвентарі, і кожне зведення стверджує, що справжній файл особи на хості збігається з ним, тож підмінений ключ зі застарілим оголошенням валить запуск, а не мовчить. Ключ ловлять обидві сторожі секретів, після того як було виміряно, що очевидний шаблон для файлу ключа збігається з ключем розгортання й проминає цей. Виведення з обігу випадкової адреси, з якою дзеркало вийшло, було поетапним переходом, а не перемикачем, тож опублікована адреса працювала, доки публікувалася читабельна. Крок, що видавався останнім, ним не був: ключ ліг правильно, а зведення повідомило про відсутність змін, бо ніщо ще не називало нову теку, тож нова адреса так і не була опублікована &ndash; тепер роль валиться на особі на диску, якої не називає жодна служба.</p>
<p><strong>Результат.</strong> Сайт має четверо дверей до однієї збірки, і ці &ndash; єдині, яких ніколи не рахують. Запити Gemini та з&rsquo;єднання Gopher підраховують щодня без адреси й без шляху; в onion немає лічильника й немає прапорця, щоб його додати, бо порахувати там читача &ndash; це саме те єдине, заради запобігання чому протокол існує, і сліпота тут ціна позиції, а не прогалина у звітності. Дзеркало окупилося ще й як друга думка: його перші читачі сиділи на іншому рушії браузера, який не реалізує керовану прокруткою анімацію, на яку спирався колофон, тож кожен із них отримав колофон, намальований поверх головної сторінки. Це був справжній дефект звичайного сайту, знайдений аудиторією, яка не мала іншого способу про нього повідомити.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
