MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

Amazon Bedrock Beginner Guide: A Complete Deep Dive into AWS Generative AI

2026-03-30 15:06:55

👋 Hey there! This is Pratik, a Senior DevOps Consultant with a strong background in automating and optimizing cloud infrastructure, particularly on AWS. Over the years, I have designed and implemented scalable solutions for enterprises, focusing on infrastructure as code, CI/CD pipelines, cloud security, and resilience. My expertise lies in translating complex cloud requirements into efficient, reliable, and cost-effective architectures.

In this guide, we’ll take a beginner-friendly deep dive into Amazon Bedrock, explaining how it works, its features, costs, and use cases.

🔍 How a Simple Problem Introduced Me to Amazon Bedrock

A while ago, I was trying to find a solution for simple problem:

How to make systems understand files and data intelligently, not just match keywords.

When I started exploring AI solutions, things quickly became complicated.
Hosting models, managing infrastructure, and scaling felt like too much work for what I wanted to create.

That’s when I discovered Amazon Bedrock.

What stood out wasn’t just the ability to generate text, it was the flexibility.
It could handle chat, text, images, and more, all through simple APIs. I didn’t have to worry about infrastructure, thanks to Amazon Web Services.

That shift from managing systems to building solutions is what this article is all about.

🧠 What is Amazon Bedrock?

Amazon Bedrock is a fully managed AWS service that allows developers to build and scale generative AI applications using foundation models (FMs).

What are Foundation Models?

Foundation Models are large AI models trained on extensive datasets that can:

  1. Understand text
  2. Analyze images
  3. Generate content
  4. Answer questions

Why Use Bedrock?

  1. No need to manage infrastructure
  2. Built for security and scalability
  3. Cost-effective with a pay-as-you-go model
  4. Seamlessly integrates with the AWS ecosystem

Popular Models Available

  1. Anthropic Claude
  2. Meta Llama
  3. Amazon Titan

🧠 What Can You Do with Amazon Bedrock?

The range of AI capabilities that Amazon Bedrock provides through a single API layer is one of its main advantages.

Let's divide it up into the main categories of capabilities:

💬 1. Chat (Conversational AI)

Chat is the most common way to interact with Amazon Bedrock.
You simply type a question or instruction, and the model responds just like a conversation.
It’s perfect for building chatbots, assistants, or automating responses.

Bedrock supports building intelligent chat systems using models like:

• Claude 3.5 Haiku
• Claude 3 Sonnet

- What you can build:

• Customer support bots
• Internal enterprise assistants
• DevOps copilots

- Example Prompt:

{
  "messages": [
    {
      "role": "user",
      "content": "Explain AWS Bedrock in simple terms"
    }
  ]
}

👉 Best practice:
• Use structured conversation format (messages) instead of plain prompt
• Maintain chat history for context

✍️ 2. Text Generation

Text generation is used when you want the AI to create content.
This can include summaries, articles, code, or structured outputs like JSON.
It’s ideal for automation tasks, documentation, and content creation.

- Supported Models:

• Amazon Titan Text
• Claude 4 Sonnet

- What you can build:

• Blog/article generation
• Code generation
• Email drafting
• Summarization

- Example Use Case:

{
  "prompt": "Write a professional email for leave request",
  "max_tokens": 150,
  "temperature": 0.7
}

🖼️ 3. Image Generation

With image input, you can send pictures to the model and ask questions about them.
The AI can analyze visuals, detect objects, or extract information from images.
This is useful for use cases like document verification, image matching, and visual inspection.

Bedrock also supports text-to-image generation.

- Supported Model:

• Amazon Titan Image Generator

- What you can build:

• AI-generated designs
• Marketing creatives
• Thumbnails and banners

- Example Prompt:

{
  "textToImageParams": {
    "text": "A futuristic city with flying cars at sunset"
  }
}

⚙️ Understanding Bedrock API Parameters

When you work with Amazon Bedrock, you basically send a request to the AI saying:

“Here’s what I want and here’s how I want you to respond.”

A typical request looks like this:

{
  "anthropic_version": "bedrock-2023-05-31",
  "max_tokens": 1000,
  "temperature": 0,
  "top_p": 1,
  "messages": [...]
}

Let’s break this down 👇

1. anthropic_version - [ Which rulebook to follow ]

• Defines the API schema version
• It’s required for Anthropic models (like Claude)
• Always keep this fixed unless AWS updates it

2. max_tokens - [ How long should the answer be? ]

This controls the length of the response.

  • Higher value → longer answer

  • Lower value → short and precise

Quick tips:

  • Use 200–500 → for JSON / short answers

  • Use 800+ → when you want detailed explanations

3. temperature - [ How creative should the AI be? ]

This controls how predictable or creative the response is.

  • 0 → very strict, same answer every time

  • 0.5 → balanced

  • 1 → more creative and random

4. top_p - [ How many options should the AI consider? ]

This one sounds complex, but it’s actually simple.

• Controls token probability sampling
• Limits how “wide” the model thinks
Value Behavior

1 Consider all possibilities
<1 More focused output

Best practice:
• Use top_p = 1 with temperature = 0

5. messages - [ What do you actually want? ]

This is the most important part.

This is where you:

  • Ask your question

  • Give instructions

  • Provide input (text, image, etc.)

"messages": [
  {
    "role": "user",
    "content": [...]
  }
]

📌 Types of input you can send

Inside messages, you can include:

  • text → normal instructions

  • image → for image understanding

  • document → structured files (limited use)

💰 Amazon Bedrock Pricing

When you first look at Bedrock pricing, it can feel confusing but the idea is actually very simple:

You only pay for what you use (pay-as-you-go)

No upfront cost, no subscription required.

1. The Most Important Concept: Tokens

Bedrock pricing is mainly based on tokens.

  • What is a token?

A token is a piece of text (word or part of a word)
Example: “Hello world” ≈ 2–3 tokens

  • You are charged for:

Input tokens (what you send)
Output tokens (what AI generates)

2. Pricing Depends on the Model

Different models = different pricing

For example:

  • Anthropic Claude

~$6 per 1M input tokens
~$30 per 1M output tokens

  • Smaller / cheaper models

Can be 10x cheaper
Example: some models start around $0.07 per 1M tokens

3. Image Pricing

For image-based tasks:

You are charged per image processed
Example: ~$0.03 to $0.60 per image depending on operation

For detailed pricing information, click here 👉 AWS Bedrock Pricing

✨Final Thoughts

Amazon Bedrock makes it extremely simple to get started with generative AI without worrying about the infrastructure or complexity.
With multiple models available, flexible pricing options, and support for text, chat, and image-based applications, it provides the ability to create highly scalable applications.
The key here is to understand how to effectively tune parameters, select the most appropriate model, and manage costs effectively for your application.

Start simple, experiment, and scale as needed and that’s where Bedrock shines.

🔜 What’s Next

In our next article, we’ll work on a hands-on example of a real-world use case involving Amazon Bedrock and AWS Lambda.
The example will be a solution to verify if a reference image exists within a target file, such as a document or PDF.

💬 Let’s Keep the Conversation Going

Have thoughts, questions, or any experience with Event driven architectures to share? I would love to hear from you! Feel free to leave a comment or connect with me on LinkedIn. Let's learn and grow together as a community of builders.
Keep exploring, keep automating and see you in the next one!

Will AI Replace Software Testers? The Truth About AI in Software Testing

2026-03-30 15:04:37

The rise of AI in software testing has created both excitement and uncertainty across the tech industry. Tools are getting smarter, automation is becoming more adaptive, and testing cycles are speeding up like never before.

This rapid shift has led many professionals to ask a pressing question: will ai replace software testers?

It’s a valid concern. After all, when machines start generating test cases, predicting defects, and even maintaining scripts, it’s natural to wonder about the impact of AI on QA jobs.

But here’s the reality—this question, will ai replace software testers, is often driven more by fear than facts.
AI is not here to eliminate testers. It is here to redefine how testing is done. The future of software testing with AI is less about replacement and more about collaboration.

