<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AZ-Way</title><link>https://az-way-blog.web.app/en/</link><description>Recent content on AZ-Way</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 09 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://az-way-blog.web.app/en/index.xml" rel="self" type="application/rss+xml"/><item><title>A profile instead of willpower: how AZ-Way Lock keeps focus on iPhone, iPad and Mac</title><link>https://az-way-blog.web.app/en/posts/az-way-lock/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/az-way-lock/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;I don&amp;rsquo;t try to “spend less time on my phone” through willpower. I built a configuration profile in Apple Configurator that removes entertainment from my iPhone, iPad and Mac and makes bringing it back expensive. Count what&amp;rsquo;s inside, and the main thing becomes clear: 44 % of the blocked sites and 31 % of the blocked apps are not the content itself, but workarounds to reach it. After installing the profile, the &lt;code&gt;phone&lt;/code&gt; reason almost disappeared from az-log: 4 cases out of 5 on the first day and 1 out of 24 over the next eight.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="why-a-profile-and-not-willpower"&gt;Why a profile and not willpower&lt;/h2&gt;&#10;&lt;p&gt;In the post &lt;a href="https://az-way-blog.web.app/en/posts/az-log/"&gt;az-log&lt;/a&gt; I described how the very first row of the spreadsheet showed that I had missed or delayed four of five prayers because of my phone. The conclusion wasn&amp;rsquo;t “try harder” but “change the conditions”.&lt;/p&gt;</description></item><item><title>Angular 6 → 22: the upgrade path and where you trip up</title><link>https://az-way-blog.web.app/en/posts/angular-6-to-22/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/angular-6-to-22/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;There&amp;rsquo;s only one way to upgrade Angular across many versions: one major version at a time, with a green build and tests after each. Big breaks are rare, but they&amp;rsquo;re predictable: a new rendering engine, a new build system, standalone, signals, zone.js. Below is a map of the path from 6 to 22, what broke for us on the last steps (import cycles, overlays on top of everything, zone.js), and why in a monorepo you do this once rather than ten times.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="rule-number-one-one-version-at-a-time"&gt;Rule number one: one version at a time&lt;/h2&gt;&#10;&lt;p&gt;Angular releases a major version roughly every six months. The upgrade command:&lt;/p&gt;</description></item><item><title>CI from scratch on Nx affected: from “no pipeline” to 9 minutes for all staging apps</title><link>https://az-way-blog.web.app/en/posts/ci-nx-affected/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/ci-nx-affected/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;In a monorepo with dozens of apps, building everything on every commit is slow and pointless: most apps aren&amp;rsquo;t touched by the change. Nx can work out what&amp;rsquo;s affected — &lt;code&gt;nx affected&lt;/code&gt;. The difficulty isn&amp;rsquo;t the command but the question “affected compared to what?”. Below is the path from manual deploys with scripts to a pipeline that checks MRs and builds only what&amp;rsquo;s needed, and four pitfalls I stepped on along the way.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="point-zero-deploying-by-hand"&gt;Point zero: deploying by hand&lt;/h2&gt;&#10;&lt;p&gt;At first there was no pipeline. There was a shell script: build the app locally and copy the files to the server. The problems are obvious:&lt;/p&gt;</description></item><item><title>ESLint rules that fix things themselves: fixers, suggestions and Angular templates</title><link>https://az-way-blog.web.app/en/posts/eslint-fixer-angular-templates/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/eslint-fixer-angular-templates/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;In the previous post, &lt;a href="https://az-way-blog.web.app/en/posts/custom-eslint-rules/"&gt;custom-eslint-rules&lt;/a&gt;, the rule only found the mistake. The next step is for it to fix it. The main thing here isn&amp;rsquo;t technique but a boundary: &lt;code&gt;eslint --fix&lt;/code&gt; can be trusted only with a fix that &lt;strong&gt;never changes the code&amp;rsquo;s behaviour&lt;/strong&gt;. Everything else is a suggestion that a person applies themselves. Plus rules for Angular templates: they work the same way, only their tree is different.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="three-levels-of-help"&gt;Three levels of help&lt;/h2&gt;&#10;&lt;p&gt;A rule can do one of three things:&lt;/p&gt;</description></item><item><title>From 10+ copied Angular projects to one Nx monorepo</title><link>https://az-way-blog.web.app/en/posts/nx-monorepo-from-copies/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/nx-monorepo-from-copies/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;We had more than ten copies of one Angular app — one for each regional customer. We fixed a bug ten times, added a feature ten times, and every time something was forgotten somewhere. We gathered it all into one Nx monorepo: shared code in libraries, and a region&amp;rsquo;s app became a thin shell of ~25 files. Below: in what order to move things, how to draw boundaries between libraries, and where we got burned.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="the-problem-a-copy-is-a-debt-that-grows"&gt;The problem: a copy is a debt that grows&lt;/h2&gt;&#10;&lt;p&gt;The pattern is familiar. There&amp;rsquo;s an app for the first customer. A second one comes along: “we want the same, but with our logo and a couple of differences”. The quickest thing is to copy the folder. A year later there are ten copies, and:&lt;/p&gt;</description></item><item><title>Java OCA 8 through a frontend developer's eyes</title><link>https://az-way-blog.web.app/en/posts/java-oca-8-frontend/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/java-oca-8-frontend/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;I&amp;rsquo;m a frontend developer working with Angular and TypeScript, and I&amp;rsquo;m preparing for the Oracle Java SE 8 Programmer I certification (1Z0-808) with the book by Boyarsky and Selikoff. The goal is a junior or intern interview for Java (Spring) backend. In this post: progress in numbers, what each of the six chapters covers, where TypeScript habits lead to a wrong answer, and one or two LeetCode problems per chapter to reinforce it with code. Java and TypeScript syntax look alike, so the trickiest places are the ones where the code looks familiar but works differently.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="why-java-and-why-this-exam"&gt;Why Java and why this exam&lt;/h2&gt;&#10;&lt;p&gt;The goal is to be able to write backend in Java/Spring, not only frontend. A certificate by itself doesn&amp;rsquo;t get you a job. But preparing for it forces you to learn the core of the language down to the details, not “at Stack Overflow level”. The exam tests exactly the details: will this code compile, what will it print, which exception will it throw.&lt;/p&gt;</description></item><item><title>Migrating Tailwind v3 → v4 in a large monorepo</title><link>https://az-way-blog.web.app/en/posts/tailwind-v3-to-v4-monorepo/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/tailwind-v3-to-v4-monorepo/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;Tailwind v4 moved configuration from JavaScript to CSS and finds classes in files by itself. In an ordinary project that&amp;rsquo;s convenient. In a monorepo, where classes live in a dozen libraries outside the app, it&amp;rsquo;s the number one reason why “styles disappeared” after the upgrade. Below: what changes, four directives you can&amp;rsquo;t do without (&lt;code&gt;@import&lt;/code&gt;, &lt;code&gt;@config&lt;/code&gt;, &lt;code&gt;@source&lt;/code&gt;, &lt;code&gt;@reference&lt;/code&gt;), what to do with Sass, and how to lock in the result with a check in CI.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="what-changed-in-v4-in-plain-words"&gt;What changed in v4, in plain words&lt;/h2&gt;&#10;&lt;p&gt;Tailwind is a CSS generator. It reads your files, finds classes in them (&lt;code&gt;flex&lt;/code&gt;, &lt;code&gt;bg-primary&lt;/code&gt;, &lt;code&gt;px-4&lt;/code&gt;) and writes CSS only for the ones that are actually used.&lt;/p&gt;</description></item><item><title>Sentry in an Angular monorepo: from “users don't complain” to 6889 events in one group</title><link>https://az-way-blog.web.app/en/posts/sentry-angular-monorepo/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/sentry-angular-monorepo/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;Users almost never report bugs: they reload the page, grumble and move on. Sentry collects errors from every user&amp;rsquo;s browser with a readable stack and context. Below: how we connected it to all 17 apps of one monorepo at once, why it&amp;rsquo;s useless without source maps, how one wrongly reported error piled up 6889 events from 157 people, and what Sentry should not know about the user.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="why-you-need-it"&gt;Why you need it&lt;/h2&gt;&#10;&lt;p&gt;Nobody sees &lt;code&gt;console.error&lt;/code&gt; in a user&amp;rsquo;s browser. A tester checks one browser and one set of data. Real users are hundreds of combinations: an old Chrome on a work computer, a tab left open since yesterday, a slow network, permissions nobody on the team has.&lt;/p&gt;</description></item><item><title>Your own ESLint rules as a guard against repeated mistakes</title><link>https://az-way-blog.web.app/en/posts/custom-eslint-rules/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/custom-eslint-rules/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;Code review catches a mistake once. A linter rule catches it always: in every commit, for every developer, in CI. My rule is simple: if the same mistake reaches review a second time, it&amp;rsquo;s no longer a person&amp;rsquo;s mistake but a hole in the tooling. Next: a three-step ladder (an existing rule → a restriction with a message → your own rule), your own rule taken apart step by step, and how to tell whether it works at all.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="why-review-isnt-enough"&gt;Why review isn&amp;rsquo;t enough&lt;/h2&gt;&#10;&lt;p&gt;Review is done by a person. People get tired, rush, look at the logic and miss the small thing they&amp;rsquo;ve already seen ten times. And a new developer on the team doesn&amp;rsquo;t know about that small thing at all: it lives only in the heads of those who once fixed production because of it.&lt;/p&gt;</description></item><item><title>az-log: one row a day and the profile that locked my phone</title><link>https://az-way-blog.web.app/en/posts/az-log/</link><pubDate>Sat, 07 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/az-log/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;az-log is a Google spreadsheet where one row is one day and the columns are split into four areas: faith, health, family and income. On the very first day the spreadsheet showed that I had missed all five prayers, and for four of them the reason was the same: my phone. After that I put a profile on my iPhone and iPad with Apple Configurator that removes entertainment apps and sites and can&amp;rsquo;t be removed.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="where-the-spreadsheet-came-from"&gt;Where the spreadsheet came from&lt;/h2&gt;&#10;&lt;p&gt;My goals for the year are written in my notes, in four areas. The problem was that by the end of the month I couldn&amp;rsquo;t honestly say whether I had met them. There was a feeling of “seems fine”, and a feeling proves nothing.&lt;/p&gt;</description></item><item><title>Immunity and cold hardening: what works, according to research</title><link>https://az-way-blog.web.app/en/posts/immunity-cold-hardening/</link><pubDate>Wed, 04 Nov 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/posts/immunity-cold-hardening/</guid><description>&lt;div class="az-alert az-alert--info" role="status"&gt;&#10; &lt;span class="az-alert__title"&gt;In short&lt;/span&gt;&#10; &lt;div&gt;You can&amp;rsquo;t “boost immunity” with a single pill. According to research, five things work: a flu shot, at least 7 hours of sleep, regular cardio, hand washing, and vitamin D if you are low on it. Cold exposure, gargling, probiotics and sauna give a small or uncertain effect. Garlic, ginger, vitamin C “for everyone” and “immunomodulators” do almost nothing for prevention.&lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="how-to-read-the-levels-of-evidence"&gt;How to read the levels of evidence&lt;/h2&gt;&#10;&lt;p&gt;Each item below has one of four levels:&lt;/p&gt;</description></item><item><title>OCA: Oracle Certified Associate Java SE 8 Programmer I Study Guide</title><link>https://az-way-blog.web.app/en/books/java-oca-8/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/books/java-oca-8/</guid><description>&lt;h2 id="why-im-reading-it"&gt;Why I&amp;rsquo;m reading it&lt;/h2&gt;&#10;&lt;p&gt;The goal is to be able to write backend in Java/Spring, not only frontend. A certificate by itself doesn&amp;rsquo;t get you a job. But preparing for it forces you to learn the core of the language down to the details, not “at Stack Overflow level”.&lt;/p&gt;&#10;&lt;h2 id="chapter-notes"&gt;Chapter notes&lt;/h2&gt;&#10;&lt;p&gt;A breakdown of each of the six chapters — where TypeScript habits lead to a wrong answer and which LeetCode problems reinforce the chapter — is in the post &lt;a href="https://az-way-blog.web.app/en/posts/java-oca-8-frontend/"&gt;Java OCA 8 through a frontend developer&amp;rsquo;s eyes&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Gear</title><link>https://az-way-blog.web.app/en/tech/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://az-way-blog.web.app/en/tech/</guid><description>&lt;p&gt;Devices I use or plan to buy soon.&lt;/p&gt;&#10;&lt;h2 id="using"&gt;Using&lt;/h2&gt;&#10;&#10;&lt;div class="az-card az-card--icon"&gt;&#10; &lt;span class="az-card__icon az-card__icon--wealth"&gt;&lt;svg viewBox="0 0 48 48" width="48" height="48" focusable="false" aria-hidden="true"&gt;&#10; &lt;path class="az-ill__soft" d="M8 20 L24 13 L40 20 L24 27 Z"/&gt;&#10; &lt;path class="az-ill__line" d="M8 20 L24 13 L40 20 L24 27 Z M8 20 V26 L24 33 L40 26 V20 M24 27 V33"/&gt;&#10; &lt;circle class="az-ill__accent" cx="32" cy="27.6" r="1.4"/&gt;&#10;&lt;/svg&gt;&#10;&lt;/span&gt;&#10; &lt;div class="az-card__body"&gt;&#10; &#10; &lt;h3 class="az-card__title"&gt;Mac mini (2024)&lt;/h3&gt;&#10; &lt;div&gt;Computer: M4, 16 GB RAM&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&#10;&lt;div class="az-card az-card--icon"&gt;&#10; &lt;span class="az-card__icon az-card__icon--wealth"&gt;&lt;svg viewBox="0 0 48 48" width="48" height="48" focusable="false" aria-hidden="true"&gt;&#10; &lt;path class="az-ill__soft" d="M7.5 14.5 Q24 17.5 40.5 14.5 V28 Q24 31 7.5 28 Z"/&gt;&#10; &lt;path class="az-ill__line" d="M4 11 Q24 15 44 11 V31 Q24 35 4 31 Z M24 34 V39 M16 40 H32"/&gt;&#10;&lt;/svg&gt;&#10;&lt;/span&gt;&#10; &lt;div class="az-card__body"&gt;&#10; &#10; &lt;h3 class="az-card__title"&gt;Dell P3421W&lt;/h3&gt;&#10; &lt;div&gt;Monitor&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&#10;&lt;div class="az-card az-card--icon"&gt;&#10; &lt;span class="az-card__icon az-card__icon--wealth"&gt;&lt;svg viewBox="0 0 48 48" width="48" height="48" focusable="false" aria-hidden="true"&gt;&#10; &lt;rect class="az-ill__line" x="4" y="15" width="40" height="18" rx="3"/&gt;&#10; &lt;path class="az-ill__line az-ill__keys" d="M9 20 H39 M11 24.5 H37"/&gt;&#10; &lt;rect class="az-ill__accent" x="15" y="27.5" width="18" height="2.5" rx="1.25"/&gt;&#10;&lt;/svg&gt;&#10;&lt;/span&gt;&#10; &lt;div class="az-card__body"&gt;&#10; &#10; &lt;h3 class="az-card__title"&gt;Logitech MX Keys Mini&lt;/h3&gt;&#10; &lt;div&gt;Keyboard&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&#10;&lt;div class="az-card az-card--icon"&gt;&#10; &lt;span class="az-card__icon az-card__icon--wealth"&gt;&lt;svg viewBox="0 0 48 48" width="48" height="48" focusable="false" aria-hidden="true"&gt;&#10; &lt;path class="az-ill__line" d="M24 6 C33 6 36 14 36 24 C36 35 31 42 24 42 C17 42 12 35 12 24 C12 14 15 6 24 6 Z M24 6 V18 M12.5 19 Q24 22 35.5 19"/&gt;&#10; &lt;rect class="az-ill__accent" x="22.5" y="9.5" width="3" height="6" rx="1.5"/&gt;&#10;&lt;/svg&gt;&#10;&lt;/span&gt;&#10; &lt;div class="az-card__body"&gt;&#10; &#10; &lt;h3 class="az-card__title"&gt;Logitech MX Master 3S&lt;/h3&gt;&#10; &lt;div&gt;Mouse&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;h2 id="planning-to-buy"&gt;Planning to buy&lt;/h2&gt;&#10;&#10;&lt;div class="az-card az-card--icon"&gt;&#10; &lt;span class="az-card__icon az-card__icon--health"&gt;&lt;svg viewBox="0 0 48 48" width="48" height="48" focusable="false" aria-hidden="true"&gt;&#10; &lt;path class="az-ill__line" d="M19 14 L20 5 H28 L29 14 M19 34 L20 43 H28 L29 34 M35 22 H37 V26 H35"/&gt;&#10; &lt;circle class="az-ill__line" cx="24" cy="24" r="11"/&gt;&#10; &lt;path class="az-ill__accent-line" d="M24 17 A7 7 0 1 1 17.42 26.39"/&gt;&#10;&lt;/svg&gt;&#10;&lt;/span&gt;&#10; &lt;div class="az-card__body"&gt;&#10; &#10; &lt;h3 class="az-card__title"&gt;Garmin Forerunner 265&lt;/h3&gt;&#10; &lt;div&gt;Watch&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&#10;&lt;div class="az-card az-card--icon"&gt;&#10; &lt;span class="az-card__icon az-card__icon--health"&gt;&lt;svg viewBox="0 0 48 48" width="48" height="48" focusable="false" aria-hidden="true"&gt;&#10; &lt;path class="az-ill__accent-line" d="M5 12 H14 L17 6 L21 17 L24 10 L26 12 H43"/&gt;&#10; &lt;rect class="az-ill__line" x="4" y="25" width="40" height="6" rx="3"/&gt;&#10; &lt;rect class="az-ill__bg az-ill__line" x="16" y="22" width="16" height="12" rx="6"/&gt;&#10; &lt;circle class="az-ill__accent" cx="24" cy="28" r="1.6"/&gt;&#10;&lt;/svg&gt;&#10;&lt;/span&gt;&#10; &lt;div class="az-card__body"&gt;&#10; &#10; &lt;h3 class="az-card__title"&gt;Garmin HRM 600&lt;/h3&gt;&#10; &lt;div&gt;Heart rate monitor&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;</description></item></channel></rss>