<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Moonshiner</title>
    <description>The latest articles on Forem by Moonshiner (@moonshiner-insights).</description>
    <link>https://forem.com/moonshiner-insights</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F10128%2F20449036-b878-46f5-ad83-131ab90d3e25.png</url>
      <title>Forem: Moonshiner</title>
      <link>https://forem.com/moonshiner-insights</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/moonshiner-insights"/>
    <language>en</language>
    <item>
      <title>The disappearing customer: How unstable sorting breaks pagination</title>
      <dc:creator>Raphael</dc:creator>
      <pubDate>Thu, 17 Jul 2025 19:05:15 +0000</pubDate>
      <link>https://forem.com/moonshiner-insights/the-disappearing-customer-how-unstable-sorting-breaks-pagination-45i7</link>
      <guid>https://forem.com/moonshiner-insights/the-disappearing-customer-how-unstable-sorting-breaks-pagination-45i7</guid>
      <description>&lt;p&gt;I have recently discovered a strange issue where a record in my database mysteriously disappears from a paginated API endpoint. And in fact, this is an issue that could happen to you as well, if your sorting is unstable. But let's start from the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Starting Point
&lt;/h2&gt;

&lt;p&gt;In my application, I have an endpoint that returns all customers, sorted by customer group. So each customer is assigned to a customer group, has a first name, a last name and some other fields. Because we have quite a few customers in the system, we also added pagination, so that the endpoint only returns 10 records at a time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The fact that I am using Laravel and the Eloquent ORM does not matter, it happens with any SQL query.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My query using the Eloquent Query Builder looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Customer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'customer_group_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is equivalent to the following SQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_group_id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Problem: Unstable Sorting
&lt;/h2&gt;

&lt;p&gt;At first, it seems logical. We first load all customers of group 1, then all customers of group 2 etc. But here's the catch: Although we loaded all pages in the frontend, one customer never showed up. Nowhere, on none of the pages - although they were in the database!&lt;br&gt;
How is this possible? The reason is the following:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️  For customers with the same customer_group_id, the database has no clear rule for how to order them within the group.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is called unstable sorting and leads to a non-deterministic order of records. In our case that meant that for every page, the order of customers within a specific group was not consistent. While one customer did not get returned on any of the pages, others were returned on multiple pages. Not great.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Solution: Add a unique tie-breaker
&lt;/h2&gt;

&lt;p&gt;So let's look at how to fix it. To make your pagination stable and reliable, you need to ensure that sorting is deterministic. That means every record has a well-defined position in the order.&lt;br&gt;
The fix? Add so many ORDER BY clauses that there isn't any ambiguity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel Query Builder:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Customer&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'customer_group_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'last_name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'first_name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Plain SQL:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_group_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without specifying the ID as a tie-breaker, you could still have unstable results if there are multiple customers who have the same first and last name. Since the ID is unique, this guarantees a consistent order across pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This issue is easy to miss, especially if there are lots of entries and only a few of them are non-unique. Debugging non-deterministic issues is never fun. But once you know what causes this problem, it's super easy to fix.&lt;/p&gt;

&lt;p&gt;To save yourself the headache, here's my take-away for you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡️ If your sorting relies on a non-unique field, always add a unique, secondary ORDER BY column.️️&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Written by Raphael Fleischmann, Team Lead Custom Software at Moonshiner.&lt;br&gt;
This post was originally published on Raphael's personal blog: &lt;a href="https://www.raphaelf.xyz/the-disappearing-customer-how-unstable-sorting-breaks-pagination/" rel="noopener noreferrer"&gt;https://www.raphaelf.xyz/the-disappearing-customer-how-unstable-sorting-breaks-pagination/&lt;/a&gt;&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Collation Confusion: How to Search in MySQL</title>
      <dc:creator>Martin Sedláček</dc:creator>
      <pubDate>Thu, 22 May 2025 11:34:11 +0000</pubDate>
      <link>https://forem.com/moonshiner-insights/collation-confusion-how-to-search-in-mysql-10dj</link>
      <guid>https://forem.com/moonshiner-insights/collation-confusion-how-to-search-in-mysql-10dj</guid>
      <description>&lt;p&gt;Have you ever received a ticket and thought to yourself — "&lt;em&gt;That will be easy&lt;/em&gt;"? That was exactly the case for the ticket I received in one of our projects. The ticket was about adding an extra condition to the MySQL database query that would narrow results using a &lt;code&gt;LIKE&lt;/code&gt; condition on a database column. The database query is already implemented, so I will just add one extra condition to it, pass a few parameters here and there, and the ticket is done. Easy! Right?&lt;/p&gt;

