<?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>DEV Community: Saar Ezagouri</title>
    <description>The latest articles on DEV Community by Saar Ezagouri (@saar_ezagouri_f9e823978b6).</description>
    <link>https://dev.to/saar_ezagouri_f9e823978b6</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%2Fuser%2Fprofile_image%2F3923095%2F3162236a-1f88-4ee9-a62d-7b71a851569c.png</url>
      <title>DEV Community: Saar Ezagouri</title>
      <link>https://dev.to/saar_ezagouri_f9e823978b6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saar_ezagouri_f9e823978b6"/>
    <language>en</language>
    <item>
      <title>I shipped my mobile app to production. Key engineering decisions and sub-agents-based QA system.</title>
      <dc:creator>Saar Ezagouri</dc:creator>
      <pubDate>Sun, 10 May 2026 11:02:28 +0000</pubDate>
      <link>https://dev.to/saar_ezagouri_f9e823978b6/i-shipped-my-mobile-app-to-production-key-engineering-decisions-and-a-sub-agent-qa-system-4ed5</link>
      <guid>https://dev.to/saar_ezagouri_f9e823978b6/i-shipped-my-mobile-app-to-production-key-engineering-decisions-and-a-sub-agent-qa-system-4ed5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Brief introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m a solo builder. I built &lt;a href="https://www.trysalute.com/" rel="noopener noreferrer"&gt;Salute&lt;/a&gt;, a cross-platform mobile application focused on structured tracking of workouts, nutrition, and habits — the three core pillars for building a sustainable healthy lifestyle product.&lt;/p&gt;

&lt;p&gt;In this post, I want to walk through some of the more significant technical and architectural decisions I made during the last months of development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building solo: slow is fast&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Working alone changes the nature of execution. You are responsible for both system design and implementation, and every decision compounds quickly.&lt;/p&gt;

&lt;p&gt;I tend to work in a highly time-aware way, optimizing small actions and switching contexts efficiently. But when building a full product solo, I had to shift priorities.&lt;/p&gt;

&lt;p&gt;I followed a principle I learned from my Brazilian Jiu-Jitsu coach: technique first, then power. In practice, this translated to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prioritizing architecture before implementation&lt;/li&gt;
&lt;li&gt;Spending time on system design and edge cases upfront&lt;/li&gt;
&lt;li&gt;Mapping flows visually (I used Miro and physical sketches). Defining constraints and tech decisions early, but keeping flexibility where needed. &lt;/li&gt;
&lt;li&gt;Although this approach felt slower at the beginning, it significantly reduced rework later and improved overall development speed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Flutter for cross-platform development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the key decisions was using Flutter for cross-platform development.&lt;/p&gt;

&lt;p&gt;While I did not perform a deep comparative evaluation with React Native in this project, Flutter proved to be stable and consistent across platforms in practice. The ecosystem was mature enough for all required features, and the community and documentation were reliable and structured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code and sub-agent workflows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During the planning phase, I introduced sub-agent workflows as a core part of the development process.&lt;/p&gt;

&lt;p&gt;I worked with Claude Code (and evaluated other tools such as Gemini Pro, GPT-based coding tools, FlutterFlow, and Firebase Studio), but found that a structured agent-based workflow provided the most control and reliability.&lt;/p&gt;

&lt;p&gt;A key part of this system was building a knowledge layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collecting official documentation and best practices from Flutter&lt;/li&gt;
&lt;li&gt;Structuring them into modular “skills”&lt;/li&gt;
&lt;li&gt;Maintaining a central instruction file (CLAUDE.md) containing architectural rules and coding standards&lt;/li&gt;
&lt;li&gt;Adding platform-specific guidelines from Android (Material Design) and iOS (Human Interface Guidelines)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This created a reusable, structured context layer for the agents, improving consistency in UI/UX and architecture decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sub-agent QA system: a major productivity shift&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most impactful parts of the system was an agent-based QA pipeline.&lt;/p&gt;

&lt;p&gt;As a solo developer, testing becomes a bottleneck. External beta testers help, but feedback cycles are slow and inconsistent. I needed a more deterministic system.&lt;/p&gt;

&lt;p&gt;So I built an internal QA pipeline composed of multiple specialized agents:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;u&gt;Screeners&lt;/u&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each screener is responsible for a specific part of the application (e.g., onboarding flow). Their tasks include but not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI/UX validation against platform guidelines&lt;/li&gt;
&lt;li&gt;Identifying broken states or missing edge cases&lt;/li&gt;
&lt;li&gt;Detecting unlocalized or inconsistent text&lt;/li&gt;
&lt;li&gt;Verifying interaction behavior&lt;/li&gt;
&lt;li&gt;Responsive and adaptive UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They operate with direct access to the running app via MCP tools and the Dart SDK environment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;u&gt;Validators&lt;/u&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Validators review screener outputs and filter noise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove false positives&lt;/li&gt;
&lt;li&gt;Split overloaded screener tasks when necessary&lt;/li&gt;
&lt;li&gt;Improve signal-to-noise ratio in reported issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They do not modify the system, only verify findings.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;u&gt;Reviewers&lt;/u&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reviewers consolidate validated findings into structured reports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Summarize issues per feature area&lt;/li&gt;
&lt;li&gt;Refine or generate targeted improvement notes&lt;/li&gt;
&lt;li&gt;Update or extend internal “skills” documentation when needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are responsible for turning raw findings into actionable engineering work - for the head agent.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;u&gt;Orchestrator&lt;/u&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The orchestrator manages execution flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screeners run first&lt;/li&gt;
&lt;li&gt;Validators refine outputs&lt;/li&gt;
&lt;li&gt;Reviewers structure the final reports&lt;/li&gt;
&lt;li&gt;Implementation follows based on prioritized findings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A key aspect of making this system work in practice was carefully managing agent permissions and tool access. Each agent was given a very specific role, with tightly scoped responsibilities and minimal required context. This was important both for maintaining order in the workflow and for controlling token usage across the system. Overloading agents with broad access or unclear responsibilities quickly reduced efficiency and increased noise in the output, so strict separation of concerns and tool-level access control became a core design principle. When optimized - it works very good and saves priceless time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical QA infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The QA system was built around a direct runtime connection to the Flutter application using the Dart SDK MCP server, which exposes the Dart Tooling Daemon (DTD) and flutter_driver capabilities to agents.&lt;/p&gt;

&lt;p&gt;Each screener agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launches the app in debug mode on an emulator&lt;/li&gt;
&lt;li&gt;Connects to the Dart Tooling Daemon&lt;/li&gt;
&lt;li&gt;Interacts with the live application through MCP tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI interaction (taps, input, navigation, scrolling)&lt;/li&gt;
&lt;li&gt;Widget tree inspection&lt;/li&gt;
&lt;li&gt;Runtime log and error monitoring&lt;/li&gt;
&lt;li&gt;Hot reload / hot restart cycles
Because agents interact directly with the running app, there is no need for traditional test harness code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I intentionally avoided integration_test due to both architectural constraints and known build issues (notably release-time dependency stripping of required libraries under R8, which can break plugin registration).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outcome&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This QA architecture significantly reduced manual testing overhead and improved iteration speed during development. For a solo builder, it effectively acted as a scalable internal QA team, without introducing heavy testing infrastructure.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>claude</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