Instead of asking whether AI will take over, the better question is: how will the role of testers in AI era evolve?

How Will AI Transform Software Testing?

To truly answer will ai replace software testers, we first need to understand how AI is changing the testing landscape.
Today, AI in software testing is no longer experimental. It is actively being used to analyze large datasets, detect patterns, and optimize testing workflows with greater speed and accuracy. This shift is a major reason behind the growing discussion around the impact of AI on QA jobs.

AI in Test Automation

One of the biggest transformations is happening in automation vs manual testing. Traditional automation relies heavily on predefined scripts, which often break when applications change.
AI-powered automation, on the other hand, is more adaptive:

  • Tests can automatically update when UI elements change
  • Test cases are generated based on user behavior and risk areas
  • Systems can predict failures before they occur This is where codeless automation testing becomes significantly more powerful than conventional methods. However, this advancement also leads many to revisit the same concern:

Will AI replace QA engineers as automation becomes smarter?

The answer lies in understanding that AI is improving efficiency, not replacing human thinking. It handles repetitive and data-heavy tasks, but still depends on human input for strategy and decision-making.

AI’s Role in Different Testing Phases

To better understand will ai replace software testers, it helps to look at how AI is being used across different stages of testing.
Today, AI in software testing is influencing almost every phase of the testing lifecycle, making processes faster and more data-driven. This shift is a key part of the growing impact of AI on QA jobs.

  1. Unit and Integration Testing: AI tools can analyze code patterns and detect potential issues early, reducing defects before they move further in the cycle.
  2. Functional Testing: Intelligent systems can execute end-to-end scenarios that simulate real user behavior, improving coverage and efficiency.
  3. Performance Testing: AI monitors system behavior, detects anomalies, and suggests optimizations automatically.
  4. Regression Testing: Instead of running all tests, AI prioritizes only the most critical ones, saving time and effort.

This evolution is also changing the dynamics of automation vs manual testing, where automation becomes smarter, but still requires human oversight.
As we move toward the future of software testing with AI, testing cycles are becoming faster and more efficient.
But even with all these advancements, the question remains: will ai replace software testers completely?

The answer is still no—because while AI can execute and optimize, it cannot fully understand context, business impact, or user expectations.

Why AI Still Needs Human-Driven Risk Assessment

Even with rapid advancements in AI in software testing, there are critical areas where human involvement remains essential. This is where the answer to Will AI replace QA engineers becomes much clearer.
AI can identify defects, flag anomalies, and even predict failures.

However, it cannot fully understand the real-world impact of those issues. This limitation highlights an important aspect of the impact of AI on QA jobs—AI supports decision-making, but it does not replace it.
For example, a minor UI issue detected by AI might seem insignificant technically, but could have serious business consequences. Only human testers can evaluate:

How a defect affects user experience

Whether it violates business rules or compliance requirements
The actual risk associated with releasing a feature
This is where the role of testers in AI era becomes more strategic. Testers are no longer just executing tests—they are

interpreting results, prioritizing risks, and guiding release decisions.
In the broader discussion of automation vs manual testing, this is a clear boundary. AI can automate execution, but it cannot take ownership of risk.

So when asking will ai replace software testers, it’s important to remember—AI can detect problems, but only humans can decide what truly matters.

Will AI Fully Replace Software Testers?

It’s easy to imagine a future where AI handles everything—from writing test cases to identifying defects. That’s why the question Will AI replace software testing professionals keeps coming up in almost every QA discussion.
But in reality, complete replacement is highly unlikely. The future of software testing with AI is not about removing testers, but about redefining their responsibilities.

Lack of Contextual Understanding

Software testing is not just about execution—it’s about understanding context.
Even with advancements in AI in software testing, machines still struggle to interpret business logic, user intent, and real-world scenarios. They can detect that something is broken, but they cannot always determine whether it actually matters.
This limitation is a key reason why will ai replace software testers continues to have the same answer: no.

Testing Requires Creativity

Testing is not a purely technical activity—it’s also creative.
Testers explore applications, think like users, and uncover edge cases that are not always predictable. In the ongoing comparison of automation vs manual testing, this is where humans still have a clear advantage.
AI can generate scenarios based on data, but it cannot truly “imagine” unexpected behaviors the way humans do.

Ethics and Responsibility

Another important factor in the impact of AI on QA jobs is accountability.
If an AI system misses a critical defect, who is responsible? The answer is always human teams. This is why the role of testers in AI era includes oversight, validation, and ethical decision-making.
AI can assist, but it cannot take responsibility.

Collaboration, Not Replacement

The real shift is not AI versus testers—it’s AI working alongside testers.
In the future of software testing with AI, the most successful professionals will be those who can combine human insight with AI capabilities.
So when we revisit the question will ai replace software testers, the answer becomes clearer: AI will change how testing is done, but it will not eliminate the need for testers.

Where AI Actually Fails in QA

To fully address the question will ai replace software testers, it’s important to look at where AI still struggles.

Despite the rapid growth of AI in software testing, it is far from perfect. There are clear limitations that prevent it from functioning independently without human involvement. This is also a key part of understanding the impact of AI on QA jobs.

AI performs well with structured data and predictable scenarios. But when it comes to ambiguity, changing requirements, or human-centric experiences, it often falls short.
For instance, AI may:

  • Misinterpret unclear or incomplete requirements
  • Miss edge cases that don’t appear in historical data
  • Generate false positives or overlook subtle defects
  • Struggle with usability, emotion, and user intent These gaps highlight a major point in the automation vs manual testing discussion—automation can scale, but it cannot fully replace human judgment.

As we move toward the future of software testing with AI, these limitations reinforce why human oversight is critical.
So again, when asking will ai replace software testers, the answer remains consistent. AI can assist and accelerate testing, but it cannot replace the depth of understanding and adaptability that human testers bring.

Can AI Take Over Manual Testing?

This is another variation of the same concern: will ai replace software testers, especially those focused on manual testing.
The short answer is no. AI will not completely take over manual testing. Instead, it is reshaping the balance in automation vs manual testing, making both approaches more complementary than competitive.
With the rise of AI in software testing, repetitive tasks like regression checks and basic validations are increasingly automated. This shift contributes to the ongoing impact of AI on QA jobs, where routine work is reduced, but strategic work increases.

How AI Enhances Manual Testing

AI is making manual testing more efficient by:

  • Automating repetitive and time-consuming tasks
  • Generating test cases from simple inputs
  • Providing faster feedback and broader test coverage
  • Reducing the effort required for test maintenance This evolution is a strong indicator of the future of software testing with AI, where testers focus less on execution and more on analysis and decision-making.

Where Manual Testers Remain Essential

Even with these advancements, there are areas where AI cannot replace humans:

  • Exploratory testing that requires intuition and curiosity
  • User experience validation, which depends on human perception
  • Complex problem-solving involving business context
  • Creative thinking to uncover unexpected issues These responsibilities clearly define the role of testers in AI era—moving beyond execution to becoming quality-focused thinkers.

So, when revisiting the question will ai replace software testers, especially in manual testing, the answer is still no. AI enhances productivity, but human insight remains irreplaceable.

The Testing Roles Most Affected by AI

As the discussion around Will AI replace software testing professionals continues, it’s important to understand that not all roles are impacted equally. The impact of AI on QA jobs varies depending on the nature of the work.
AI is not removing entire careers—but it is reshaping certain responsibilities, especially in the context of automation vs manual testing.

High-Risk Roles: Repetitive Manual Testing

  • Roles that involve repetitive and predictable tasks are the most affected.
  • Activities like executing the same test cases, basic UI checks, and data validation are increasingly handled by AI in software testing tools. These tasks follow patterns, making them easier to automate. This is why many people ask Will AI replace software testing professionals—because these repetitive roles are clearly declining.

Medium-Risk Roles: Traditional Automation Engineers

