Self-code review – це практика, коли розробник самостійно аналізує свій код перед тим, як відправити його на зовнішній рев’ю або змерджити у main branch. Її мета – знайти помилки, підвищити якість, узгодженість і зрозумілість коду ще до командного перегляду.
У 2025 році я вважаю використання AI для аналізу власного коду невід’ємною частиною процесу self-code review. Зазвичай я запускаю кілька циклів AI code review, перш ніж позначити pull request як готовий.
Що я для цього використовував
🤖 AI Self-Review (JetBrains)
🤖 Codex (OpenAI)
🤖 GitHub Copilot
Для мене GitHub Copilot показав найвищу якість аналізу та швидкість роботи. Навіть без додаткової кастомізації (яку, утім, рекомендую налаштувати), Copilot ефективно підсвічує потенційні проблеми, пропонує релевантні фікси й адаптується до стилю коду. Його можна легко перезапускати кілька разів.
👉 Рекомендація: тримайте Copilot увімкненим за замовчуванням для всіх pull request’ів – це забезпечує відчутний приріст якості ще до командного рев’ю.
Деякі спостереження
1️⃣ AI перевершує людину у виявленні очевидних помилок.Наприклад, сьогодні AI помітив, що я переплутав min і max у розрахунку high/low для свічкових графіків – банальна, але критична помилка, яку ШІ знаходить миттєво.
2️⃣ AI поступається у забезпеченні єдиної стилістики та узгодженості коду на рівні всієї системи.Він не розуміє архітектурного контексту, внутрішніх домовленостей чи специфіки доменної логіки. Тут досвід і відчуття цілісності системи залишаються прерогативою людини.
3️⃣ AI майже не здатен виявити пропущене у pull request. Нажаль людина теж.
TL;DR; Human in the Loop – найкраща стратегія використання AI.
❤32👍19🥱5🔥1
Хочу показати вам різницю між продуктовими та платформенними інженерами.
Учора в розсилці ADVENTURES IN NODELAND, яку веде Matteo Collina, вийшла чудова стаття — Noop Functions vs Optional Chaining: A Performance Deep Dive. У ній автор детально пояснює, чому Noop function працює швидше за Optional chaining.
Не буду вам переказувати цю статтю – просто скажу, що вона чудово ілюструє, на чому зосереджені платформенні інженери. Для платформенних інженерів подібні оптимізації важливі, адже вони безпосередньо впливають на швидкодію фреймворків і бібліотек.
Натомість продуктові інженери фокусуються на тому, що створює затримки в роботі продукту – зазвичай це мережеві виклики та база даних. Тому витрачати час, щоб виграти кілька наносекунд у коді, немає сенсу, якщо можна зменшити затримку на сотні мілісекунд, оптимізувавши business flow або покращивши індексацію бази даних.
Платформенні інженери створюють технічні інструменти, а продуктові інженери використовують ці інструменти, щоб створювати цінність для кінцевого користувача. Обидві ролі важливі – просто вони розв’язують різні завдання, і підходи, які працюють у одній ролі, часто не підходять для іншої.
Учора в розсилці ADVENTURES IN NODELAND, яку веде Matteo Collina, вийшла чудова стаття — Noop Functions vs Optional Chaining: A Performance Deep Dive. У ній автор детально пояснює, чому Noop function працює швидше за Optional chaining.
// Підхід 1: Noop function
function noop() {}
function testNoop() {
noop();
}
// Підхід 2: Optional chaining
const a = {}
function testOptionalChaining() {
a.b?.fn?.();
}
Не буду вам переказувати цю статтю – просто скажу, що вона чудово ілюструє, на чому зосереджені платформенні інженери. Для платформенних інженерів подібні оптимізації важливі, адже вони безпосередньо впливають на швидкодію фреймворків і бібліотек.
Натомість продуктові інженери фокусуються на тому, що створює затримки в роботі продукту – зазвичай це мережеві виклики та база даних. Тому витрачати час, щоб виграти кілька наносекунд у коді, немає сенсу, якщо можна зменшити затримку на сотні мілісекунд, оптимізувавши business flow або покращивши індексацію бази даних.
Платформенні інженери створюють технічні інструменти, а продуктові інженери використовують ці інструменти, щоб створювати цінність для кінцевого користувача. Обидві ролі важливі – просто вони розв’язують різні завдання, і підходи, які працюють у одній ролі, часто не підходять для іншої.
👍58🥱9❤6
Існує команда docker scout quickview, яка аналізує Docker-образ і показує короткий звіт про вразливості, залежності та базовий образ.
Вона корисна для швидкої оцінки безпеки контейнерів, особливо перед використанням образу у продакшн-середовищі.
Втім, якщо цієї команди немає (бо треба docker login), можна обійтися без неї – достатньо відкрити сторінку потрібного образу на hub.docker.com і перейти у вкладку Tags, де також відображається кількість вразливостей для кожної версії.
👉Приклад з Node.js
Під час воркшопів я використовую цю команду, щоб продемонструвати, чому варто обирати конкретну версію базового образу:
✅ node:22.x.x-alpine3.21
⚠️ а не просто node:22.x.x-alpine
🚫 і тим більше не node:22.x.x
Рекомендую спробувати самому:
Порівняйте результати – різниця у кількості вразливостей будє суттєвою.
👉Рекомендація
Команда docker scout quickview — це must-have інструмент перед тим, як використовувати будь-який образ, особливо коли його рекомендує AI. Також, якщо ви відповідаєте за налаштування CI/CD, рекомендую додати це у ваш pipeline, подібно до npm audit.
Вона корисна для швидкої оцінки безпеки контейнерів, особливо перед використанням образу у продакшн-середовищі.
Втім, якщо цієї команди немає (бо треба docker login), можна обійтися без неї – достатньо відкрити сторінку потрібного образу на hub.docker.com і перейти у вкладку Tags, де також відображається кількість вразливостей для кожної версії.
👉Приклад з Node.js
Під час воркшопів я використовую цю команду, щоб продемонструвати, чому варто обирати конкретну версію базового образу:
✅ node:22.x.x-alpine3.21
⚠️ а не просто node:22.x.x-alpine
🚫 і тим більше не node:22.x.x
Рекомендую спробувати самому:
docker scout quickview node:22
docker scout quickview node:22-alpine
docker scout quickview node:22-alpine3.21
Порівняйте результати – різниця у кількості вразливостей будє суттєвою.
👉Рекомендація
Команда docker scout quickview — це must-have інструмент перед тим, як використовувати будь-який образ, особливо коли його рекомендує AI. Також, якщо ви відповідаєте за налаштування CI/CD, рекомендую додати це у ваш pipeline, подібно до npm audit.
👍47❤11
У вересні мені написали з питанням: “А як проходить твій день?”
Нагадю що я CTO у стартапі.
Тож ось 6 годин із сьогоднішнього 👇
1️⃣ Виявив що хтось зробив тестовий DDoS на ~100k/s.
Порадів, що ми вже комусь цікаві 😄
Підняв Cloud Armor для захисту.
Артефакти: Terraform + Helm charts
2️⃣ Готував розділення моноліту на API / Worker.
(Вітаємо мікросервіси 🎉)
Артефакти: Mermaid-діаграма + код у межах рефакторингу
3️⃣ Перевірив кількох користувачів на запит operations-відділу.
Артефакт: нова діаграма в Looker Data Studio
4️⃣ Code review.
Цікаво: підказав FE-інженеру, що баг не в нашому коді, а через регресію після оновлення залежностей
5️⃣ Дзвінки: дейлік, weekly planning.
Артефакти: нові задачі в Linear
Можна було б піти інженером у FAANG і фокусуватись на “кнопці-лайк”, але драйв стартапів мені набагато ближчий
Нагадю що я CTO у стартапі.
Тож ось 6 годин із сьогоднішнього 👇
1️⃣ Виявив що хтось зробив тестовий DDoS на ~100k/s.
Порадів, що ми вже комусь цікаві 😄
Підняв Cloud Armor для захисту.
Артефакти: Terraform + Helm charts
2️⃣ Готував розділення моноліту на API / Worker.
(Вітаємо мікросервіси 🎉)
Артефакти: Mermaid-діаграма + код у межах рефакторингу
3️⃣ Перевірив кількох користувачів на запит operations-відділу.
Артефакт: нова діаграма в Looker Data Studio
4️⃣ Code review.
Цікаво: підказав FE-інженеру, що баг не в нашому коді, а через регресію після оновлення залежностей
5️⃣ Дзвінки: дейлік, weekly planning.
Артефакти: нові задачі в Linear
Можна було б піти інженером у FAANG і фокусуватись на “кнопці-лайк”, але драйв стартапів мені набагато ближчий
👍64❤8🔥4🤝1
У п’ятницю, 31 жовтня о 21:00 за Києвом, ми зробимо стрім із Віталієм Ратушним.
Обговоримо останні новини зі світу AI. Саме штучний інтелект запропонував назву — AI Insights — October 2025 Edition.
Мета стріму — зробити огляд ключових подій та трендів за останній місяць і поділитися інсайтами.
Надсилайте в коментарях свої запитання та новини, які ви хотіли б побачити у стрімі,
і перегляньте коментарі інших — ставте лайки тим темам, що здаються вам найцікавішими. Це допоможе нам визначити, що взяти в огляд.
Обговоримо останні новини зі світу AI. Саме штучний інтелект запропонував назву — AI Insights — October 2025 Edition.
Мета стріму — зробити огляд ключових подій та трендів за останній місяць і поділитися інсайтами.
Надсилайте в коментарях свої запитання та новини, які ви хотіли б побачити у стрімі,
і перегляньте коментарі інших — ставте лайки тим темам, що здаються вам найцікавішими. Це допоможе нам визначити, що взяти в огляд.
❤28👍7
🕘 Через 45 хвилин починаємо стрім!
Буде цікаво, легко і по-людськи. Побачимось о 21:00
Чекаємо вас на стрімі, щоб відповісти на ваші питання та коментарі
👀 https://www.youtube.com/live/34Yxho1Avu0
Буде цікаво, легко і по-людськи. Побачимось о 21:00
Чекаємо вас на стрімі, щоб відповісти на ваші питання та коментарі
👀 https://www.youtube.com/live/34Yxho1Avu0
👍9❤3
Сьогодні хочу поділитися підходом до обробки помилок бази даних у Nest.js за допомогою Exception Filter.
Ключові моменти:
1. Перевірка бізнес-логіки на рівні БД – використання UNIQ/CHECK-обмежень у схемі бази даних.
2. Робота з кодами помилок драйвера – наприклад, обробка стандартних кодів PostgreSQL (23505, 23514, 40001 тощо).
3. Транзакції через typeorm-transactional – оскільки транзакції через
Приклад фільтра, щоб проілюструвати ідею:
PS Цей метод не скасовує, а доповнює моніторинг журналу помилок вашої бази даних.
Ключові моменти:
1. Перевірка бізнес-логіки на рівні БД – використання UNIQ/CHECK-обмежень у схемі бази даних.
2. Робота з кодами помилок драйвера – наприклад, обробка стандартних кодів PostgreSQL (23505, 23514, 40001 тощо).
3. Транзакції через typeorm-transactional – оскільки транзакції через
@Transaction, фільтр є єдиним місцем, де можна перехопити помилку на рівні запиту.Приклад фільтра, щоб проілюструвати ідею:
import type { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
import { Catch } from '@nestjs/common';
import { Response } from 'express';
import { DatabaseError } from 'pg';
import { QueryFailedError } from 'typeorm';
@Catch(QueryFailedError)
export class TypeormExceptionFilter implements ExceptionFilter {
catch(exception: QueryFailedError, host: ArgumentsHost) {
const context = host.switchToHttp();
const response = context.getResponse<Response>();
if (exception.driverError instanceof DatabaseError) {
if (exception.driverError.code === '40001') {
return response.status(409).send({
message: 'Conflict. Please try again later.',
});
}
if (exception.driverError.code === '23505') {
return response.status(400).send({
message: 'Should be unique',
});
}
if (exception.driverError.code === '23514') {
switch (exception.driverError.constraint) {
case 'not_negative_balance_check': {
return response.status(400).send({
message: 'Not enough balance',
});
}
//…
}
}
}
throw exception;
}
}
PS Цей метод не скасовує, а доповнює моніторинг журналу помилок вашої бази даних.
❤20👍8
Під час оновлення eslint-plugin-unicorn до версії 62 я дізнався про String.raw. Він повертає «сирий» рядок без обробки escape-послідовностей.
Приклад коду:
Як же мені бракувало цього знання під час написання міграцій з регулярними виразами CHECK для PostgreSQL. У цих міграціях Unicorn покращив код додавши String.raw
Приклад коду:
// без String.raw
const file = `C:\\windows\\temp\\myapp-${process.pid}.log`;
const re = `\\d{4}-\\d{2}-\\d{2}`;
// із String.raw
const file = String.raw`C:\windows\temp\myapp-${process.pid}.log`;
const re = String.raw`\d{4}-\d{2}-\d{2}`;
Як же мені бракувало цього знання під час написання міграцій з регулярними виразами CHECK для PostgreSQL. У цих міграціях Unicorn покращив код додавши String.raw
1👍22👀3😨2
Сьогодні мав Zoom-coffee з інженером, який перейшов у формат solopreneur (тобто працює самостійно, поєднуючи ролі інженера, підприємця та продакт-менеджера).
Він зараз шукає оптимальну бізнес-модель і активно автоматизує власні процеси за допомогою агентів, написаних на Python, використовуючи підхід vibe coding.
Знайомий поділився болючою історією: витратив понад 20 годин на пошук і виправлення бага, спричиненого тим, що в одних місцях було написано
Мій особистий висновок із цієї історії: у системному промті варто одразу вказувати, який саме варіант англійської мови (наприклад, USA, що є де-факто стандартом) слід використовувати для документації та коду. Інакше LLM може обрати власний варіант написання, виходячи з контексту.
Він зараз шукає оптимальну бізнес-модель і активно автоматизує власні процеси за допомогою агентів, написаних на Python, використовуючи підхід vibe coding.
Знайомий поділився болючою історією: витратив понад 20 годин на пошук і виправлення бага, спричиненого тим, що в одних місцях було написано
cancelled, а в інших — canceled. Зрештою з’ясувалося, що розбіжність походить ще з документації, де описувався план для coding-агентів. Тепер він проводить рефакторинг, щоб впровадити StrEnum для уніфікації.Мій особистий висновок із цієї історії: у системному промті варто одразу вказувати, який саме варіант англійської мови (наприклад, USA, що є де-факто стандартом) слід використовувати для документації та коду. Інакше LLM може обрати власний варіант написання, виходячи з контексту.
👍28🔥7🤔5❤4😁4
Для тих, хто у Львові — цікавий мітап FRONTEND CASE EVENING від Skelar
🗓 27 листопада, 18:30
💸 Участь безкоштовна (офлайн + онлайн)
📍Львів (офлайн + онлайн)
🔗 ЗАРЕЄСТРУВАТИСЯ
Я б сам сходив, тому короткий огляд доповідей:
🎤 Як ми інтегрували AI у процес код-рев’ю, Ігор Бойко (Liven)
Я теж використовую AI у код-рев’ю — цікаво дізнатись, як це працює в мобільній розробці.
🎤 Коли дизайн-система має стати окремим продуктом, Тетяна Мельник (Preply)
Як CTO я часто думаю, що дизайн-системи — це зайві витрати. Але бізнес і дизайнери хочуть вирізнятися, тож досвід Preply буде цікавим.
🎤 Тема: TBA, Юрій Артюх (Coderiver)
Його доповіді завжди технічно глибокі й натхненні. Що б не розповідав - буде варто почути.
🎤 Як ми побудували кастомний пошуковий двигун на Next.js, Юрій Куцин (RiseGuide)
Я уникаю Next.js через поганий DevExp, тож мені менш цікаво.
І, звісно, нетворкінг на афтерпаті. Офлайн зараз рідкість, але буде стрім та запис
🗓 27 листопада, 18:30
💸 Участь безкоштовна (офлайн + онлайн)
📍Львів (офлайн + онлайн)
🔗 ЗАРЕЄСТРУВАТИСЯ
Я б сам сходив, тому короткий огляд доповідей:
🎤 Як ми інтегрували AI у процес код-рев’ю, Ігор Бойко (Liven)
Я теж використовую AI у код-рев’ю — цікаво дізнатись, як це працює в мобільній розробці.
🎤 Коли дизайн-система має стати окремим продуктом, Тетяна Мельник (Preply)
Як CTO я часто думаю, що дизайн-системи — це зайві витрати. Але бізнес і дизайнери хочуть вирізнятися, тож досвід Preply буде цікавим.
🎤 Тема: TBA, Юрій Артюх (Coderiver)
Його доповіді завжди технічно глибокі й натхненні. Що б не розповідав - буде варто почути.
🎤 Як ми побудували кастомний пошуковий двигун на Next.js, Юрій Куцин (RiseGuide)
Я уникаю Next.js через поганий DevExp, тож мені менш цікаво.
І, звісно, нетворкінг на афтерпаті. Офлайн зараз рідкість, але буде стрім та запис
👍12🔥5
"Я уникаю Next.js через поганий DevExp" - розшифруйте будь ласка.
Next.js — це закрита екосистема, яка обмежує вибір технологій і підходів. Ось чому:
1️⃣ Деплой та залежність від Vercel
Для розгортання Next.js або потрібно використовувати Vercel, або вирішувати безліч додаткових завдань на власному хостингу.
Команда Next.js свідомо блокує покращення DevExp для сторонніх платформ. Я це розумію: вони не хочуть створювати конкурентів своєму основному продукту.
2️⃣ Складне усунення помилок
Дуже важко зрозуміти джерело проблеми: це Server Components, Turbopack, сам Next.js чи сторонній пакет.
3️⃣ Надмір кількох неявних конвенцій
У фреймворку багато прихованих правил (file-system conventions), які не перевіряються лінтерами або самим Next.js.
Було б логічно, якби команда дозволила явно зазначати в конфігурації: «ми дотримуємося цієї конвенції», і отримувати помилки або попередження, якщо її порушено.
4️⃣ Монолітність архітектури
Підхід “build APIs with Next.js” сприяє створенню монолітних застосунків замість модульної архітектури з окремими деплоями, як у монорепозиторіях.
Що я використовую натомість:
React Router v7 — дає більше контролю, прозорості й передбачуваності під час розробки.
👍55❤6🔥3
Рік тому Heroku Open Sources the Twelve-Factor App Definition
Я хотів би сказати, як це круто, що проєкт теперь з OpenSource/OpenContribution, а тому тепер рухається швидше.
Але, на жаль, це не так.
Приклади:
🤔 Питання з використанням файлової системи, яка монтується як Volume для збереження конфігурації, досі не вирішене. А це один зі стандартних підходів у Cloud Native/Kubernetes.
🤔 Чудова ініціатива Twelve-Factor for Generative AI and Agentic Systems за пів року так і не отримала жодного внеску.
Причина, як мені здається, банальна: в учасників немає матеріальної зацікавленості працювати. Тому й немає прогресу.
Я хотів би сказати, як це круто, що проєкт теперь з OpenSource/OpenContribution, а тому тепер рухається швидше.
Але, на жаль, це не так.
Приклади:
🤔 Питання з використанням файлової системи, яка монтується як Volume для збереження конфігурації, досі не вирішене. А це один зі стандартних підходів у Cloud Native/Kubernetes.
🤔 Чудова ініціатива Twelve-Factor for Generative AI and Agentic Systems за пів року так і не отримала жодного внеску.
Причина, як мені здається, банальна: в учасників немає матеріальної зацікавленості працювати. Тому й немає прогресу.
🥱2😐2👍1🤔1
Учора вийшла Gemini 3. Перше враження від Code generation with Gemini 3 Pro (High): краще до чого я маю доступ.
Як це спробувати?
- https://aistudio.google.com/ – vibe coding platform
- https://geminicli.com/ – coding agent that you can run locally from your terminal. Аналог OpenAI Codex CLI, Aider, Claude Code, etc
- https://antigravity.google/ – ще один VS Code з агентом, аналог Cursor/Windsurf/etc. Killer features: Browser Subagent, Artifacts
Як це спробувати?
- https://aistudio.google.com/ – vibe coding platform
- https://geminicli.com/ – coding agent that you can run locally from your terminal. Аналог OpenAI Codex CLI, Aider, Claude Code, etc
- https://antigravity.google/ – ще один VS Code з агентом, аналог Cursor/Windsurf/etc. Killer features: Browser Subagent, Artifacts
👍39
16-17 грудня буду на конференції WAWTECH із доповіддю: “AI Driven Development for the Sane”.
Розповім про здоровий глузд у розробці та чому Vibe Coding варто навчати менеджерів, а не інженерів.
Промокод на знижку 20% для підписників: NODEJSRECIPES20
Розповім про здоровий глузд у розробці та чому Vibe Coding варто навчати менеджерів, а не інженерів.
Промокод на знижку 20% для підписників: NODEJSRECIPES20
❤13🔥8
На співбесідах я завжди кажу щось на зразок:
I’m an expert in TypeScript, Node.js, AWS, but I’m not married to this tech stack and open to new approaches and tools.
Учора ця фраза з мого intro викликала у рекрутера уточнювальне запитання:
“Could you tell me more about this in detail?”
Відверто кажучи, тут я трохи розгубився. У мене не було заздалегідь заготовленої відповіді на таке запитання. Але мене врятувала кмітливість. За кілька годин до цього я заповнював опитувальник Auth0 (той, що на скрині).
Я просто сказав: “Let me share my screen”, відкрив опитувальник і пройшовся по пунктах, показавши, з якими інструментами працював і в яких проєктах. Фактично це був стислий переказ мого CV, але з tech stack focus.
Мораль дуже проста:
1) Ваше резюме, швидше за все, не читали детально.
Його переглянули, але не аналізували. Тому підсвітити ключові моменти ще раз це ефективна стратегія.
2) Коли не знаєш, як краще відповісти – покажи. Це економить час, знімає ризик непорозумінь і допомагає говорити по суті.
❤33👍21😁1🤓1🤷1
Принципи роботи з таймзонами
Ось набір принципів, які в мене сформувалися на практиці роботи з таймзонами:
1. Timezone, як і locale, — це частина UX, тому її обробка має виконуватися на client-side, а не на server-side.
2. Комунікація client ↔ server здійснюється виключно в UTC.
Формат серіалізації — передавати значення як string чи як timestamp — визначає команда FE, але timestamp зазвичай має менший розмір і економніший у передачі.
3. Server-time завжди в UTC. Це гарантується на рівні коду ось так:
4. Дані в базі зберігаються як timestamp without time zone.
5. Якщо бізнес-логіка цього потребує, server зберігає user-timezone у DB та використовує його для розрахунків. Наприклад, користувач запитує: “Покажи мої події за вчора”.
6. Усі обчислення, що залежать від timezone, виконуються на рівні запитів до бази даних. Для цього використовуємо SQL-запити з AT TIME ZONE
Ось набір принципів, які в мене сформувалися на практиці роботи з таймзонами:
1. Timezone, як і locale, — це частина UX, тому її обробка має виконуватися на client-side, а не на server-side.
2. Комунікація client ↔ server здійснюється виключно в UTC.
Формат серіалізації — передавати значення як string чи як timestamp — визначає команда FE, але timestamp зазвичай має менший розмір і економніший у передачі.
3. Server-time завжди в UTC. Це гарантується на рівні коду ось так:
process.env.TZ = 'UTC'
4. Дані в базі зберігаються як timestamp without time zone.
5. Якщо бізнес-логіка цього потребує, server зберігає user-timezone у DB та використовує його для розрахунків. Наприклад, користувач запитує: “Покажи мої події за вчора”.
6. Усі обчислення, що залежать від timezone, виконуються на рівні запитів до бази даних. Для цього використовуємо SQL-запити з AT TIME ZONE
👍88❤13
Forwarded from DOU
⚡ Стартувало зимове зарплатне опитування DOU і рейтинг мов програмування
Чекаємо всіх айтівців — тих, хто живе в Україні та за кордоном. І спеціалістів усіх напрямів: розробників, QA, менеджерів, DevOps, маркетологів, сапорт, сейлз, HR тощо. Гайда до анкети! На це потрібно не більше 10 хвилин: https://dou.ua/goto/HHph
Чекаємо всіх айтівців — тих, хто живе в Україні та за кордоном. І спеціалістів усіх напрямів: розробників, QA, менеджерів, DevOps, маркетологів, сапорт, сейлз, HR тощо. Гайда до анкети! На це потрібно не більше 10 хвилин: https://dou.ua/goto/HHph
❤3🔥1😁1