&lt;p&gt;Well, I was &lt;strong&gt;WRONG&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;After implementing the feature and going through the acceptance loop, I have discovered that filtering columns containing text using a &lt;code&gt;LIKE&lt;/code&gt; operator in MySQL can be &lt;strong&gt;trickier than it seems&lt;/strong&gt;, mainly when it comes to texts including special language-specific characters (all the ü, ř, and ß).&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's dive in
&lt;/h2&gt;

&lt;p&gt;Let's start with a small example. We have a database table with one column (charset &lt;code&gt;utf8mb4&lt;/code&gt; and collation &lt;code&gt;utf8mb4_general_ci&lt;/code&gt;).&lt;br&gt;
This table includes the following values - &lt;em&gt;Fußball&lt;/em&gt;, &lt;em&gt;summer&lt;/em&gt;, &lt;em&gt;stress&lt;/em&gt;, &lt;em&gt;Mädchen&lt;/em&gt;, &lt;em&gt;aerobic&lt;/em&gt;. So let's try to execute a few queries with this table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Stored values: Fußball, summer, stress, Mädchen, aerobic

-- Searching for ä
SELECT * FROM `foo` WHERE text_column LIKE "%ä%";

+-------------+
| text_column |
+-------------+
| Fußball     | 
+-------------+
| Mädchen     |
+-------------+
| aerobic     |
+-------------+

-- Searching for ß
SELECT * FROM `foo` WHERE text_column LIKE "%ß%";

+-------------+
| text_column |
+-------------+
| Fußball     |
+-------------+
| summer      |
+-------------+
| stress      |
+-------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not sure if the results of this example were the ones you would expect, but for sure, they were a bit off for us. So I started investigating how the matching in MySQL even works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Column Collations
&lt;/h2&gt;