Automation engineers who rely only on scripting may also feel the shift.
AI tools can now generate, update, and maintain test scripts with minimal human input. This is a growing part of the future of software testing with AI, where automation becomes more intelligent and less manual.
However, those who adapt to AI-driven tools will continue to stay relevant.

Low-Risk Roles: Strategic and Analytical Testers

Roles that involve creativity, analysis, and decision-making are far less likely to be replaced.

These include exploratory testers, performance testers, and security testers—areas where human judgment plays a critical role. This is where the role of testers in AI era becomes even more valuable.

So, when evaluating Will AI replace software testing professionals, the answer depends on the type of work.
Repetitive tasks may disappear, but strategic testing roles will continue to grow.

New Testing Areas Created Entirely by AI Adoption

While many discussions focus on will ai replace software testers, a more important shift is often overlooked—AI is actually creating entirely new testing responsibilities.

The growth of AI in software testing has introduced challenges that did not exist before. These new areas are expanding the scope of QA rather than shrinking it, which directly changes the impact of AI on QA jobs.
Testers are now expected to validate aspects such as:

  • AI model accuracy and reliability
  • Bias and fairness in decision-making
  • Data drift and model performance over time
  • Safety, guardrails, and unexpected AI behavior

These are not traditional testing problems. They require critical thinking, domain understanding, and ethical judgment—skills that machines cannot replicate.

This shift clearly reflects the future of software testing with AI, where testing goes beyond applications and into intelligent systems.

Another emerging concept is evaluating the “behavior” of AI systems—how they respond, communicate, and align with user expectations. This is where the role of testers in AI era becomes even more human-centric.
In the broader debate of automation vs manual testing, this is a space where automation alone is not enough. Human interpretation and oversight are essential.

So instead of asking only Will AI replace QA engineers, it’s equally important to recognize that AI is opening new career paths that did not exist before.

Building a Future-Proof Tester Mindset

The fear behind will ai replace software testers often comes from uncertainty. But instead of reacting with panic, testers can focus on adapting to the changing landscape.

The future of software testing with AI belongs to those who are willing to evolve with it. This is where mindset becomes just as important as technical skills.

Adopt a Growth Mindset

The first step is to shift how you think about change.
Rather than worrying about the impact of AI on QA jobs, focus on how you can grow alongside these advancements. AI is not a threat—it’s a tool that can enhance your capabilities.
Ask yourself:

  • What new tools can I learn this year?
  • How can I use AI in software testing to improve efficiency?
  • How can I move from execution to strategy? This approach helps you stay relevant in the evolving role of testers in AI era.

Upskill in AI-Aware Areas

To stay competitive, testers should expand their skill sets.
Some key areas include:

  • Understanding how AI models work at a basic level
  • Learning modern AI-powered testing tools
  • Strengthening API and cloud testing knowledge
  • Improving analytical and communication skills These skills align with the shift happening in automation vs manual testing, where technical depth and strategic thinking are becoming more valuable.

Become a Quality Advocate

Testing is no longer limited to finding bugs. It’s about ensuring overall product quality.
In the future of software testing with AI, testers are expected to collaborate with developers, designers, and business teams to define what quality truly means.

This evolution strengthens the role of testers in AI era, making it more influential than ever before.
So instead of focusing only on Will AI replace QA engineers, the better approach is to ask how you can grow into a more strategic and future-ready tester.

Real-World Example of Manual Testers Thriving with AI

A practical way to understand will ai replace software testers is by looking at how teams are already using AI in real scenarios.
The adoption of AI in software testing is not eliminating testers—it is helping them achieve more with less effort. This is clearly visible in the evolving impact of AI on QA jobs.

Take the example of a company aiming to significantly increase its test automation coverage. Initially, they relied on traditional tools and reached limited success. Over time, maintaining test scripts became more time-consuming than creating new ones—highlighting the challenges in the classic automation vs manual testing approach.

When they introduced an AI-powered testing solution, things changed. Manual testers, even those without strong coding skills, were able to create and manage automated tests using simple inputs.
The results were clear:

  • Test coverage increased significantly
  • Maintenance effort dropped drastically
  • Test creation became faster and more scalable This shift reflects the future of software testing with AI, where AI tools empower testers rather than replace them. More importantly, it highlights how the role of testers in AI era is evolving—from executing tests to leveraging intelligent tools for better outcomes.

How to Emotionally Navigate the AI Anxiety

The fear behind will ai replace software testers is not just technical—it’s emotional. Rapid changes in AI in software testing can create uncertainty, making testers feel like they might fall behind.
However, the impact of AI on QA jobs should be seen through a balanced perspective. Every major technological shift has created similar concerns, and testing has always evolved through change.

Accept That Change Is Constant

From manual testing to automation, and from traditional models to agile and cloud, the industry has continuously transformed.
The current shift driven by AI is simply the next phase in the future of software testing with AI. Testers who adapted before can adapt again.

Focus on Human Strengths

Instead of focusing only on Will AI replace QA engineers, it’s more useful to recognize what AI cannot do:

  • Understand human emotions and user intent
  • Make ethical decisions
  • Think creatively in unpredictable scenarios
  • Collaborate across teams with context These strengths define the growing role of testers in AI era and ensure continued relevance.

Learn Without Overwhelm

Many testers feel pressure due to the rapid pace of change. But adapting doesn’t require learning everything at once.
A steady approach works better:

  • Explore one concept of AI in software testing at a time
  • Practice with tools gradually
  • Apply learning in real projects This balanced approach helps reduce anxiety while staying aligned with the evolving automation vs manual testing landscape. So instead of worrying about will ai replace software testers, focus on building confidence, clarity, and continuous learning.

The Road Ahead – The Role of Human Testers in an AI-Enhanced Environment

As we look ahead, the question Is AI going to replace QA testers becomes less relevant than understanding how the role is evolving.

The future of software testing with AI is not about fewer testers—it’s about smarter, more capable testers who can work alongside intelligent systems. This shift is redefining the impact of AI on QA jobs in a positive way.

Several new and evolving roles are emerging:

  • AI Test Analysts who validate AI-driven systems for accuracy and fairness
  • AI-Augmented QA Engineers who use intelligent tools for faster and smarter testing
  • Data Quality Engineers who ensure the reliability of training data
  • Quality Strategists who align testing with business outcomes These roles clearly show how the role of testers in AI era is expanding beyond traditional boundaries. In the ongoing discussion of automation vs manual testing, the future lies in combining both—leveraging automation for efficiency while relying on human insight for quality and decision-making.

Conclusion

The question will ai replace software testers is ultimately about mindset, not just technology.

Yes, AI in software testing is advancing rapidly. Yes, the impact of AI on QA jobs is real. But replacement is not the outcome—evolution is.
Testers who stay curious, adapt to change, and embrace the future of software testing with AI will continue to grow in their careers.

Because in the end, AI can assist, accelerate, and automate—but it cannot replace human thinking, creativity, and judgment.
And that’s exactly what defines the true role of testers in AI era

Understanding data modelling in PowerBI.

2026-03-30 15:00:26

Understanding Data Modeling in Power BI: Joins, Relationships and Schemas Explained

Imagine trying to build a complex Lego structure without an instruction manual. You have thousands of individual bricks (your data) of different sizes, shapes, and colors. Without a blueprint (a data model), you just have a chaotic pile of plastic.

In Power BI, data modeling is that blueprint. It is the single most critical step in creating powerful, accurate, and performant reports. A poorly designed model leads to incorrect calculations, confusing visualizations, and sluggish dashboards.

In this guide, we will break down the essential pillars of data modeling for Power BI, starting with fundamental concepts like SQL Joins and table types, and moving into Power BI-specific relationships and schemas.

Part 1: The Foundation — Understanding Table Types and Joins

Before we can define how tables interact in Power BI, we must understand the fundamental types of tables and how they merge using traditional SQL joins.

Fact Tables vs. Dimension Tables