&lt;p&gt;For storing values in the database, MySQL uses &lt;strong&gt;Character sets&lt;/strong&gt; (&lt;em&gt;we won't be talking about them in this post&lt;/em&gt;). But when the values are already retrieved and MySQL needs to &lt;strong&gt;compare them&lt;/strong&gt;, then &lt;strong&gt;Collation&lt;/strong&gt; is used. That means that the Collation heavily influences any operation requiring comparison of characters (such as filtering, sorting, etc.).&lt;/p&gt;

&lt;p&gt;The Collation is always bound to a specific Character set, but for simplicity, we will be using only the Character Set &lt;code&gt;utf8mb4&lt;/code&gt; for the rest of this post, as it is the most common one.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;general&lt;/code&gt; vs. &lt;code&gt;unicode&lt;/code&gt; Collation
&lt;/h3&gt;

&lt;p&gt;For Unicode Character sets, there are two most common Collations - &lt;code&gt;xxx_unicode_ci&lt;/code&gt; and &lt;code&gt;xxx_general_ci&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The recommended column collation for MySQL database is the &lt;code&gt;xxx_general_ci&lt;/code&gt;, as it is the &lt;strong&gt;fastest one&lt;/strong&gt; ⚡ to perform the operations. However, with this Collation, the search results are less correct than with the &lt;code&gt;xxx_unicode_ci&lt;/code&gt;. The &lt;code&gt;xxx_general_ci&lt;/code&gt; only supports mapping one character to exactly one character. On the other hand, the &lt;code&gt;xxx_unicode_ci&lt;/code&gt; supports more complex mapping, where one character can also represent a sequence of characters, or some characters can be ignored.&lt;/p&gt;

&lt;p&gt;This can be very well seen in the example of ß.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ß = s   -- For utf8mb4_general_ci
ß = ss  -- For utf8mb4_unicode_ci, as it supports mapping one character to multiple characters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows that when the precise character comparison is required, setting the correct Collation can make a difference.&lt;/p&gt;

&lt;p&gt;So if we look at our example from the beginning, we can see that, for example, the row containing the word &lt;em&gt;summer&lt;/em&gt; was selected, as the ß was "converted" to normal 's' (as we used &lt;code&gt;utf8mb4_general_ci&lt;/code&gt;), and that matches the condition.&lt;/p&gt;

&lt;h3&gt;
  
  
  Language-specific Collations
&lt;/h3&gt;

&lt;p&gt;But what if you want to be even more specific and need to follow really strict rules when comparing characters? Then, MySQL offers many language-specific Collations that include some additional rules for given languages.&lt;/p&gt;

&lt;p&gt;So, if you, for example, require German DIN-2 (phone book) ordering, you can use the &lt;code&gt;utf8mb4_german2_ci&lt;/code&gt;, which has this set of additional rules&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ä = Æ = AE
Ö = Œ = OE
Ü = UE
ß = ss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;But wait!&lt;/strong&gt; What if I don't like the behavior shown in the example at the beginning? What if I only want to match the words with either ß or 'ss'? Is there anything I can do with the knowledge about the Collations?&lt;/p&gt;

&lt;p&gt;Let's refresh the current state - Collation: &lt;code&gt;utf8mb4_general_ci&lt;/code&gt;; Values:  &lt;em&gt;Fußball&lt;/em&gt;, &lt;em&gt;summer&lt;/em&gt;, &lt;em&gt;stress&lt;/em&gt;, &lt;em&gt;Mädchen&lt;/em&gt;, &lt;em&gt;aerobic&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Stored values: Fußball, summer, stress, Mädchen, aerobic

-- Searching for ß
SELECT * FROM `foo` WHERE text_column LIKE "%ß%";

+-------------+
| text_column |
+-------------+
| Fußball     |
+-------------+
| summer      |
+-------------+
| stress      |
+-------------+

-- I don't want the "summer" to show up, 
-- so I change the collation to utf8mb4_general_ci
SELECT * FROM `foo` WHERE text_column LIKE "%ß%" COLLATE utf8mb4_unicode_ci; 

+-------------+
| text_column |
+-------------+
| Fußball     |
+-------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After changing the Collation to &lt;code&gt;utf8mb4_unicode_ci&lt;/code&gt;, the extra result is gone, and we are only getting the result with a proper match.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch with &lt;code&gt;LIKE&lt;/code&gt; operator
&lt;/h2&gt;

&lt;p&gt;However, have you noticed something strange in the last example? When we changed the Collation to &lt;code&gt;utf8mb4_unicode_ci&lt;/code&gt;, the &lt;em&gt;summer&lt;/em&gt; also disappeared from the result set.&lt;/p&gt;

&lt;p&gt;That seems to go against the facts explained above, right? As we said that for &lt;code&gt;utf8mb4_unicode_ci&lt;/code&gt;, the mapping of character is the following - &lt;code&gt;ß = ss&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But actually, this has very little to do with the Collation itself. It has something to do with how the LIKE operator performs matching. Quoting from MySQL documentation, the LIKE performs a per-character matching.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Per the SQL standard, LIKE performs matching on a per-character basis, thus it can produce results different from&lt;br&gt;
the = comparison operator.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means that even if you use the correct Collation, which correctly maps the characters to their multi-character forms, you might experience an unexpected behavior when using a &lt;code&gt;LIKE&lt;/code&gt; operator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT "ß" LIKE 's' COLLATE utf8mb4_unicode_ci; -- FALSE
SELECT "ß" LIKE 'ss' COLLATE utf8mb4_unicode_ci; -- FALSE
SELECT "ß" LIKE 'ß' COLLATE utf8mb4_unicode_ci; -- TRUE
SELECT "ß" == 'ss' COLLATE utf8mb4_unicode_ci; -- TRUE

SELECT "ß" LIKE 's' COLLATE utf8mb4_general_ci; -- TRUE
SELECT "ß" LIKE 'ss' COLLATE utf8mb4_general_ci; -- FALSE
SELECT "ß" LIKE 'ß' COLLATE utf8mb4_general_ci; -- TRUE
SELECT "ß" = 'ss' COLLATE utf8mb4_general_ci; -- FALSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When concluding this topic, it might be a good time to reflect on the initial task that was given — "&lt;em&gt;Add an extra condition to an existing database query.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Such a simple task and so many implications. If you look at it from the perspective of how complex this topic can get, you might think, you should not use a MySQL database for searching and filtering. And you might be right.&lt;/p&gt;

&lt;p&gt;However, it's also pretty important to see it in the bigger picture, and maybe, it is, in some cases, just the best solution you have. And if you keep in mind all the quirky behaviors that MySQL has when it comes to character comparison, you might be just completely fine when you use it the next time.  &lt;/p&gt;

</description>
      <category>mysql</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your First Moves in Enterprise Architecture – A Strategic Guide to Getting Started</title>
      <dc:creator>Raphael</dc:creator>
      <pubDate>Thu, 17 Apr 2025 09:23:03 +0000</pubDate>
      <link>https://forem.com/moonshiner-insights/your-first-moves-in-enterprise-architecture-a-strategic-guide-to-getting-started-1cp5</link>
      <guid>https://forem.com/moonshiner-insights/your-first-moves-in-enterprise-architecture-a-strategic-guide-to-getting-started-1cp5</guid>
      <description>&lt;p&gt;So you want to get started with Enterprise Architecture (EA)? This guide will help you take the first steps successfully. The beginning feels like hacking your way through a dense jungle of many applications, technologies, teams and processes. But with the right tools and a clear strategy, you can cut a path towards a future-proof business. So let's start this expedition!&lt;/p&gt;

&lt;h2&gt;
  
  
  🌀 Define Your Objectives: Find Your Why
&lt;/h2&gt;

&lt;p&gt;First things first: Why are you diving into EA? Before moving on, take a step back and look at the big picture. What is the organization trying to achieve? Are you aiming to align your business and IT? Perhaps you're on a quest to make your organization more agile, or double-down on digital transformation? Or maybe you're striving to reduce costs – or the opposite: expand rapidly?&lt;/p&gt;

&lt;p&gt;Whatever the reasons, make sure to clarify them with top management and articulate them clearly. These objectives are your North Star, guiding you through the fog of enterprise complexity. Write them down, share them widely, and refer to them often. Without understanding the business strategy, architecture efforts will lack direction.&lt;/p&gt;

&lt;p&gt;Your success depends on your relationships with upper management. It's office politics, but in a positive way. Show them your superpowers. These are your capabilities to bring structure into chaos, to lead initiatives and to explain complex technical topics in simple words. Once they trust you, you'll have the backing you need to make real, impactful changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🦕 Assess Your Current State: Digital Archaeology
&lt;/h2&gt;

&lt;p&gt;Time to play detective! Investigate your current application landscape, business processes, information systems, and infrastructure. It's like archaeology, but instead of dinosaur bones, you're discovering legacy systems and forgotten databases. Create a comprehensive map of all your existing applications, their functions, and how they interact.&lt;/p&gt;

&lt;p&gt;Also document their "ingredients": the current technology stack. List out languages, frameworks, infrastructure providers, databases and standard software. You might find some ingredients that are well past their expiration date!&lt;/p&gt;

&lt;h2&gt;
  
  
  🔠 Categorize and Prioritize: What's Hot, What's Not?
&lt;/h2&gt;

&lt;p&gt;Categorize your applications and tech stacks. Which ones are strategically important, and which ones are the Internet Explorer of your organization (in desperate need of change)? Focus on the important ones - you're an architect, not a magician. You cannot fix everything at once. To make prioritization easier, you might want to take a look at Gartner's TIME framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 Develop a Vision for the Future
&lt;/h2&gt;

&lt;p&gt;Based on your objectives and current state, now it's all about your vision for the future. Ensure this vision aligns with your organization's overall strategy.&lt;/p&gt;

&lt;p&gt;Establish a set of architecture principles that will guide you through the transformation. These principles are not just goals, they're your architectural mantras. Cover aspects like technology standards, information management and security. Make them clear, memorable, and maybe even a little witty.&lt;/p&gt;

&lt;p&gt;Next, paint a picture of your future architecture. This is where you get to channel your inner Da Vinci (but with more rectangles and arrows). Which applications and technologies do you want to improve, replace or sunset?&lt;/p&gt;

&lt;h2&gt;
  
  
  🗺️ How will you get there? Create a Roadmap
&lt;/h2&gt;

&lt;p&gt;Now that you know where you are and where you want to go, it's time to figure out how to get there. Break down your journey into manageable phases and projects, with some milestones that you can use as checkpoints. One thing is clear: for this step you need your application experts on board, to get a realistic estimation of effort and lead time. Finally, you need management approval to get the necessary resources to make your ideas come true.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 Collaboration, Support and Governance
&lt;/h2&gt;

&lt;p&gt;It's time to establish processes for quality gates, architecture reviews and compliance checks. If needed, create a list of approved services and a process for exceptions. But remember, you're here to improve the organization, not to be the architecture police. Support projects, offer guidance and closely collaborate with architects, developers and product managers. Maybe you can even provide your teams with a convenient shared platform that they can build upon, to simplify and speed up their development.&lt;/p&gt;

&lt;h2&gt;
  
  
  📈 Try Out, Improve, Repeat.
&lt;/h2&gt;

&lt;p&gt;Nothing is perfect from the beginning, but this should give you a good start into Enterprise Architecture. You can always iterate and continuously improve the status quo. Listen to what your colleagues say (and maybe what they think but don't say), monitor progress and read up about best practices and EA frameworks. Then you will definitely be successful! I wish you all the best!&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Written by Raphael Fleischmann, Team Lead Custom Software at Moonshiner.&lt;br&gt;
This post was originally published on Raphael's personal blog: &lt;a href="https://www.raphaelf.xyz/your-first-moves-in-enterprise-architecture/" rel="noopener noreferrer"&gt;https://www.raphaelf.xyz/your-first-moves-in-enterprise-architecture/&lt;/a&gt;&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