A strong data model differentiates between two main types of tables:

  • Fact Tables: These store the verbs of your business. They contain measurable, quantitative data (facts or metrics) that occur at a specific point in time. They are usually very tall (many rows).
    • Examples: Sales transactions, website visits, support tickets, inventory levels. Key columns might be SalesAmount, Quantity, and OrderDate.
  • Dimension Tables: These store the nouns of your business. They provide context (who, what, where, when) to the facts. They are usually wide (many columns describing an attribute).
    • Examples: Products, Customers, Geography, Employees. Key columns might be ProductName, CustomerEmail, RegionName, and HireDate.

All SQL Joins Explained (with Diagrams)

A "Join" physically merges two tables horizontally into a new, wider table based on matching values in a common key column. In Power BI, joins are primarily performed within Power Query (the ETL layer) to prepare data before it loads into the model.

Let's look at the different join types using two simple tables: Customers and Orders.

CustomerID (Key) CustomerName
1 Alice
2 Bob
3 Charlie

Customers Table

OrderID CustomerID (Key) Amount
A 1 $50
B 1 $30
C 2 $70
D 4 $90

Orders Table

1. INNER JOIN

Returns only the rows where there is a match in both tables. Rows without matches in either table are discarded.

Real-Life Example: A list showing all orders placed only by customers who are currently active and registered in the CRM. (Order D and Charlie would be excluded).

2. LEFT JOIN (LEFT OUTER)

Returns all rows from the Left table, and the matching rows from the Right table. If there is no match on the right, null values are returned.

Real-Life Example: List all customers and any orders they have placed. This ensures every single customer (like Charlie) is shown, even if they have zero orders (their order columns would be NULL).

3. RIGHT JOIN (RIGHT OUTER)

The exact opposite of a LEFT JOIN. Returns all rows from the Right table, and the matching rows from the Left table. If no match on the left, nulls are returned.

Real-Life Example: List all orders, including those where the customer data might be missing (like Order D, where CustomerID 4 isn't in our Customers table). This is crucial for data auditing.

4. FULL OUTER JOIN

Returns all rows from both tables. It includes matching rows and all non-matching rows from both sides (filled with NULLs where appropriate).

Real-Life Example: Merging complete records from two merged companies where you need a comprehensive view of all customers and all transactional data, whether they overlap or not.

5. LEFT ANTI JOIN

Returns rows only from the Left table that have no matching rows in the Right table.

Real-Life Example: Generating a retention report: "Show me all customers (from the Left/Customers table) who have not placed an order (no match in Right/Orders table) in the last six months."

6. RIGHT ANTI JOIN

Returns rows only from the Right table that have no matching rows in the Left table.

Real-Life Example: Identifying abandoned or "ghost" orders: "Show me all orders (Right table) associated with CustomerIDs that do not exist in our main customer database (Left table)."

Step-by-Step: How to create Joins in Power BI (Power Query)

Joins happen in the Power Query Editor.

  1. Click Transform Data in Power BI Desktop.
  2. Select your primary query (e.g., Orders).
  3. In the Home ribbon, click Merge Queries (or Merge Queries as New).
  4. In the Merge dialog:
    • Select the second table (e.g., Customers) from the dropdown.
    • Click on the matching key column in both tables (e.g., CustomerID).
    • Choose your desired Join Kind (e.g., Left Outer) from the dropdown.
    • Click OK.
  5. A new column containing the merged table will appear. Click the Expand icon (two arrows) on that column header to select which columns from the joined table you wish to include.

Part 2: The Heart of Power BI — Relationships

While Joins merge tables, Relationships are different. Relationships are defined in the main Power BI Model interface and dictate how data filters flow between tables during visualization.

When you drag a field onto a report canvas, Power BI uses these defined relationships to automatically filter related fact tables.

Key Concepts of Power BI Relationships

1. Cardinality (1:M, M:M, 1:1)

This defines how many records in one table relate to how many records in another.

  • One-to-Many (1:M or 1:*): This is the most common and recommended cardinality for analytics. One record in the Dimension table (e.g., ProductID: 101 in Products) maps to many records in the Fact table (e.g., many instances of ProductID: 101 in Sales).
  • Many-to-Many (M:M): Occurs when multiple rows in table A relate to multiple rows in table B. Avoid these if possible; they are complex and can cause unpredictable results or circular dependencies. They are often solved by introducing a 'bridge table.'
    • Example: Students (many) enrolled in Classes (many).
  • One-to-One (1:1): One record in table A maps exactly to one record in table B. Often indicating that the tables could logically be merged into a single table. Useful occasionally for splitting very wide tables (e.g., separating sensitive payroll data into its own 1:1 linked table).

2. Cross-Filter Direction (Single vs. Both)

This determines how the filtering "flows."

  • Single (One-Way): The recommended default for 1:M relationships. Filtering flows from the 'One' side (Dimension) to the 'Many' side (Fact).
    • Effect: Selecting 'USA' on a Country slicer (the 'One' side) will filter the Sales table (the 'Many' side). However, selecting a specific SalesAmount (Many side) will not automatically filter which Countries generated that amount.
  • Both (Bi-directional): The filter can flow in both directions. Selecting a value on the 'Many' side will filter the 'One' side. Use this sparingly as it introduces complexity and significant performance overhead. It is sometimes necessary for complex M:M scenarios.

3. Active vs. Inactive Relationships

A model can only have one active relationship between two tables. This is the primary path Power BI uses for filtering. You can create other 'Inactive' relationships (indicated by a dotted line) to handle advanced scenarios, but these are only utilized when specifically invoked using DAX functions like USERELATIONSHIP().

Role-Playing Dimensions (A Common Inactive Scenario)

This occurs when a single dimension table can relate to a fact table in multiple ways. A classic example is a Date table relating to Orders.

A single order table has multiple dates: OrderDate, ShipDate, and RequiredDate.

  • Active Relationship: Date[Date]Orders[OrderDate] (By default, slicers filter orders by the day they were placed).
  • Inactive Relationship: Date[Date]Orders[ShipDate] (To analyze shipping times, you must write DAX that explicitly activates this relationship).

Key Difference Summary: Join vs. Relationship

Feature Join (Power Query) Relationship (Power BI Model)
Output Creates a new, physically wider table. Data is permanently combined. Maps logical paths between separate tables. Tables remain distinct.
When it runs During data refresh (ETL phase). At report run-time, dynamically when visuals are rendered.
Use Case Merging data that belongs together permanently (e.g., appending address data to customer records). Connecting logical business entities (e.g., Customers, Products, Time) to enable dynamic cross-filtering.
Performance Good for query performance, but increases model size by duplicating columns. Efficient for model size, but requires CPU overhead at run-time for dynamic filtering.

Step-by-Step: Managing Relationships in Power BI

You manage relationships primarily in the Model View.

  1. Go to the Model View (the relationship diagram icon on the left).
  2. You can often just drag a field (e.g., CustomerID) from one table (the dimension) and drop it directly onto the matching field in the other table (the fact). Power BI will automatically attempt to detect the correct cardinality and direction.
  3. Alternatively, click Manage Relationships in the Home ribbon.
  4. In the dialog:
    • Click New.
    • Select the two tables and the linking columns (just like the Merge dialog).
    • Power BI will populate the detected Cardinality (e.g., One-to-many) and Cross-filter direction (e.g., Single).
    • Ensure Make this relationship active is checked if you want it to be the default path.

Part 3: Data Schemas — Organizing the Tables

A Schema is the high-level organization or architecture of your related tables. It is how you arrange your dimensions and facts to create an effective analytical environment.

1. Star Schema (Gold Standard)

This is the recommended schema for almost all analytical workloads and is optimized for Power BI's performance engine.

In a Star Schema, a single, central Fact table is surrounded by multiple Dimension tables. Each relationship is a clean 1:M Single-Direction connection. It is simple, highly performant, and intuitive for users.

Use Case: Almost everything. This is what you should always aim for first.

2. Snowflake Schema

The Snowflake is a variation of the Star Schema where dimensions are further normalized (split) into additional tables to reduce data redundancy.

For example, instead of having one wide Product table that includes ProductSubcategory and ProductCategory text, you split it into three normalized tables: ProductsProductSubcategoryProductCategory.

While normalized schemas save storage space in transactional databases, they degrade analytical performance because the report must traverse multiple relationships (additional joins at run-time) to perform simple filtering. They also make the model more complex to navigate.

Use Case: Rarely in Power BI. It might be used when dimension tables are extremely large, or when the data is sourced directly from a highly normalized data warehouse and you choose not to simplify it (de-normalize it) in Power Query.

3. Flat Table (DLAT - Denormalized Large Analytical Table)

This is the opposite of normalization. Instead of separating dimensions and facts, everything is joined (Power Query Merges) into one extremely wide, massive table.

This eliminates all model relationships and cross-filtering complexity. While theoretically the most performant schema (zero run-time joins), it has severe drawbacks: the model size explodes due to immense data redundancy, making it difficult to manage and sluggish to load.

Use Case: Very simple datasets or proof-of-concept models with a limited number of columns (less than 20-30). It is not scalable for complex business reporting.

Common Modeling Issues to Avoid

  • Ambiguity and Circular Dependencies: Occur when there are multiple paths to filter between two tables (often caused by excessive Bi-directional filtering). Power BI will throw errors or choose an unpredictable path.
  • Assuming Power BI Knows Best: Power BI tries to "Autodetect new relationships." While smart, this can be dangerous. Always review and manually correct cardinality (especially ensuring 1:M where expected).
  • Excessive Bi-directional Filtering (Both): Use only when strictly required for complex scenarios (like M:M). It causes major performance degradation.
  • M:M Relationships: Always try to resolve these with a bridge table and 1:M relationships. They cause confusing filter propagation.
  • Ignoring Key Column Data Types: Relationships require perfect matches. integer columns will not relate correctly to text columns, even if the content looks like "101". Ensure key data types are identical in both tables in Power Query.

Conclusion

Mastering data modeling is the differentiating skill of a professional Power BI developer.

Start by understanding your data (Fact vs. Dimension). Use Joins in Power Query to permanently merge tables. In the Model View, prioritize clean 1:M relationships with Single-Direction filtering, aiming always to build a robust Star Schema. Avoiding complex relationships and overly normalized Snowflake structures will lead to faster reports, accurate results, and a better user experience.

Is your repo ready for the AI Agents revolution? Checklist

2026-03-30 14:59:10

Intro

AI is probably the biggest buzzword around this year and last — it’s not just developers talking about it, it’s everyone! We’re seeing huge shifts in the programming world thanks to personal assistants packed with knowledge, tools that help us code, and autonomous agents. This whole thing is a mix of risks and cool opportunities. On one side, you’ve got the AI fans who are super excited about boosted productivity, getting more creative, and having millions of agents handle all the boring stuff for us. On the other, the cautious folks are raising valid concerns about data privacy, accuracy, and how this all affects our mental health. But here’s the deal: this change is happening, and we can’t hit the brakes. The best way to get ready is to jump in and be a part of it. So, I really recommend you try out, practice, and just play around with these new technologies. Keep an open mind, but also stay smart about the risks. That’s definitely what I’m aiming for!

For some time now, I’ve been exploring various AI tools, frameworks, models, and approaches, primarily focusing on existing (brownfield) codebases rather than entirely new experiments. My goal is straightforward: to find ways to make my work easier and more enjoyable. I don’t expect AI to write all my code or solve complex architectural challenges. Instead, I want it to handle the tedious, repetitive tasks, such as writing tests, fixing minor issues, or migrating outdated technologies. I ran experiments across different projects — in PHP, Node, React, and Java, encompassing both legacy and newer systems. Some were successful; others were not, and I plan to share more about these experiences in future articles. However, through this process, I recognized a critical omission in all the courses, tutorials, and articles I encountered: a simple, practical checklist for preparing a codebase to work effectively with AI agents. This checklist is what I’m sharing today. While you can just check the checklist below, I highly recommend reading the full article to fully understand the context and customize it to your specific requirements.

Disclaimer: Please note that I am a software engineer, not an AI specialist. The AI landscape is evolving rapidly, and I acknowledge that I may have missed certain developments or information. My focus is primarily on integrations with GitHub, Cursor, and Copilot, as these are the tools I use most often. While this checklist should be generally applicable, users of different toolchains may need to make minor adaptations. This article and the following tips are based on my personal experiences and may not universally apply. I encourage discussion and feedback — if you disagree with any points or feel something is missing, my DMs are open. I anticipate that this article will require updates over time, but I believe it offers immediate value in its current form.

The high-level goal

This checklist serves as an initial roadmap, not a definitive final product. You are encouraged to customize it to fit your project’s specific needs and development practices. However, it offers a simple guide to immediate steps for making AI agents more effective in your project. The structure is outlined below (in markdown so you can easily reuse for your projects):

# AI Readiness checklist

## Repository Hygiene

### Source Control & Ignore Rules
- [ ] Repository is integrated with Git (GitHub / GitLab / Bitbucket)
- [ ] `.gitignore` is added
- [ ] `.cursorignore` is added
- [ ] No secrets are hardcoded
- [ ] `.env` file is used and secrets are injected securely

### Automatic Linting & Formatting
- [ ] One formatter is configured and enabled
- [ ] Auto-format on save is enabled
- [ ] One linter is configured and added to the repository
- [ ] Linter runs in the CI pipeline

### IDE Setup & Extensions
- [ ] Modern IDE is used (Cursor / Antigravity / IntelliJ + Windsurf, etc.)
- [ ] Common shortcuts are configured (open chat, select lines, inject files, etc.)

### Standard Repository Commands
The repository provides a **single obvious command** for each action:
- [ ] Start the application
- [ ] Run all tests
- [ ] Run unit tests only
- [ ] Run e2e tests only
- [ ] Run the linter

## Testing Safety Net

### Unit and e2e rules
- [ ] Unit tests cover core functionality
- [ ] Test coverage is at least ~70%
- [ ] E2E tests cover critical user flows

### CI / CD & Code Review
- [ ] CI runs before every merge
- [ ] Linting, tests, and formatting are enforced in CI
- [ ] Code review is required before merge
- [ ] Merge Request (MR) template with a manual checklist exists (e.g. accessibility)
- [ ] (Optional) Automated AI-based code reviews are enabled (e.g. Copilot)
- [ ] (Optional) Automated repo checks are enabled (e.g. Jules agents)


## Grounding Documents

### Requirements & Intent
- [ ] High-level product specification exists in `.ai/requirements`
- [ ] Each new feature has a PRD in `.ai/requirements`
- [ ] (Optional) Out-of-scope features are documented in `.ai/requirements`

### High-Level Technical Documentation
- [ ] `architecture.md` exists in `.ai/docs`
- [ ] `tech-stack.md` exists in `.ai/docs`

### AI Rules & Guardrails
- [ ] `agents.md` with high-level AI rules exists in `.cursor/rules`
- [ ] Each framework/technology has its own rules file in `.cursor/rules`
- [ ] Cognitive-load reduction rules (e.g. 3x3 rule) are documented in `.cursor/rules`


## MCP Integrations

- [ ] Task management MCP (Jira / Asana, etc.) is added to `mcp.json`
- [ ] Design tooling MCP (Figma / Subframe, etc.) is added to `mcp.json`
- [ ] Database tooling MCP is added to `mcp.json`
- [ ] Browser tooling MCP (e.g. Chrome DevTools) is added to `mcp.json`

Let’s talk about those sections and rules in more detail.

Repository hygiene

Source control & ignore rules

Before you start throwing new AI tools at your codebase, you’ve gotta make sure your repository has the right basic setup. The name of the game is safety and making sure you can easily track and roll back any changes. Seriously, these simple points are crucial:

  • Your Version Control Setup:

    • Git is Key: Your code needs to be fully hooked up with Git. Also, make sure your setup (whether it’s your terminal, your IDE plugin, or whatever else) is super comfortable and efficient for you to use.
    • Hosting Platform: You need a platform like GitHub, GitLab, or Bitbucket. Personally, I highly recommend GitHub — in the last months it’s got some great features and integrations not available in other platforms, especially when you start bringing AI agents into the mix.
  • Essential “Don’t Look Here” Files:

    • .gitignore: Non-negotiable. Use this to stop tracking files that are unnecessary or sensitive, like your .env file with all your credentials.
    • .cursorignore (or similar): Add this file to tell tools like semantic search, code completion (like Tab), agents, and inline edits to totally ignore certain content. Files already in .gitignore are automatically skipped, but you can:
    • Overrule It: Use the ! symbol if you do need an agent to see a file that Git is ignoring.
    • Speed Things Up: Add extra rules to cut out irrelevant parts of the repo. It helps the indexing go faster.

Quick Tip: If you use Cursor, you can set up global ignore patterns in your user settings so you don’t have to configure it for every single project.

  • Secret Management (Seriously, Stop Hardcoding):

No Hardcoded Secrets: This is a basic security rule, but it’s even more vital now that Large Language Models (LLMs) are learning from and analyzing our code. Back in the day, early LLMs like Copilot were sometimes proposing actual secret values just based on common variable names — a huge security risk! You must stop your secrets from being suggested to anyone else.

Automatic linting and formatting

Setting up the right tools isn’t strictly required, but man, does it make a difference for the developers! It seriously improves the quality of life and saves a ton of time arguing during code reviews or when new folks join the team (you know, like that never-ending tabs vs. spaces war). You totally need a formatter. Just make sure it’s set up to match your project’s style. If it auto-formats when you save, developers won’t even have to think about it — it just happens! For trickier style and quality issues, a Linter is a must-have. Get it configured, and make sure there’s one simple command to run it. And the last piece? Your CI/CD pipeline needs to lock these rules down. Any pull requests that mess up the formatting or fail the linting checks should be stopped dead before they can merge into the main branch.

IDE setup + extensions

Investing time in mastering your IDE is a crucial, yet often overlooked, step — much like familiarizing yourself with a new phone/car or air-fryer. While coding in a Notepad is technically possible (I still remember when teachers taught us to code this way back at school), it’s not an efficient use of your time. Utilize a modern IDE specifically designed for AI-tooling. Tools like Cursor IDE and Antigravity are excellent options that offer significant functionality right out of the box with minimal setup. If you prefer your existing IDE (such as IntelliJ), at least install and learn a contemporary, AI-focused plugin like Windsurf.

Knowing the most common shortcuts will drastically improve your efficiency. For example, in Cursor:

  • Cmd r then Cmd s: Opens the command palette
  • Cmd i: Toggles the side panel
  • Cmd e: Toggles the agent layout
  • Cmd Shift L (with code selected): Selects the highlighted code as context for the chat
  • @: Selects a file as input
  • /: Runs a shortcut command within the chat

Sharpen Your Axe: Think of preparing your workspace as a reasonable investment to maximize productivity.

The repository provides a single obvious command for each action

Having too many options, like when you’re shopping or picking a restaurant, can actually freeze you up, turning simple decisions into a major time sink. You see the same problem in a ton of software projects: too many settings and options. They’re great for the “power users,” sure, but they’re a total headache for the average person who just needs the standard setup. To make sure your code repository is easy for an AI Agent to use and welcoming to new developers, you’ve got to keep it from getting crazy complicated. It’s fine to keep the deep configuration options for the advanced folks, but you absolutely must provide a simple, single-command way to run the most common, basic stuff. This straightforward approach will be a huge win for both Large Language Models (LLMs) and junior engineers just getting started with your code.

The Must-Have One-Command Tasks:

  • Start the whole app
  • Run every test
  • Run just the unit tests
  • Run only the end-to-end (e2e) tests
  • Run the linter

These commands should be front-and-center in your README and included in the usual spots — like the scripts section in the package.json for any TypeScript/JavaScript project. Cutting down on confusion is key to a smooth start for everyone: new engineers and AI tools.

Testing safety net

To get your repository ready for AI agents, after the initial setup, you should really focus on building a solid testing safety net so you don’t accidentally break your application’s logic. Trust me, you really want to throw down comprehensive tests before you dive into any major refactoring or logic changes to guard your code. This safety net keeps unexpected failures from popping up, especially those caused by “improvements” or changes from your shiny new AI agents. Don’t just cross your fingers; never assume code is too simple to fail, or that developers will manually check things after every agent run. Make sure you get super-fast feedback — tests are the shortest loop you can get, letting the agent quickly fix itself if it slips up and introduces a bug. Keep that code quality high by running these tests in your CI/CD pipeline. This is a must-do to stop buggy code from sneaking into production. Plus, well-written test cases are actually awesome documentation for both your human engineers and the LLMs.

While automating is key, let’s be real — you can’t automate everything. For those tricky bits, set up a clear manual process instead of just relying on “everyone knows this” or a gut feeling. Make code reviews mandatory by requiring approval from another team member (you can set this up in Github). Give them review templates with checklists for things you can’t automate (like more advanced accessibility checks). Automate all the grunt work you can to maximize efficiency so your human reviewers can focus their brainpower on the critical, nuanced stuff, not nitpicking a missing comma. Oh, and definitely use AI pre-checks! Tools like Copilot’s automatic code review or Jules’ scheduled regular checks are an easy, cheap way to get an extra set of eyes, which is super helpful, especially for smaller teams.

Grounding documents


AI agents are quickly moving past their initial “junior engineer” phase — they’re getting way smarter and more capable. The thing is, their training is based on tons of global data, so they don’t know the ins and outs of your specific app or tech stack yet. To connect their general expertise with your specific world, you need to introduce grounding documents.

Requirements & Intent

If you’re wondering where to put documents about your product’s logic, the .ai/requirements folder, usually right at the top of your repository, is a great spot. It’s not a super-official standard, but it works well for keeping a high-level product spec. This spec should clearly explain what the app can do, and just as important, what’s definitely not going to be included (out-of-scope). Seriously, listing those excluded things, especially when you have to cut scope because of time or resources, has been super helpful.

For those of you into spec-driven development, this is also the perfect home for your Product Requirement Documents (PRDs). PRDs should get into the nitty-gritty of every feature and function. They basically turn the product manager’s big-picture idea into actual code and keep the documentation handy. PRDs shine brightest in “greenfield” projects (brand new repositories). But if you’re dealing with an existing, “brownfield” project, a mixed approach is the way to go: keep a high-level doc for all the stuff that’s already solid, then use good PRD practices for new things, like fresh features or big code migrations to ditch old systems. This hybrid strategy works pretty well for me (at least for now 😛).

High-level tech documentation

These two files I propose you to add in the repo are basically the high-level, technical rundown of what the project is all about.

architecture.md

First up is architecture.md. Keep this one short, like max two pages. It sketches out the project’s architecture, and you can toss in links to more detailed stuff if needed. Right now, I stick it in the .ai/docs folder at the root of the repo, but honestly, I don’t know if that’s standard practice or not. Why architecture.md is useful? It’s the main reference point for AI agents when they’re tackling huge jobs, like moving everything over to a new technology. It’s super helpful for getting new engineers up to speed fast. It’s essential for showing exactly how data moves through the whole application.

tech-stack.md

The second document I think we should have is tech-stack.md. This is just a list of all the tools and frameworks the app uses. It stops AI agents from “hallucinating” or randomly adding stuff we don’t need (like bringing in a new unit testing library) by nudging them to use what’s already there. It helps make sure new code follows our chosen solutions, especially during migrations, although we can also manage this with those cursor rules files (more on those later).

AI rules and guardrails

While previous sections can be useful also in standard development, this one is strictly connected with AI. There are special techniques to improve accuracy, reduce time needed for changes, help with context window problems and ensure that AI-generated code fits your best practices and conventions.

agents.md

First of them is an AGENTS.md file, which serves as a readme specifically for AI agents. This is an open, simple format designed to guide coding agents, with various examples available on their dedicated webpage. You should place this file in the root directory of your repository. For monorepos, it should also be included in the root of subfolders. The AGENTS.md file should contain essential information such as:

  • Build and test commands.
  • Code style guidelines.
  • Testing instructions.
  • A high-level overview of the project. My additional tip is to not overfocus on creating this file perfect at the first run. Start with a working version and improve it gradually — you can always update the file later.

Cursor rules

I understand that not everyone finds “Cursor rules” appealing, but I personally consider them quite valuable. Cursor rules are concise markdown files, ideally under 500 lines, located in the .cursor/rules folder. They serve to provide agents with additional context about specific frameworks, technologies, or areas, you can also add some good and bad examples of given rule there. For example, a rule could mandate the use of functional components in React or enforce your internal design system. Another rule might define what should typically be covered in unit tests and what mocking strategies to employ. You should continuously refine these files. After extended sessions with an agent, prompt it to improve the rules, adding more context relevant to your objectives. The agent finds and uses these rules automatically, so you don’t need to add them specifically.

Cognitive load rules

This section was added to my personal workflows after completing the 10xDevs course by Przeprogramowani (hello, Przemek and Marcin!). I realized that while I was focused on improving AI performance, I neglected the importance of managing my own cognitive load, overfocusing on helping machines instead. Dealing with detailed change tracking, debugging, or reviewing hundreds of lines of code is exhausting. You can significantly ease this burden by establishing rules for the AI agent on when it should pause and ask for your review. This approach allows you to understand changes and adjust the code more frequently. A practical example is the 3x3 approach: instruct the agent to implement a maximum of three steps from the plan, briefly summarize the work done, and then propose the next three steps. While Cursor’s built-in agents have recently started doing something similar, it lacks predictability (yet?). To tailor this interaction to your needs, you should define a specific rule for it. These rule files can contain various other tips for collaboration. Simply consider your preferred way of communicating with the agent and ask them to follow those preferences in the rules.

MCPs

The Model Context Protocol (MCP) is an open-source standard designed to connect AI applications with external systems, often likened to the simplicity of a USB-C connection — a “one-fits-all” solution that eliminates the need for special converters. You can learn more here: https://modelcontextprotocol.io/docs/getting-started/intro. Its primary benefit is enabling AI applications to connect to data sources and perform tasks, essentially giving the Large Language Model (LLM) “hands.” This means the AI can move beyond just suggesting or proposing actions to actually carrying them out and learning from the results. This capability leads to:

  • Improved accuracy due to better context for the LLM.
  • Reduced development time.
  • Simplified workflows, especially when multiple tools are involved.
  • Getting started is very easy, typically requiring only a few lines of code in your mcp.json file.

While this area is rapidly evolving, a general approach is recommended. In my view, you will likely need MCP integration for:

  • Task management tools
  • Design tooling
  • Database tooling
  • Browser tooling

Your specific needs may vary — you might require fewer or different tools, especially if you specialize in a certain area. How to find good MCP candidates? Validate your existing working flows. Ask yourself: which tools do you use most often? What common tasks do you perform? What actions currently require you to stop the agent’s work, perform an action manually, and then paste the results back into the agent window to continue? These manual steps are excellent candidates for MCP integration. Given current trends, it’s highly likely that “there should be an MCP for that!”

Summary

This article is long, personal and opinionated. However, I hope it will help you build a “framework” to maximalize benefits from using AI-agents in your project. You absolutely don’t have to agree with everything here, so feel free to read through, think critically, and adjust these ideas to fit what your project actually needs.

“Plans are worthless, but planning is everything.”
~Dwight D. Eisenhower

Remember that famous Eisenhower quote, “Plans are worthless, but planning is everything.” Take some time to prep before you jump into “vibe-coding” and just throw random changes into the repo. A little foresight goes a long way toward avoiding huge messes, bad changes, and flat-out wrong calls. Your code, your teammates, and future-you will seriously appreciate the effort.

P.S. If you got something good out of this, please think about sharing it or dropping a clap/comment below to help other people find it. Thanks!

P.S.2 All pictures used in the article were generated using ChatGPT.

Common Pitfalls in Azure DevOps Migrations (and How to Avoid Them)

2026-03-30 14:57:54

Migrating Azure DevOps is far more complex than it appears. Most businesses underestimate the effort required to move work items, pipelines, identities, and historical traceability without disruption. Here, we highlight the challenges along with practical mitigation steps to prevent data loss, preserve traceability, and ensure continuity for development teams.

According to industry analysts, 60–90% of cloud migration projects fall short of their goals, often due to predictable, recurring issues rather than rare technical errors. But most of these Azure DevOps migration issues are entirely avoidable.

With the right awareness and preparation, enterprises can steer clear of costly missteps and accelerate their path to the substantial efficiency, scalability, and governance benefits that a well-executed Azure DevOps migration delivers.

If your enterprise is undertaking an Azure DevOps migration, then read on as we list some of these common challenges along with the best practices to avoid them.

Pitfall #1 - Ignoring Process Template Differences

Azure DevOps supports multiple process models Inherited and Hosted XML with differing definitions for work item types and workflows. If data is moved from one Azure DevOps project to another without checking whether both use the same form structure/template, things will break.

Mitigation

The solution for a smooth Azure DevOps migration issues is to take an inventory of the process templates standardize the names and types of work items so they align across environments. Mapping tools can be used to correctly translate each work item type from the old system to the new one.

Pitfall #2 - Losing Work Item History or Attachments

Data loss is a frequent and high-risk challenge when you migrate Azure DevOps attachments. Incomplete history or missing attachments can lead to errors in audit trails, approvals, and future compliance issues. Even sophisticated tools have limits: Azure DevOps’ TFS Attachment Tool shows that attachments beyond certain size limits (e.g., >60 MB in Azure DevOps Services) can fail silently unless handled explicitly.

Mitigation

To avoid losing work item history or attachments during migration, it’s important to use dedicated, purpose-built migration tools that are designed to handle these elements reliably rather than relying on manual exports or basic scripts.

After the migration, you should always run thorough validation to confirm everything transferred correctly. This includes checking that the number of revisions, comments, and attachments in the target system matches what you had in the source.

This combination of proper tooling and careful post-migration verification significantly reduces the risk of hidden data loss.

Pitfall #3 - Broken Links Between Work Items, Commits, and Builds

Work items are tightly linked with commits, PRs, and CI/CD pipelines in Azure DevOps. When IDs or URLs change during migration, these cross-references often break. A common example: a feature linked to a commit via work item ID will display broken links if IDs are regenerated.

These broken links lead to a loss of end-to-end traceability, which results in reduced productivity, incorrect reporting, and difficulty in auditing.

Mitigation

To prevent broken links between work items, commits, and builds during an Azure DevOps migration, try to preserve the original IDs wherever possible so that references remain intact.

If preserving them isn’t feasible, use reflected IDs to create a reliable mapping back to the original items so teams can still trace history correctly. After the Azure DevOps links migration, always validate link integrity using tools such as the TFS Work Item Link Tool to ensure relationships between items weren’t disrupted.

Finally, test complete end-to-end scenarios from code changes to work items to pipeline runs to confirm that full traceability has been maintained in the new environment.

Pitfall #4 - User and Identity Mapping Errors

One of the trickiest aspects of Azure DevOps migrations is ensuring identity consistency. Azure DevOps Server may wrap identities in TFS-specific constructs; when migrating to services backed by Microsoft Entra ID (Azure AD), mismatches cause work items to appear as assigned to “unknown” or historical accounts.

In the absence of correct identity mapping, unauthorized users may get access to sensitive data which can lead to security concerns. This makes correct identity mapping critical to the migration process.

Mitigation

To prevent Azure DevOps user mapping issues, create a clear, accurate mapping of all source users to their corresponding target identities before the migration begins. Once the mapping is ready, validate it against your Microsoft Entra (Azure AD) tenant to ensure every user exists, has the correct permissions, and won’t end up with orphaned or inaccessible history after the migration.

Pitfall #5 - Neglecting Pipeline and Build Dependencies

Migrating work items and repos may get most attention, but pipelines are full of dependencies agent pools, service connections, variable groups, environment secrets. Neglecting these leads to broken or insecure pipelines post-migration. These broken connections often need to be recreated manually or via automation tooling.

Mitigation

To prevent Azure DevOps build migration problems and build-related issues, begin by thoroughly auditing all pipeline dependencies such as agent pools, service connections, variable groups, environment variables, and deployment targets so nothing is overlooked.

Once the audit is complete, script the recreation of service connections, agent pools, and other reusable components to ensure they are rebuilt consistently and securely in the target environment.

It also helps to use mapping templates for environment variables and configuration values so that pipelines run exactly as they did before, without unexpected failures caused by missing or mismatched settings.

Pitfall #6 - Poor Validation and Testing

An Azure DevOps migration may look flawless on the surface but only thorough validation will reveal the hidden issues that may be buried. Many teams only check whether projects and work items appear in the new environment, but this is not enough.

Proper validation means confirming that everything, work item counts, history, attachments, links, pipelines, permissions, identities, and repository integrity, has migrated accurately and functions as expected.

Mitigation

To properly validate Azure DevOps migration, run automated validation scripts to compare item counts, attachments, history entries, pipeline runs, and other key metrics between the source and target systems to ensure nothing is missing.

Validation also includes having real users perform UAT to test daily workflows like updating items, running builds, and triggering deployments, which could be missed by automated tests.

Additionally, compare analytics and reports side-by-side helps identify subtle discrepancies in throughput, trends, or historical data.

How to Avoid These Pitfalls (Best Practices)

Below is an Azure DevOps migration checklist, to ensure your business is not vulnerable to the common mistakes made during migrations:

1. Pre-Migration Audit

Inventory source artifacts processes, work items, attachments, identities
Standardize processes across tenants

2. Dry Runs & Tools

Execute dry runs with representative data
Use dedicated migration tooling (e.g., Azure DevOps Migration Tools) which handles history, links, attachments, mapping, and pipelines out of the box.

3. Validation Reports

Compare source vs. target counts and link integrity
UAT with real users validating day-to-day workflows

4. Go-Live Protocol

Cut-over only when tests pass
Ensure rollback or fallback options

Conclusion

Azure DevOps migrations are high-stakes engineering projects. They require not just careful tooling but disciplined planning. From process templates and identity mapping to pipelines and post-migration validation. With structured planning and best practices, teams can avoid common Azure DevOps migration errors and ensure high-fidelity migrations that preserve history, traceability, and productivity.

From Frustration to Language: The Birth of the DeukPack IDL

2026-03-30 14:54:41

DeukPack Brand Image

"Why not just use Thrift? What about Protobuf?"

These are the first questions we hear whenever we introduce DeukPack. And they're fair questions. Thrift and Protobuf are proven, battle-tested tools. We used them successfully for years. The problem was what started becoming visible only after we'd used them well.

This is not an article about introducing a new IDL tool. It's an engineering story about how the friction we accumulated fighting with legacy tools solidified into a design philosophy—and how that philosophy was eventually realized in code.

1. Where the Problem Started: "Nobody Knows What This message Is"

As our systems grew, we started to feel the limits of what the word message could communicate.

// Legacy Protobuf IDL — Is this a DB table? A network packet? Excel data?
message Item {
  int64 item_id = 1;
  string name = 2;
  int32 quantity = 3;
}

In production, this single Item was being used in three different places simultaneously:

  • Server: As an inventory query response payload sent to the client
  • Designer Tools: As a row in the item master data that designers managed in Excel
  • Database: As a row in a table storing per-user inventory state

But the .proto file makes zero distinction between these three contexts. When you ask an AI coding assistant to "write code that handles this Item," the AI guesses which of the three contexts you mean—and that guess is often wrong.

The deeper problem: it takes time to realize the guess was wrong.

2. Searching for a Solution: "Should We Just Abandon Legacy Tools?"

At first, the fix seemed simple. "What if we used a more expressive IDL? Or differentiated contexts with comments?"

Two realities shut that down quickly.

  1. The Weight of Legacy: Tens of thousands of lines of .proto or .thrift files had accumulated. Telling the team "let's throw it all away and migrate to a new IDL" was simply not a realistic option.
  2. Comments Don't Enforce Anything: Expressing intent through comments provides no enforcement. The AI, the compiler, and your colleagues can all ignore them freely.

This is where the design direction crystallized:

"We don't discard legacy. Instead, we layer what legacy cannot express on top of it."

3. Design Philosophy: Embedding a 'Data Identity Card' into IDL Syntax

This philosophy led to DeukPack's Declaration Kinds design.

Where legacy IDLs lumped everything into struct, DeukPack distinguishes data by its purpose at the syntax level.

namespace game

// Item master data — read from files, managed in Excel.
record ItemMaster {
  1> int64 itemId
  2> string name
  3> int32 maxStack
}
table<ItemMaster> = { key: "itemId" }

// Inventory DB row — manages per-user persistent state.
entity UserInventory {
  1> [key] int64 userId
  2> int64 itemId
  3> int32 quantity
}

// Item query response packet — a one-way transient payload.
keyword message_scope 10000
message<10001> ItemQueryResponse {
  1> list<ItemInfo> items
  2> int32 totalCount
}

This distinction produces tangible changes in three directions at once:

  • The Compiler: Generates Excel serialization code for table, DB mapping code for entity, and optimized binary serialization for message<N>—each one correct and different.
  • AI Coding Tools: The declaration keyword alone tells the AI what context this data lives in. The surface area for generating wrong-context code shrinks dramatically.
  • Developers: Someone reading the code for the first time doesn't waste time guessing what this struct is for.

4. "What About Legacy?" — The Mixed Architecture Answer

Once the philosophy was set, the next question was unavoidable:

"What do we do with existing .proto or .thrift files that are already running in production?"

The DeukPack engine was designed to read .proto, .thrift, and .deuk files simultaneously. Existing files are imported with include and DeukPack features are layered on top—no modifications required.

// Include the existing Protobuf file as-is — zero file modifications
include "legacy/item_base.proto"

// Use the legacy record directly, just register it as a table
table<item_base.Item> = { key: "item_id" }

The legacy files are untouched—not a single line changed. The DeukPack engine parses both files together, merges them into a single Unified AST, and generates code in the target language (C#, TypeScript, C++, and more) from that shared representation.

5. "How Is This Even Possible?" — The Technical Foundation of the Unified AST

The reason all of this works is that inside the DeukPack engine, every IDL—regardless of origin—is transformed into a single, common AST structure.

   [Input Sources]                 [Unified AST Hub]          [Output Code]

   legacy.proto (Protobuf)  ----+
                                |
   legacy.thrift (Thrift)   ----+--> [ DeukPack Engine ] --> C# / TS / C++
                                |           (AST)
   new_logic.deuk (Deuk)    ----+

There's a dedicated parser for .thrift files and a separate one for .deuk files—but both parsers produce the same DeukPackAST as output. The code generators look only at the AST; they don't care what the source format was.

The AST carries more than type information. It embeds declarationKind (record, entity, message, table), bracket attributes ([key], [split], etc.), and doc comments—all preserved. Generators read this rich metadata to produce code that precisely matches each declaration's Intent.

Conclusion: Accumulated Frustration Becomes Design, Which Becomes Language

The reason DeukPack IDL looks superficially similar to Thrift or Protobuf—while carrying a fundamentally different philosophy inside—is that it was designed to precisely target the problems legacy tools left unsolved.

Throwing everything out and starting fresh is easy. Preserving what works, while carefully filling in what was always missing on top of it—that's harder, and in practice, far more valuable.

Continues in the next article:

[Designing the Unified AST Hub: Making Multi-Protocol Co-existence Possible] goes deeper into how the engine that makes this mixed architecture possible is structured internally.

🔗 DeukPack Ecosystem

DeukPack aims for a technical ecosystem where AI and human developers grow together, preventing fragmentation in complex systems.