# Doximity

Doximity is building the default Clinical AI Suite. Read more on our Technical Blog.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Migrating Doximity's iOS Newsfeed to SwiftUI Without Disrupting Users or Development

DevFeed: [Migrating Doximity's iOS Newsfeed to SwiftUI Without Disrupting Users or Development](<https://devfeed.tech/articles/migrating-doximity-s-ios-newsfeed-to-swiftui-without-disrupting-users-or-development-20037.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/migrating-doximity-s-ios-newsfeed-to-swiftui-without-disrupting-users-or-development>)

Author: Doximity

Published: 2026-09-04T10:50:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [iOS](<https://devfeed.tech/topics/ios.md>), [SwiftUI](<https://devfeed.tech/topics/swiftui.md>), [Development](<https://devfeed.tech/topics/development.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [app](<https://devfeed.tech/tags/app.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [bridge](<https://devfeed.tech/tags/bridge.md>), [development](<https://devfeed.tech/tags/development.md>), [incremental](<https://devfeed.tech/tags/incremental.md>), [ios](<https://devfeed.tech/tags/ios.md>), [migration](<https://devfeed.tech/tags/migration.md>), [swiftui](<https://devfeed.tech/tags/swiftui.md>)

### AI overview

This article describes Doximity's incremental migration of its iOS Newsfeed from UIKit to SwiftUI. The team moved one section at a time, kept UIKit and SwiftUI compatible, continuously measured behavior, and made each step reversible. The feed's server-driven card and section architecture, with state and logic managed in The Composable Architecture, provided the migration boundary.

### Source excerpt

The Newsfeed is one of the most-used features in the Doximity iOS app. It is the first thing many users see when they open the app. For doctors checking in between patients or residents catching up during a break, it has to be fast and efficient. Those expectations defined success for the migration. Feature work had to continue, analytics had to remain reliable, and the experience had to remain familiar to users even as the underlying implementation changed. We approached the migration less like a rewrite and more like a controlled rollout. We moved one section at a time, kept the UIKit and SwiftUI implementations compatible, measured behavior continuously, and made each step reversible. The technical bridge enabled the migration, but this incremental approach reduced the risk to the product. The Newsfeed brings several types of content together in a single scrolling experience. Here are a few examples of the different cards users may encounter: The Architecture Behind the Newsfeed Before discussing the migration, it helps to understand the architecture that made our incremental approach possible. The Newsfeed is not one large custom view. It is a server-driven list built from cards, with each card assembled from smaller sections. The server controls the composition of the feed. It tells the app which cards should appear, which sections belong inside each card, and the order in which those sections should render. The iOS app owns the rendering and behavior of each known section type. This separation makes the feed flexible. Rather than relying on a fixed set of hardcoded card types, the server can compose cards from reusable sections such as headlines, authors, summaries, media, polls, and social actions. By combining and ordering those sections differently, the server can create different card layouts without requiring a new implementation in the app. This is roughly what the model looks like: Server-driven feed response Newsfeed ├─ Card │ ├─ Section: author │ ├─ S

## From Batch Snapshots to Near-Real-Time Data

DevFeed: [From Batch Snapshots to Near-Real-Time Data](<https://devfeed.tech/articles/from-batch-snapshots-to-near-real-time-data-20029.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/from-batch-snapshots-to-near-real-time-data>)

Author: Doximity

Published: 2026-08-04T16:29:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [data](<https://devfeed.tech/topics/data.md>), [Kafka](<https://devfeed.tech/topics/kafka.md>), [Streaming](<https://devfeed.tech/topics/streaming.md>), [MySQL](<https://devfeed.tech/topics/mysql.md>), [Amazon Aurora](<https://devfeed.tech/topics/amazon-aurora.md>)

Tags: [amazon-aurora](<https://devfeed.tech/tags/amazon-aurora.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [data](<https://devfeed.tech/tags/data.md>), [kafka](<https://devfeed.tech/tags/kafka.md>), [mysql](<https://devfeed.tech/tags/mysql.md>), [pipelines](<https://devfeed.tech/tags/pipelines.md>), [streaming](<https://devfeed.tech/tags/streaming.md>)

### AI overview

Doximity describes combining batch database snapshots with Change Data Capture to make data available in minutes while retaining batch-based consistency and recovery guarantees. The design uses Kafka and includes a trusted snapshot, metadata-preserving routing, a base-plus-delta view, and synthetic cascade deletes. In a 12-day measurement window, 95% of sampled events reached the queryable intermediate layer within eight minutes of publication to Kafka.

### Source excerpt

Change Data Capture (CDC) is often presented as a straightforward pipeline: read a database transaction log, publish each change, and apply those changes to another system. That description is accurate, but it leaves out many of the decisions that determine whether the resulting data can be trusted. At Doximity, we already had a batch pipeline that periodically copied snapshots of application databases into our data warehouse. Those snapshots were reliable, but their freshness was measured in hours. We introduced CDC to make changes available in minutes so downstream transformations and operational analytics would not have to wait for the next batch snapshot. We continued using the batch pipeline for the consistency and recovery guarantees it already provided. Over a 12-day measurement window, 95% of events from a stratified sample of active tables reached the queryable intermediate layer within eight minutes of being published to Kafka. The most interesting parts of the project were not the connections from a source database to Kafka or from Kafka to Snowflake, but four questions we had to answer around them: How could we reuse our existing, transactionally consistent batch snapshots as an on-demand starting point for CDC, without reprocessing every existing row? How could we onboard new tables and absorb schema changes from many source databases across our products without growing operational overhead for each one? How could new changes become queryable without waiting for the warehouse to merge them into place? How could we handle cascading child deletes that MySQL performs but never emits as individual binary-log events? Our answers are the four design decisions in this article: a trusted batch snapshot, metadata-preserving routing, a base-plus-delta view, and synthetic cascade deletes. Together, they turned a stream of row changes into a system we could bootstrap, scale, validate, and recover. The sections that follow explain the tradeoffs and guardrails so rea

## Doximity Ask

DevFeed: [Doximity Ask](<https://devfeed.tech/articles/doximity-ask-20025.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/doximity-ask>)

Author: Doximity

Published: 2026-06-23T09:30:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [Retrieval-Augmented Generation](<https://devfeed.tech/topics/retrieval-augmented-generation.md>), [Hallucination detection](<https://devfeed.tech/topics/hallucination-detection.md>)

Tags: [agentic](<https://devfeed.tech/tags/agentic.md>), [ai](<https://devfeed.tech/tags/ai.md>), [grounding](<https://devfeed.tech/tags/grounding.md>), [hallucinations](<https://devfeed.tech/tags/hallucinations.md>), [retrieval-augmented-generation](<https://devfeed.tech/tags/retrieval-augmented-generation.md>), [review](<https://devfeed.tech/tags/review.md>), [verification](<https://devfeed.tech/tags/verification.md>)

### AI overview

The article explains how Doximity Ask approaches reliability in clinical AI. It describes a HIPAA-compliant clinical reference platform that combines retrieval-augmented generation, validated tools, a reasoning model, citation-grounded responses, automated verification, physician-authored evaluation, and production monitoring. It argues that reliability is a system property spanning retrieval, ranking, reasoning, tool use, verification, and evaluation.

### Source excerpt

Medical AI has attracted confident claims: perfect scores, no hallucinations, a system that gracefully declines whenever the evidence runs out. But are these dimensions the right way to think about a tool that physicians use to make real-world decisions? For clinical AI, reliability is not just a question of whether an answer is correct. It is also a question of whether a physician can understand where the answer came from, evaluate the supporting evidence, and identify situations where uncertainty remains. How Doximity Ask Answers Clinical Questions Few domains face stakes as high as medical AI, where system performance can directly influence patient outcomes, clinical workflows, and healthcare professionals' decisions. Clinical reference requires traceable grounding, numerically exact doses and scores, and explicit handling of situations in which the available evidence is insufficient to support an answer. At the same time, healthcare providers often work under significant time constraints and have exceptionally high expectations for the performance and reliability of AI systems. Doximity Ask is a HIPAA compliant composite clinical reference platform for question answering at the point of care. It combines retrieval-augmented generation over a physician-governed evidence library, multi-turn agentic tool use through a fixed registry of validated calculators and structured lookups, and a post-trained reasoning model that orchestrates retrieval, tool calls, and citation-grounded generation. Automated verifiers, physician-authored rubrics, and in-product physician review form one evaluation loop that grades releases, defines training rewards, and monitors production. Reliability Is A System Property Over 150 health systems have purchased the Doximity Clinical AI Suite including 8 of the top 20 hospitals in the country, therefore reliability is paramount. The reliability of a clinical AI system depends on more than the capabilities of its underlying language model. Pro

## Profiling Performance Bottlenecks in Production

DevFeed: [Profiling Performance Bottlenecks in Production](<https://devfeed.tech/articles/profiling-performance-bottlenecks-in-production-20040.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/profiling-performance-bottlenecks-in-production>)

Author: Doximity

Published: 2026-06-18T12:53:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [Code](<https://devfeed.tech/topics/code.md>), [User Experience](<https://devfeed.tech/topics/user-experience.md>)

Tags: [how-to](<https://devfeed.tech/tags/how-to.md>), [latency](<https://devfeed.tech/tags/latency.md>), [performance](<https://devfeed.tech/tags/performance.md>), [production](<https://devfeed.tech/tags/production.md>), [profiling](<https://devfeed.tech/tags/profiling.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [time](<https://devfeed.tech/tags/time.md>)

### AI overview

This article explains how to use profiling to identify performance bottlenecks in production Ruby applications. It contrasts instrumenting and sampling profilers, emphasizing that sampling has lower overhead and is suitable for production. The article reports that profiling reduced a background job's runtime by about 80%.

### Source excerpt

One of our background jobs was so slow that users assumed it was broken. They would kick it off, wander away, knowing it would take ages to complete. Turns out the job was fine. It was just taking its sweet time. We eventually cut its runtime by about 80%, and the fix was so small it was almost insulting. You could have stared at the code for hours and missed it. A profiler found it in minutes. This post is about how to think about profiling so you reach for it at the right moment, not as a first reflex. Performance is a KPI, Not a Vibe It's easy to treat performance as something you tune when someone complains. But latency is a feature, and a slow background job has real downstream costs: a worse user experience, more compute burned, queues backing up, and a quietly growing tolerance for "well, that's just how long it takes." The mindset shift that helped us was treating performance like any other key metric we hold ourselves accountable to. That means it has to be measured, it has to have a number, and that number has to move in a direction we choose on purpose. "It feels faster" is not a result. "p95 went from 214 seconds to 69 seconds on a representative input" is a result. Which raises the obvious question: Once you've decided to take a number seriously, how do you find out where the time actually goes? Profilers, And How They Work A profiler answers one question very well: Inside a single execution of code, where is the time being spent? We can get that answer using one of two broad strategies: Instrumenting (tracing) profilers wrap every method call to record when it starts and stops. You get extremely precise, complete call counts and timings. But the overhead is high, and that overhead can distort the very timings you're trying to measure. Wrapping millions of tiny method calls makes the cheap ones look expensive. Sampling profilers take the opposite approach. Instead of instrumenting every call, they periodically interrupt the program -- say, hundreds of ti

## How We're Thinking About Agentic Systems

DevFeed: [How We're Thinking About Agentic Systems](<https://devfeed.tech/articles/how-we-re-thinking-about-agentic-systems-20031.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/how-we-re-thinking-about-agentic-systems>)

Author: Doximity

Published: 2026-06-15T10:03:00Z

Content type: opinion

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [Automation](<https://devfeed.tech/topics/automation.md>), [systems](<https://devfeed.tech/topics/systems.md>), [Software Engineering](<https://devfeed.tech/topics/software-engineering.md>), [Authorization](<https://devfeed.tech/topics/authorization.md>), [observability](<https://devfeed.tech/topics/observability.md>)

Tags: [agentic](<https://devfeed.tech/tags/agentic.md>), [agentic-ai](<https://devfeed.tech/tags/agentic-ai.md>), [ai](<https://devfeed.tech/tags/ai.md>), [automation](<https://devfeed.tech/tags/automation.md>), [observability](<https://devfeed.tech/tags/observability.md>), [reasoning](<https://devfeed.tech/tags/reasoning.md>), [software-engineering](<https://devfeed.tech/tags/software-engineering.md>), [systems](<https://devfeed.tech/tags/systems.md>)

### AI overview

Doximity discusses how to decide whether a workflow needs an agent, arguing that predictable processes are better served by deterministic automation. Agents are more useful when workflows require judgment, adaptation, tool selection, or interpretation of messy context, but they introduce additional failure modes and operational requirements.

### Source excerpt

In the current rush to adopt agentic systems, the most dangerous question isn't "what can we make agentic?" but "where do agents actually help?" At Doximity, we've found that moving from a working demo to a production-grade agent requires a shift in focus--from model capability to system design. That framing matters because a working demo and a production system are very different things. The demo proves something can work once. The product has to work repeatedly, with real users, real permissions, real data, and real failure modes. That matters even more in healthcare-oriented products like Ask, where information surfaced to clinicians helps support patient care. A few patterns are starting to feel useful: Solve the Workflow, Not the AI A valuable attribute of software engineering is knowing when not to overbuild. That sounds obvious, but it gets harder when the shiny new toy is genuinely useful. Agentic AI is one of those moments. Because agents can reason, call tools, and move through workflows in ways traditional automation cannot, it becomes tempting to look at every process and ask, "Could this be an agent?" That is the wrong first question. The better question is: what does this workflow actually need? If the process is predictable, repeatable, and follows a known set of rules, it probably does not need an agent. It needs good automation, clean inputs, reliable APIs, and clear failure handling. Agents become more useful when the workflow requires judgment: interpreting messy context, choosing between tools, adapting based on what it finds, or making decisions where the path is not fully known upfront. That distinction matters because adding an agent is not free. It introduces new failure modes around reasoning, permissions, observability, evaluation, retries, and edge cases. Sometimes that tradeoff is worth it. Sometimes it is just a more complicated way to do what a well-designed workflow could have handled deterministically. So the starting point should not

## LeadDev StaffPlus 2025: My Top Takeaways

DevFeed: [LeadDev StaffPlus 2025: My Top Takeaways](<https://devfeed.tech/articles/leaddev-staffplus-2025-my-top-takeaways-20034.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/leaddev-staffplus-2025-my-top-takeaways>)

Author: Doximity

Published: 2025-12-02T13:27:00Z

Content type: opinion

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Tech Lead](<https://devfeed.tech/topics/tech-lead.md>), [Programming](<https://devfeed.tech/topics/programming.md>)

Tags: [conference](<https://devfeed.tech/tags/conference.md>), [leadership](<https://devfeed.tech/tags/leadership.md>), [management](<https://devfeed.tech/tags/management.md>), [software-engineer](<https://devfeed.tech/tags/software-engineer.md>), [tech-lead](<https://devfeed.tech/tags/tech-lead.md>)

### AI overview

A Staff Software Engineer at Doximity reflects on takeaways from LeadDev StaffPlus NY, focusing on egoless leadership, delegating programming work, and elevating colleagues to increase engineering impact.

### Source excerpt

As a newly minted Staff Software Engineer at Doximity, I've been looking for ways to maximize my impact on the teams I support. My mandate as a Staff Software Engineer is to solve the kinds of problems that affect every team in my umbrella, not just the one team where I do my own IC work. That's a big change from my previous role as tech lead of a small team. I've enjoyed following LeadDev's content, from blog posts and videos to webinars, so attending a LeadDev conference has been on my bucket list for a while. I got my chance when I learned they were hosting their conference in New York City for StaffPlus engineers (engineering leaders who are in roles anywhere from Staff to Distinguished Engineer). I came away from the conference with a lot of ideas on how to improve my impact as an engineering leader and a plan to get more traction on a difficult project I've been leading. Here are some of the highlights from my experience at StaffPlus NY. Lead Without Ego Image: Katie Sylor-Miller during her talk "Mind the gap: Navigating the Staff+ Performance Cliff" Katie Sylor-Miller's talk "Mind the gap: Navigating the Staff+ Performance Cliff" was fantastic. She emphasized the need for egoless leadership and touched on the benefits you reap when you lead with humility. In particular, as StaffPlus engineers, we're not meant to be writing and shipping all the code all the time. We're meant to give those opportunities to other engineers on our teams and build them up. This wasn't new advice to me, but it's worth hearing again and again as I develop in my technical leadership position. It was particularly useful as it connected with a technical project I've been working on that has grown in scope. I've been feeling an increasing burden that I can't do all the coding and project management this project requires with the resources I have, on top of my other responsibilities. I realized during Katie's talk that I can move my project forward by delegating more of the programming t

## Inside Data Engineering at Doximity: Building for Impact

DevFeed: [Inside Data Engineering at Doximity: Building for Impact](<https://devfeed.tech/articles/inside-data-engineering-at-doximity-building-for-impact-20032.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/inside-data-engineering-at-doximity-building-for-impact>)

Author: Doximity

Published: 2025-08-20T15:29:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [data-engineering](<https://devfeed.tech/topics/data-engineering.md>), [data](<https://devfeed.tech/topics/data.md>), [coding](<https://devfeed.tech/topics/coding.md>), [SQL](<https://devfeed.tech/topics/sql.md>)

Tags: [coding](<https://devfeed.tech/tags/coding.md>), [data-engineering](<https://devfeed.tech/tags/data-engineering.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [pipelines](<https://devfeed.tech/tags/pipelines.md>), [sql](<https://devfeed.tech/tags/sql.md>), [systems](<https://devfeed.tech/tags/systems.md>)

### AI overview

This article explains how Doximity organizes data engineering into platform-focused and product-focused roles. It describes the teams' responsibilities, daily engineering practices, and how product data engineers use pipelines, queries, and data sources to support product development and user value.

### Source excerpt

IBM defines Data Engineering as "the practice of designing and building systems for the aggregation, storage, and analysis of data at scale, empowering organizations to get insights in real time from large datasets." While this definition generally captures what data engineering is, it blends together distinct specializations that enable scalable transformation of raw data to actionable insights. At Doximity, we break this down into two distinct roles: product-focused data engineers and platform-focused data engineers, each playing a crucial role to fuel our organization with timely, reliable data. Our platform-focused data engineers sit on a centralized team that owns two core areas: (1) providing a high-velocity, low-risk data platform and (2) providing reliable and accessible services, standards, and foundational datasets. Our product-focused data engineers are embedded directly on product teams and leverage our data platform, its services, and data to shape our products and deliver value directly to our users. Let's take a closer look at a day in the life of our product team data engineers. Finding Flow As a member of a cross-functional product team, mornings typically start with a quick scrum (sometimes live, sometimes asynchronously in Slack), providing a shared space to align priorities and highlight blockers before diving into focused work. Meetings are minimal; most of the day is spent deep in the code, refining data pipelines, optimizing queries, reviewing code, and working closely with the other members on your team. We are first and foremost engineers, and take pride in spending as much time as possible doing what we love: coding. This includes everything from small snowflake SQL logic tweaks to systemic architecture designs. The goal isn't only to move data but also to ensure that every system we build remains maintainable for fellow engineers and intuitive for analysts. It's no wonder that one of our guiding principles is "Always leave the code better

## The Modern Data Toolbox

DevFeed: [The Modern Data Toolbox](<https://devfeed.tech/articles/the-modern-data-toolbox-20046.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/the-modern-data-toolbox>)

Author: Doximity

Published: 2025-08-18T00:36:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [data](<https://devfeed.tech/topics/data.md>), [Large Language Model](<https://devfeed.tech/topics/llm.md>), [Machine learning](<https://devfeed.tech/topics/machine-learning.md>), [data-modeling](<https://devfeed.tech/topics/data-modeling.md>), [Statistics](<https://devfeed.tech/topics/statistics.md>), [Machine Learning, Security Attacks](<https://devfeed.tech/topics/machine-learning-security-attacks.md>)

Tags: [data](<https://devfeed.tech/tags/data.md>), [data-modeling](<https://devfeed.tech/tags/data-modeling.md>), [datasets](<https://devfeed.tech/tags/datasets.md>), [fraud](<https://devfeed.tech/tags/fraud.md>), [fraud-detection](<https://devfeed.tech/tags/fraud-detection.md>), [large-language-models-llms](<https://devfeed.tech/tags/large-language-models-llms.md>), [machine-learning](<https://devfeed.tech/tags/machine-learning.md>), [statistics](<https://devfeed.tech/tags/statistics.md>)

### AI overview

The article explains how to choose among large language models, machine learning, and statistical methods based on data characteristics, goals, scale, and explainability requirements. It argues that complex data problems often benefit from hybrid systems that combine these approaches, illustrating the idea with a multi-layered fraud detection system for payment processing.

### Source excerpt

Matching the Tool to the Task A Quick Recap In a previous article, we focused on the strengths of Large Language Models (LLMs), traditional Machine Learning (ML), and statistical methods and recommended 4 key questions to help you choose the right tool for a data solution. Your Data: Is it structured or unstructured? Bounded or unbounded? Your Goal: Do you need prediction, generation, or inference? Your Data Volume: Are you working with massive datasets or limited samples? Your Need for Transparency: Is deep explainability or strict repeatability a requirement? The key takeaway was that LLMs excel at understanding and generating unstructured, unbounded language; ML models are the gold standard for prediction on structured data; and statistics are invaluable for inference and causality, especially with limited data. However, the most complex and valuable real-world problems rarely fit neatly into one box. What if you need to understand unstructured customer feedback and use it to accurately predict churn? This is where hybrid approaches come in, combining the capabilities of each tool to create a system that is greater than the sum of its parts. Below, we present a few examples showcasing how working with hybrid data approaches helps unlock greater value. Hybrid Data Solutions In our experience, the most effective data solutions often emerge from combining multiple data modeling approaches. Rather than viewing LLMs, ML, and statistics as competitors, we recommend considering them as complementary parts of your broader data toolbox. 1. A Multi-Layered Fraud Detection System built using ML, LLM and Statistics Let's consider a high-stakes and regulated environment of a payments processing system. The primary challenge is to detect and block fraudulent transactions in real-time without incorrectly declining legitimate purchases. In addition, the decision-making process should be transparent and auditable. The analytics workhorse of such a system will be a real-time trans

## Deploying Airflow Data Pipelines with a DAG Synchronization Service

DevFeed: [Deploying Airflow Data Pipelines with a DAG Synchronization Service](<https://devfeed.tech/articles/a-smarter-way-to-deploy-data-pipelines-20021.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/a-smarter-way-to-deploy-data-pipelines>)

Author: Doximity

Published: 2025-03-12T14:28:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [airflow](<https://devfeed.tech/topics/airflow.md>), [data](<https://devfeed.tech/topics/data.md>), [Amazon S3](<https://devfeed.tech/topics/amazon-s3.md>), [CI/CD](<https://devfeed.tech/topics/cicd.md>)

Tags: [airflow](<https://devfeed.tech/tags/airflow.md>), [amazon-s3](<https://devfeed.tech/tags/amazon-s3.md>), [ci-cd](<https://devfeed.tech/tags/ci-cd.md>), [container](<https://devfeed.tech/tags/container.md>), [deployment](<https://devfeed.tech/tags/deployment.md>), [pipelines](<https://devfeed.tech/tags/pipelines.md>), [s3](<https://devfeed.tech/tags/s3.md>)

### AI overview

Doximity describes replacing Airflow container image rebuilds and scheduled service restarts with a DAG synchronization service that continuously updates DAGs from Amazon S3. The approach reduced deployment times from about 30 minutes to under one minute and reduced UI disruption and downtime.

### Source excerpt

At Doximity, we have nearly 20 data teams responsible for the development of data pipelines to support product and business intelligence needs. These teams rely on Apache Airflow to orchestrate over 900 active DAGs (fancy word for data pipelines), with dozens of updates deployed daily. However, with the growth of our data platform team, the bottlenecks in our deployment process for data pipelines could no longer be ignored. Deploying new pipelines or updating existing ones required building, publishing, and deploying a new Airflow container image--a process that could take up to 20 minutes. To make matters worse, pulling in the latest updates meant restarting Airflow services, causing temporary UI disruptions and delaying workflows--the salt in the wound, if you will. In this article, we will discuss in further details the bottlenecks of our legacy deployment system and how we overcame them by developing a DAG synchronization service that continuously updates DAGs directly from Amazon S3 object storage. This new approach not only accelerated deployment times--reducing them from 30 minutes to under one--but also improved system reliability, reduced downtime, and enhanced operational flexibility. Problem Overview Prior to the sync service, DAGs were deployed by building them into the Airflow container image using a CI/CD pipeline. This was both time-consuming and resource-intensive, with each build and delivery process taking nearly 20 minutes to complete. With dozens of teams pushing updates daily, each triggering a full image rebuild, these delays were a clear bottleneck to our productivity. Pulling in these changes required scheduled restarts of the Airflow Scheduler and Web Server at regular intervals. These restarts, while necessary, caused temporary (and dare I say, annoying) disruptions to the Airflow Web UI. Refreshing your screen only to be greeted by a 503 error was the virtual equivalent of stubbing your toe--frustrating and painfully avoidable. Factoring in the

## Balancing Individual Contributor Work and Management in Data Leadership

DevFeed: [Balancing Individual Contributor Work and Management in Data Leadership](<https://devfeed.tech/articles/the-art-of-data-management-20044.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/the-art-of-data-management>)

Author: Doximity

Published: 2024-07-22T15:00:00Z

Content type: opinion

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Data Management](<https://devfeed.tech/topics/data-management.md>), [data-engineering](<https://devfeed.tech/topics/data-engineering.md>), [data analytics](<https://devfeed.tech/topics/data-analytics.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [data-analytics](<https://devfeed.tech/tags/data-analytics.md>), [data-engineering](<https://devfeed.tech/tags/data-engineering.md>), [data-management](<https://devfeed.tech/tags/data-management.md>)

### AI overview

This opinion article examines the Data Strategist role and the player-coach model in data leadership. It argues that combining individual contributor work with people management can build trust, improve collaboration, and provide a closer understanding of technical challenges.

### Source excerpt

The rise of a new title in the data industry, Data Strategist, caught my attention recently. Initially, I was skeptical. "Isn't this just a fancy term for a Data Manager?" I wondered. However, as I delved deeper, I realized my perspective was heavily influenced by my recent tenure at Doximity. At Doximity, the Data Engineering and Data Analytics Manager roles have always blended technical individual contributor work (often referred to as "IC Work") with responsibilities as people managers and functional leaders in the data organization and product. Prior to Doximity, I rarely had managers who had the expectations or bandwidth to do both. This player/coach role might sound too good to be true. Imagine a role where you could work with data, cultivate people and teams, and build data strategies that propel a business towards success, all without working 80 hours a week. After over five years as a manager at Doximity, I can confidently say it is not only possible, but it is also the best type of management role (and a role we are currently hiring for 🤩). Inspired, I reached out to our Data Leadership team here at Doximity to discuss why and how we aim to find balance amidst the chaos. Benefits of IC Work When Managing "Actions speak loudest. One of the fastest ways I found to gain trust from reports, peers, and stakeholders is by writing code to address a technical issue they care about. This approach works especially well if you are inheriting or joining a new team." - Doximity Data Analytics Manager "Understanding what all the teams are working on and enhancing collaboration among them is probably one of the best things about being a manager because you can facilitate communication to different silos that could benefit from each other." - Doximity Data Engineering Manager Whether it has been communicated explicitly or not, if you're expected to do IC work and management, you're doing two jobs. However, I view this as an opportunity to actively improve my skills and co

## Tropical.rb Conference and Rails Girls São Paulo

DevFeed: [Tropical.rb Conference and Rails Girls São Paulo](<https://devfeed.tech/articles/tropical-rb-conference-and-rails-girls-sao-paulo-20048.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/tropical-rb-conference-and-rails-girls-sao-paulo>)

Author: Doximity

Published: 2024-05-22T16:12:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Ruby on Rails](<https://devfeed.tech/topics/ruby-on-rails.md>), [Ruby](<https://devfeed.tech/topics/ruby.md>), [Development](<https://devfeed.tech/topics/development.md>), [Programming](<https://devfeed.tech/topics/programming.md>), [software-development](<https://devfeed.tech/topics/software-development.md>), [Software Engineering](<https://devfeed.tech/topics/software-engineering.md>)

Tags: [brazil](<https://devfeed.tech/tags/brazil.md>), [community](<https://devfeed.tech/tags/community.md>), [conference](<https://devfeed.tech/tags/conference.md>), [developers](<https://devfeed.tech/tags/developers.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [event](<https://devfeed.tech/tags/event.md>), [global](<https://devfeed.tech/tags/global.md>), [junior](<https://devfeed.tech/tags/junior.md>), [learning](<https://devfeed.tech/tags/learning.md>), [programming](<https://devfeed.tech/tags/programming.md>), [projects](<https://devfeed.tech/tags/projects.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [ruby-on-rails](<https://devfeed.tech/tags/ruby-on-rails.md>), [skills](<https://devfeed.tech/tags/skills.md>), [software-development](<https://devfeed.tech/tags/software-development.md>)

### AI overview

Doximity sponsored the Tropical.rb Rails conference in São Paulo and the following Rails Girls São Paulo event. The events covered Ruby on Rails, its community and upcoming Rails 8 features, while Rails Girls participants collaborated on a mentoring app and received guidance toward advancing their software development skills.

### Source excerpt

On April 4th and 5th, 2024, Doximity sponsored Tropical.rb, also known as "The Latin America Rails Conference," in São Paulo, Brazil. This event gathered developers from across Latin America and beyond. It served as a dynamic platform for discussing Ruby on Rails, sharing knowledge, and networking among professionals in the field. The Doximity team at Tropical.rb Doximity has utilized Ruby on Rails since its founding, attributing significant success to the framework. The timing of the recent conference coincided with a resurgence in Rails' popularity, marked by new features and increased adoption among start-ups and new companies.The framework's robust foundation is evidenced by its daily use in major companies such as Doximity, Shopify, AppSignal, and 37Signals. The Tropical.rb conference featured keynotes from prominent Rails core team members Aaron Patterson and Eileen Uchitelle, who provided deep dives into the internals of Rails, explaining some of its magic. Rafael França shared insights on his experiences and the pivotal role of the Ruby on Rails community. The event highlighted numerous success stories of projects and companies built using Rails. Further excitement was generated by discussions on upcoming features in Rails 8, such as Propshaft, Kamal, and Thruster, detailed in Breno Gazzola's keynote. A central theme of the conference was Rails' suitability as a "one-person framework", with Rails 8 advancements reinforcing this concept. Rails Girls São Paulo The day after Tropical.rb, Doximity, in partnership with The Rails Foundation, sponsored the latest edition of Rails Girls São Paulo, a global non-profit initiative dedicated to introducing women of all ages to the world of software development. This edition of Rails Girls focused on empowering women with a programming background to improve their skills and guide them in their journey from junior to mid-level positions and beyond. Our SVP of Engineering, Bruno Miranda, attended the event, along with a fe

## Evaluating Doximity GPT with Ground Truths and LLM Performance Metrics

DevFeed: [Evaluating Doximity GPT with Ground Truths and LLM Performance Metrics](<https://devfeed.tech/articles/beyond-accuracy-20023.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/beyond-accuracy>)

Author: Doximity

Published: 2024-05-10T13:00:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [LLM evaluation / benchmarking](<https://devfeed.tech/topics/llm-evaluation-benchmarking.md>), [Large Language Model](<https://devfeed.tech/topics/llm.md>), [Machine learning](<https://devfeed.tech/topics/machine-learning.md>), [AI Development](<https://devfeed.tech/topics/ai-development.md>)

Tags: [evaluation](<https://devfeed.tech/tags/evaluation.md>), [hipaa](<https://devfeed.tech/tags/hipaa.md>), [large-language-models-llms](<https://devfeed.tech/tags/large-language-models-llms.md>), [llm-evaluation](<https://devfeed.tech/tags/llm-evaluation.md>), [machine-learning](<https://devfeed.tech/tags/machine-learning.md>)

### AI overview

This article explains how Doximity evaluates its Doximity GPT medical writing assistant. It discusses using ground truths and golden datasets to establish baseline metrics, comparing contender models, and combining standard metrics, manual review, benchmarks, and LLM-assisted evaluation to assess relevance, coherence, factual accuracy, and ethical compliance.

### Source excerpt

At Doximity, we go to great lengths to ensure the quality of our products aligns with the standards physicians require. Across various industries, Large Language Models (LLMs) have become the backbone of numerous applications, driving advancements in everything from natural language processing to automated content creation. As we continue to develop products that make use of these LLMs, the need for rigorous and comprehensive evaluation of their outputs has never been more critical. Strap in as we explore the process for evaluating our Doximity GPT product, Doximity's HIPAA-compliant medical writing assistant, focusing on the importance of using "ground truths" to establish baseline metrics and the relative performance of contender models. A Brief Overview of How LLMs Generate Outputs LLMs are trained on vast amounts of textual data in order to learn patterns, structures, and nuances of language. By processing this data, these models develop the ability to generate text that mimics human writing. The output generation process involves the model understanding the input prompt, enhancing its focus via a system prompt, running all of that through its learned information and constructing a coherent and contextually relevant response. While this capability makes LLMs incredibly versatile, it also introduces unique challenges in ensuring the outputs meet specific quality and accuracy standards. LLM Evaluation: What is it and Why Does it Matter? Accuracy, precision, and recall are standard metrics that help evaluate different aspects of classification model quality in machine learning, and these metrics are still incredibly important for LLM evaluation as well. Additional traditional methods include manual review and comparison against predefined benchmarks. However, as LLMs grow more complex, these methods become less feasible due to the sheer volume of outputs and the nuanced understanding required to assess them. In addition to standard machine learning performance metr

## Scaling with Deeplinks on Android

DevFeed: [Scaling with Deeplinks on Android](<https://devfeed.tech/articles/scaling-with-deeplinks-on-android-20042.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/scaling-with-deeplinks-on-android>)

Author: Doximity

Published: 2024-04-08T11:34:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>), [Library](<https://devfeed.tech/topics/library.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [annotation-processor](<https://devfeed.tech/tags/annotation-processor.md>), [build](<https://devfeed.tech/tags/build.md>), [code](<https://devfeed.tech/tags/code.md>), [complexity](<https://devfeed.tech/tags/complexity.md>), [deeplinks](<https://devfeed.tech/tags/deeplinks.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [library](<https://devfeed.tech/tags/library.md>), [manifest](<https://devfeed.tech/tags/manifest.md>), [mapping](<https://devfeed.tech/tags/mapping.md>), [module](<https://devfeed.tech/tags/module.md>), [pipeline](<https://devfeed.tech/tags/pipeline.md>), [route](<https://devfeed.tech/tags/route.md>)

### AI overview

This tutorial explains how to scale Android deeplink handling as definitions grow from a small set to dozens. It describes reducing router boilerplate with annotations and build-time code generation, and simplifying order-sensitive routing by mapping top-level paths to deeplink definitions.

### Source excerpt

Deeplinking support in Android is relatively straightforward. You declare your deeplinks in the app's manifest, receive the incoming Intent passed in to your Activity and then navigate the user to the associated destination. This pipeline works just fine when you only need to support a handful of deeplinks. What happens though as the number of deeplinks grow? How do you deal with several dozen, or possibly even hundreds, of deeplinks? First Stab at Deeplinks When we first implemented deeplinking in our app, we only had to support 12 different deeplinks. We introduced a DeeplinkRouter class that would take the incoming Intent and determine where to navigate the user: interface Deeplink { fun route(uri: Uri): Boolean } class NotificationsDeeplink(val navigator: Navigator) : Deeplink { override fun route(uri: Uri): Boolean { return if (uri.path == "/notifications") { navigator.goToNotifications() true } else { false } } class ProfileDeeplink( val navigator: Navigator, val userRepository: UserRepository ) : Deeplink { override fun route(uri: Uri): Boolean { val profileId = uri.getQueryParameter("id") val isCurrentUser = userRepository.getCurrentUser().id == profileId return if (uri.path == "/profile" && profileId != null) { navigator.goToProfile(profileId, showColleagues = isCurrentUser) true } else { false } } } // ... more deeplink definitions ... class DeeplinkRouter( notificationsDeeplink: NotificationsDeeplink, profileDeeplink: ProfileDeeplink, // ... ) { private val deeplinks = listOf( notificationsDeeplink, profileDeeplink, // ... ) fun route(intent: Intent) { intent.data?.let { uri -> deeplinks.find { it.route(uri) } } } } Problems at Scale As the number of deeplinks and the complexity of their definitions grew, two big issues started to emerge. The first was managing the sheer number of deeplinks - we had nearly 50 at one point! Each of these had to be injected into DeeplinkRouter and then passed to its internal deeplinks list. We decided to resolve this by int

## Modularizing Rails Monoliths One Bite at a Time

DevFeed: [Modularizing Rails Monoliths One Bite at a Time](<https://devfeed.tech/articles/modularizing-rails-monoliths-one-bite-at-a-time-20038.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/modularizing-rails-monoliths-one-bite-at-a-time>)

Author: Doximity

Published: 2023-12-05T13:00:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Ruby on Rails](<https://devfeed.tech/topics/ruby-on-rails.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [modules](<https://devfeed.tech/topics/modules.md>), [Architecture & Design](<https://devfeed.tech/topics/architecture-design.md>), [Microservices](<https://devfeed.tech/topics/microservices.md>)

Tags: [microservices](<https://devfeed.tech/tags/microservices.md>), [modular-monolith](<https://devfeed.tech/tags/modular-monolith.md>), [modularization](<https://devfeed.tech/tags/modularization.md>), [modules](<https://devfeed.tech/tags/modules.md>), [rails](<https://devfeed.tech/tags/rails.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [ruby-on-rails](<https://devfeed.tech/tags/ruby-on-rails.md>)

### AI overview

The article describes using a phased refactoring approach and the packwerk gem to modularize growing Rails monoliths into modules with enforced boundaries. It presents the modular monolith as a lower-complexity alternative to adopting microservices and references Doximity's experience.

### Source excerpt

As Rails monoliths grow, coupling becomes increasingly difficult to manage. Developers often reach for microservices to help simplify things, but instead find higher complexity. The Modular Monolith approach is a proven, lightweight alternative that offers the benefits of enforced boundaries without being cumbersome. I spoke at the 2023 Rocky Mountain Ruby conference on how teams can use a phased approach to refactoring toward this style using the packwerk gem. At Doximity, we've used this gem and a phased approach to break some of our most critical rails applications into modules that are easier for our teams to work with. In November, 2023, I also chatted with Elise Shaffer on The Ruby on Rails Podcast about our experience with application modularization at Doximity. Be sure to follow @doximity_tech if you'd like to be notified about new blog posts.

## On the Road to Effective Data Analyses

DevFeed: [On the Road to Effective Data Analyses](<https://devfeed.tech/articles/on-the-road-to-effective-data-analyses-20039.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/on-the-road-to-effective-data-analyses>)

Author: Doximity

Published: 2023-09-07T16:45:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Data analysis](<https://devfeed.tech/topics/data-analysis.md>), [coding](<https://devfeed.tech/topics/coding.md>), [SQL](<https://devfeed.tech/topics/sql.md>), [Python](<https://devfeed.tech/topics/python.md>)

Tags: [analysis](<https://devfeed.tech/tags/analysis.md>), [data](<https://devfeed.tech/tags/data.md>), [data-analyst](<https://devfeed.tech/tags/data-analyst.md>), [python](<https://devfeed.tech/tags/python.md>), [readability](<https://devfeed.tech/tags/readability.md>), [review](<https://devfeed.tech/tags/review.md>), [sql](<https://devfeed.tech/tags/sql.md>)

### AI overview

This article presents practical guidance for making data analyses more compelling and useful. It recommends breaking broad product questions into specific data questions, collaborating early to identify potential data issues, and writing readable, reviewable code using SQL common table expressions and Python functions.

### Source excerpt

In the modern business landscape, the significance of data analysis cannot be overstated. It empowers organizations to uncover insights, make informed decisions, and gain a competitive edge by deciphering the hidden patterns within vast datasets. Data analysis is the cornerstone of strategic innovation and effective decision-making in today's dynamic markets. At Doximity, data is crucial to the success of business operations, playing a key role in every step of the product development cycle. From determining the potential of new features to testing and tracking their performance, data analysts and business intelligence analysts are critical to Doximity's success. Data analysts are equipped with powerful data analysis tools. While the variety of tools makes data analysis enjoyable, it still requires practice and self-reflection to create engaging analyses that cater to their audience. Here are a few tips for making analyses more compelling and useful. Ask the right questions from your data Every data analysis begins with an open-ended product question, which must be broken down into more specific questions related to the data. Taking the time to structure the analysis with well-defined questions can prevent analysts from getting lost in unnecessary details. Brainstorming early with colleagues and product managers can provide valuable insights and help identify and avoid potential data issues that could lead to flawed findings. As an example, consider the open-ended production question - "Why is the engagement with component x of our app increasing/decreasing in the last 2 months?" Upon brainstorming, this leads to questions "closer" to the data, such as: Is this a local high/low or an all-time high/low? In particular, have we seen seasonality with this metric in recent years? Is there a competing component of the app whose engagement has gone down/up in recent times that is correlated with this component's engagement going up/down? Write readable code Although coding

## Managing State in Vue Applications: The Composable Provider Pattern

DevFeed: [Managing State in Vue Applications: The Composable Provider Pattern](<https://devfeed.tech/articles/managing-state-in-vue-applications-the-composable-provider-pattern-20035.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/managing-state-in-vue-applications-the-composable-provider-pattern>)

Author: Doximity

Published: 2023-07-21T07:23:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Vue.js](<https://devfeed.tech/topics/vue.md>), [Front end](<https://devfeed.tech/topics/frontend.md>), [Scalability](<https://devfeed.tech/topics/scalability.md>), [Nuxt.js](<https://devfeed.tech/topics/nuxt.md>)

Tags: [code-modularity](<https://devfeed.tech/tags/code-modularity.md>), [components](<https://devfeed.tech/tags/components.md>), [maintainability](<https://devfeed.tech/tags/maintainability.md>), [modularity](<https://devfeed.tech/tags/modularity.md>), [reusable-code](<https://devfeed.tech/tags/reusable-code.md>), [reuse](<https://devfeed.tech/tags/reuse.md>), [scalability](<https://devfeed.tech/tags/scalability.md>), [state-management](<https://devfeed.tech/tags/state-management.md>), [vue](<https://devfeed.tech/tags/vue.md>)

### AI overview

This article explains the Composable Provider pattern for state management in Vue applications. The approach combines the Vue Composition API with the Provide/Inject APIs to manage complex, feature-driven state, with benefits including scalability, maintainability, reusability, and reduced code duplication.

### Source excerpt

State management is a fundamental concept of front-end application design, and a critical aspect in building robust Vue applications. As Vue applications grow in complexity, managing state becomes an increasingly challenging task, especially when working with a large organization of engineers spread across various product teams. Fortunately, the Vue and Nuxt ecosystem provides a variety of state management solutions, each with its own trade-offs. In this blog post we will explore the Composable Provider pattern, which handles state management by combining the Vue Composition and Provide/Inject APIs, and why its clean and simple implementation is a powerful approach to handling complex, feature-driven state in modern Vue applications. Note: This article was originally intended as a reference for our internal engineering team, but given its potential general use among Vue application developers we are publishing it here. We hope you'll find this pattern helpful when designing your Vue application's state as we have here at Doximity! Why Efficient State Management Matters Efficient state management plays a crucial role in the development of Vue applications. As applications grow in complexity, the ways in which we manage and handle changes to state become increasingly important. Here are a few key reasons why managing state efficiently matters: Scalability: As Vue applications and the teams building them grow in size, the complexity and size of their state grow also. Efficient state management allows for better scalability by providing a structured and organized approach to handling state. It becomes easier to add new features, maintain existing functionality, and reason about the flow of data within the application. Code Maintainability: Well-managed state reduces code complexity and promotes code maintainability. When state is not encapsulated properly, it becomes challenging to understand and modify the application's behavior. By implementing sound state management

## Building a Note-Taking App in Compose

DevFeed: [Building a Note-Taking App in Compose](<https://devfeed.tech/articles/building-a-note-taking-app-in-compose-20024.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/building-a-note-taking-app-in-compose>)

Author: Doximity

Published: 2023-07-05T19:47:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [App](<https://devfeed.tech/topics/app.md>), [Code](<https://devfeed.tech/topics/code.md>), [Template](<https://devfeed.tech/topics/template.md>)

Tags: [app](<https://devfeed.tech/tags/app.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [build](<https://devfeed.tech/tags/build.md>), [building](<https://devfeed.tech/tags/building.md>), [class](<https://devfeed.tech/tags/class.md>), [clean-architecture](<https://devfeed.tech/tags/clean-architecture.md>), [code](<https://devfeed.tech/tags/code.md>), [collect](<https://devfeed.tech/tags/collect.md>), [compose](<https://devfeed.tech/tags/compose.md>), [data-class](<https://devfeed.tech/tags/data-class.md>), [di](<https://devfeed.tech/tags/di.md>), [extension-function](<https://devfeed.tech/tags/extension-function.md>), [flow](<https://devfeed.tech/tags/flow.md>), [icons](<https://devfeed.tech/tags/icons.md>), [implement](<https://devfeed.tech/tags/implement.md>), [koin](<https://devfeed.tech/tags/koin.md>), [list](<https://devfeed.tech/tags/list.md>), [state](<https://devfeed.tech/tags/state.md>), [state-management](<https://devfeed.tech/tags/state-management.md>), [view](<https://devfeed.tech/tags/view.md>)

### AI overview

A case study showing how to build a note-taking app with Jetpack Compose. It models note state, renders the notes UI, collects note data through a presenter and Clean Architecture use cases, and plans events for adding, editing, checking, and deleting notes.

### Source excerpt

In this case study, we will build a note-taking app that lets the user add, edit and delete notes. It uses Compose for both the view and presentation layers! Note: This is a follow up to Part 1: Simplifying State Management with Compose and assumes the reader is already familiar with Jetpack Compose. The Template I find it useful to start with the model that represents the state of the screen we're building. It will have a list of notes, with each note containing properties for the text and checkbox: data class NotesUiModel(val notes: List<Note>) : UiModel { data class Note(val text: String, val isChecked: Boolean) : UiModel } It'll be the job of the presenter to produce this model. Initially, let's implement a stub to return an empty list of notes (we'll ignore parameters for now): class NotesListPresenter : Presenter<NotesUiModel, Unit> { @Composable override fun present(params: Unit): NotesUiModel { return NotesUiModel(notes = emptyList()) } } Then we can build our view to render the model that's returned by the presenter: @Composable fun NotesScreen() { val presenter: NotesListPresenter = koinInject() // we use koin for DI val uiModel = presenter.present(Unit) Column { TopAppBar(title = { Text("Notes") }) Notes(uiModel) } } } The View The views themselves are pretty self-explanatory if you're already familiar with building UIs in Compose. For the notes, we'll take in a NotesUiModel argument and create a LazyColumn with the notes property. A FAB button is used for adding new notes, although we'll skip the triggering of events and return to this part in a little bit: @Composable private fun Notes(uiModel: NotesUiModel) { Box { LazyColumn { items(uiModel.notes) { note -> Note(note) } } FloatingActionButton(onClick = { /* TODO */ }) { Icon(imageVector = Icons.Rounded.Add) } } } Then we can render each note with a checkbox, text field and delete button: @Composable private fun Note(uiModel: Note) { Row { Checkbox( checked = uiModel.isChecked, onCheckedChange = { /* T

## Simplifying State Management with Compose

DevFeed: [Simplifying State Management with Compose](<https://devfeed.tech/articles/simplifying-state-management-with-compose-20043.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/simplifying-state-management-with-compose>)

Author: Doximity

Published: 2023-07-05T19:45:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>), [Android](<https://devfeed.tech/topics/android.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Development](<https://devfeed.tech/topics/development.md>), [interoperability](<https://devfeed.tech/topics/interoperability.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [architecture](<https://devfeed.tech/tags/architecture.md>), [clean-architecture](<https://devfeed.tech/tags/clean-architecture.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-ui](<https://devfeed.tech/tags/compose-ui.md>), [interoperability](<https://devfeed.tech/tags/interoperability.md>), [state](<https://devfeed.tech/tags/state.md>), [state-management](<https://devfeed.tech/tags/state-management.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

This tutorial explains how Doximity's Android team experimented with using the Compose Runtime instead of ViewModels to manage screen state in the refreshed Amion physician scheduling tool. It describes the related presentation-layer and clean-architecture patterns, including interoperability with existing XML and Compose UI, and introduces foundations for a follow-up note-taking app.

### Source excerpt

The recent release of Doximity's refreshed physician scheduling tool Amion involved a significant overhaul of the user interface (UI) layer using Jetpack Compose. As part of the development process, we decided to experiment with shifting from ViewModels to utilizing the Compose Runtime for managing screen state. This article explores the motivations behind this approach and demonstrates an overall improvement to the view layer and presentation logic using the patterns developed in Amion 6.0.0. Note: This is part one of a two-part article. In part two, we will build a note-taking app using the foundations covered here. Understanding the Presentation Layer The Android team at Doximity builds apps following the basic principles of clean architecture, which involves separating the app into layers, each with their own responsibilities. In our app, we have a view layer, responsible for rendering UI components (Compose UI, XML views, etc.), and a presentation logic layer, responsible for producing screen state. Every navigable point in the app corresponds to one or more UI components and is associated with one or more screen state producers. Inspiration and Initial Experiments The decision to leverage Compose for managing state was inspired by (at the risk of sounding like r/mAndroidDev) Jake Wharton's article The State of Managing State (with Compose). While the release of Circuit occurred midway through our development, it was deemed more of a framework that required significant buy-in, whereas we aimed to build a flexible pattern with smoother interoperability with our existing architecture, that at the time mostly utilized ViewModel with XML and Compose UI. When we think about the presentation layer in Android as developers, we have to think about: What is the state of the screen? That is, not just when the user first sees it, but what does it look like when it's loading, what happens when there is an error, how will the state of components of the screen interact, and

## Introducing Simplekiq: A Lightweight Orchestration Framework for Ruby

DevFeed: [Introducing Simplekiq: A Lightweight Orchestration Framework for Ruby](<https://devfeed.tech/articles/introducing-simplekiq-a-lightweight-orchestration-framework-for-ruby-20033.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/introducing-simplekiq-a-lightweight-orchestration-framework-for-ruby>)

Author: Doximity

Published: 2023-05-03T11:28:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Orchestration](<https://devfeed.tech/topics/orchestration.md>), [Sidekiq](<https://devfeed.tech/topics/sidekiq.md>), [Ruby](<https://devfeed.tech/topics/ruby.md>), [Framework](<https://devfeed.tech/topics/framework.md>)

Tags: [declarative](<https://devfeed.tech/tags/declarative.md>), [orchestration](<https://devfeed.tech/tags/orchestration.md>), [parallel](<https://devfeed.tech/tags/parallel.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [sidekiq](<https://devfeed.tech/tags/sidekiq.md>), [workflow](<https://devfeed.tech/tags/workflow.md>)

### AI overview

The article introduces Simplekiq, a lightweight Ruby workflow framework built on Sidekiq Pro batching. It presents declarative, single-file orchestrations with serial and parallel execution as a way to make complex background-job workflows easier to understand, diagnose, and refactor.

### Source excerpt

Sidekiq is an amazing background job framework for Ruby with a long history of the best kind of minimalism - one of performance and succinctness. However, a downside of this is that long workflows built from dozens of background jobs queueing subsequent background jobs can be difficult to consistently design and maintain. We especially struggled with refactoring these types of structures since one has to read through all the code for the jobs to understand when and from where each job might get queued. The added complexity of manually defining Sidekiq Pro batches leads to difficult-to-diagnose triage in more creative workflows, especially when batch callbacks are involved. Introducing Simplekiq: A Solution to Our Challenges We solved our issue by building Simplekiq (special thanks to Daniel Pepper for freeing the rubygems simplekiq name for us) --a lightweight background job workflow framework built on top of Sidekiq Pro batching. Simplekiq solves the issue of having to follow long chains of jobs that queue other jobs ad nauseam. Workflows that span many files and job classes are inherently difficult to understand, diagnose and refactor. Simplekiq flattens out these complex, multi-file workflows into declarative, single-file ones which we call orchestrations. Each orchestration can contain a mix of serial and parallel execution so that even the most complex workflow can be expressed in an efficient, readable syntax. Comparing Sidekiq Pro and Simplekiq with an Example It's easier to demonstrate this with an example: making an apple pie. The late, great Carl Sagan taught us that to make an apple pie from scratch we must first invent the universe. That's a bit out of budget for most bakeries, but in the spirit of simplicity let's explore how a workflow for baking an apple pie from basic ingredients looks in standard Sidekiq Pro structures and compare it to the flattened Simplekiq paradigm. Our example will also show how refactoring differs between the two. Implementing

## Doximity Mobile Releases Streamlined with Automation

DevFeed: [Doximity Mobile Releases Streamlined with Automation](<https://devfeed.tech/articles/doximity-mobile-releases-streamlined-with-automation-20026.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/doximity-mobile-releases-streamlined-with-automation>)

Author: Doximity

Published: 2023-04-12T14:19:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Automation](<https://devfeed.tech/topics/automation.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [releases](<https://devfeed.tech/topics/releases.md>), [Deployment](<https://devfeed.tech/topics/deployment.md>)

Tags: [automation](<https://devfeed.tech/tags/automation.md>), [continuous-deployment](<https://devfeed.tech/tags/continuous-deployment.md>), [deployment](<https://devfeed.tech/tags/deployment.md>), [devops](<https://devfeed.tech/tags/devops.md>), [efficiency](<https://devfeed.tech/tags/efficiency.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [mobile-apps](<https://devfeed.tech/tags/mobile-apps.md>), [performance](<https://devfeed.tech/tags/performance.md>), [production](<https://devfeed.tech/tags/production.md>), [releases](<https://devfeed.tech/tags/releases.md>), [versioning](<https://devfeed.tech/tags/versioning.md>)

### AI overview

This article describes how Doximity's mobile team automated its release process to move from a three-week cycle to weekly releases. The team achieved the weekly cadence in November 2021, and weekly releases later required zero developer overhead while QA controlled the process.

### Source excerpt

Releasing mobile apps to the store is inherently slower than web updates due to manual process overhead, such as versioning, packaging, and submitting to the App Store for review. While web developers have long enjoyed full buzzword-compliant Continuous Deployment, mobile teams generally use a defined release cadence, typically 2-4 weeks. The DORA metric, which stands for DevOps Research and Assessment, evaluates performance using four key metrics: Deployment Frequency (DF), Lead Time for Changes (LT), Mean Time To Recover (MTTR), and Change Failure Rate (CFR). These metrics are commonly used to gauge an organization's agility, efficiency, and ability to implement changes quickly. Organizations that excel in these areas tend to perform smaller, more frequent deployments. A few years ago, our mobile team was classified as a medium performer for deployment frequency and reported 47% for change rate failure, which should be from 0% to 15%. We knew we could do better. Doximity mobile teams historically used a three-week release cycle. However, the pace wasn't fast enough to quickly get new features out the door. As a result, almost every release would be delayed due to some "very important thing" that had to get in. We also had to do more patch releases to fix issues introduced in production, which were even harder to debug with so many changes in a single version. One of the essential features that forced us to accelerate our release cycle was the Dialer Video product. We launched Dialer Video soon after the beginning of the pandemic. We wanted to get something out and to iterate quickly to meet the needs of our doctors while they were going through a difficult time and learning to work remotely. In April 2020, we attempted to shift to a weekly release cycle to meet this demand. While some automation was in place, there was also a lot of overhead with each release, and the developers spent a significant amount of time just managing the process. We compromised on a two-

## Accelerate iOS Development Using Deep Links

DevFeed: [Accelerate iOS Development Using Deep Links](<https://devfeed.tech/articles/accelerate-ios-development-using-deep-links-20022.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/accelerate-ios-development-using-deep-links>)

Author: Doximity

Published: 2023-03-13T09:18:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Development](<https://devfeed.tech/topics/development.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [simulator](<https://devfeed.tech/topics/simulator.md>), [App](<https://devfeed.tech/topics/app.md>)

Tags: [debug](<https://devfeed.tech/tags/debug.md>), [demo](<https://devfeed.tech/tags/demo.md>), [guide](<https://devfeed.tech/tags/guide.md>), [guides](<https://devfeed.tech/tags/guides.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [ios-development](<https://devfeed.tech/tags/ios-development.md>), [simulator](<https://devfeed.tech/tags/simulator.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This tutorial explains how to use Alfred workflows to organize deep links and launch them on running iOS simulators. It uses Apple Maps Guides as an example and shows how the workflow can document deep links, select one, and choose a simulator.

### Source excerpt

Do you work on a large app with lots of deep links and dynamic content? This article will show you how to manage and leverage those deep links so you can spend more time coding and less time navigating the app. Here on the News team at Doximity, we have lots of content to manage, including articles, comments, and collections of articles. The problem compounds when considering that articles have a lot of different variations, and some of those variations are uncommon. The variety can make it hard to test the entire app, and a real pain when trying to debug a problem on a specific piece of content. Fortunately, most of that content is accessible via a deep link with the correct IDs. Unfortunately, that often means keeping a list of links in a notes document or sending a link to yourself in Slack. It's even worse when using the simulator since you cannot access those tools easily. That's where Alfred comes in. Alfred is an application launcher and productivity application that includes a rich set of tools for creating custom workflows. An Alfred workflow can organize deep links and launch them on any running simulator. Let's use Apple Maps as an example, as it's available on all simulators and supports deep linking to Guides. (Provided by Apple, Guides are curated collections of related points of interest. They can be accessed with a deeplink in the format maps://?pg=<guide id>). Apple Maps has many Guides with different combinations of features to test. Finding a particular guide using the in-app search can take a lot of time. The Alfred workflow becomes both documentation of the various guides and a fast way to navigate to them. In the demo below, a hotkey triggers the workflow. Note that the workflow prompts to select a simulator when there are multiple running. The Alfred workflow consists of 4 work performing steps and some glue. The image below shows the Alfred workflow (which can be downloaded at the bottom of this article). The green steps cover selecting the d

## Finding Joy in Git Conflict Resolution

DevFeed: [Finding Joy in Git Conflict Resolution](<https://devfeed.tech/articles/finding-joy-in-git-conflict-resolution-20028.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/finding-joy-in-git-conflict-resolution>)

Author: Doximity

Published: 2023-01-31T16:50:00Z

Content type: tutorial

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Git](<https://devfeed.tech/topics/git.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [feature flags](<https://devfeed.tech/topics/feature-flags.md>)

Tags: [command-line](<https://devfeed.tech/tags/command-line.md>), [feature-flags](<https://devfeed.tech/tags/feature-flags.md>), [git](<https://devfeed.tech/tags/git.md>), [parallel](<https://devfeed.tech/tags/parallel.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>)

### AI overview

This article explains Git's diff3 conflict resolution strategy, which adds context about the common ancestor to conflict markers and helps developers understand the intent behind conflicting changes. It also notes that trunk-based development, feature flags, smaller incremental changes, and refactoring high-churn areas can reduce conflicts.

### Source excerpt

Your big feature is tested and ready to go! Time to merge, and then... Nooooo! 😭 Memories arise of hours of uncertainty spent trying to resolve past conflicts. Sure, there are lots of UIs that make picking one side or the other easier than using the command line, but is picking sides really the right answer? I'll share a hidden gem that, for me, has turned conflict resolution from frustration into something of a joy. Git has a built-in feature that you can enable called the diff3 conflict resolution strategy. Turning this setting on enables a predictable approach to understanding and resolving the conflicts you encounter. I'll note that git conflicts can be minimized through practices such as Trunk Based Development with Feature Flags, breaking features into smaller chunks that you can deliver incrementally, and refactoring hotspots with high churn. Fewer conflicts is always a win. Even still, we'll need to deal with conflicts occasionally whenever there are parallel development branches. Before going further, let's take a closer look at what's missing from the default conflict markers that Git has always provided (for backward compatibility with other tools). Example When Git is told to merge two branches of work that modify the same lines, Git won't try to determine how to apply both changes to the same line. Instead, it inserts a set of conflict markers and relies on your beautiful human brain to work it out. These conflict markers delineate the end result of the lines with conflicting changes in both the currently checked-out branch (HEAD) and the branch you've attempted to merge. (During a rebase, it checks out the commit you're rebasing onto, which gets labeled HEAD in the first section, and the commits you're rebasing show up in the second section as the change being "merged".) Take a look at this conflict. How would you resolve it? <<<<<<< HEAD GreenMessage.send(include_signature: true) ======= BlueMessage.send(include_signature: false) >>>>>>> merged-branch S

## Emojis: A Picture is Worth 1000 Words

DevFeed: [Emojis: A Picture is Worth 1000 Words](<https://devfeed.tech/articles/emojis-a-picture-is-worth-1000-words-20027.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/emojis-a-picture-is-worth-1000-words>)

Author: Doximity

Published: 2022-12-22T00:00:00Z

Content type: opinion

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Emoji](<https://devfeed.tech/topics/emoji.md>), [Slack](<https://devfeed.tech/topics/slack.md>)

Tags: [communication](<https://devfeed.tech/tags/communication.md>), [productivity](<https://devfeed.tech/tags/productivity.md>), [retention](<https://devfeed.tech/tags/retention.md>), [slack](<https://devfeed.tech/tags/slack.md>), [trust](<https://devfeed.tech/tags/trust.md>)

### AI overview

An opinion article discusses how emojis can improve workplace communication on Slack by conveying tone, empathy, priority, and emotional context that may be missing from digital messages. It also connects effective communication with employee engagement, retention, and trust.

### Source excerpt

If you would like an opportunity to join this emoji-filled, fun environment, you're in luck: we're hiring! 🙌 The benefits of effective communication extend beyond productivity, but also towards increasing employee engagement, retention and trust. In an age where we are more distributed than ever, methods of communication are evolving to ensure we continue to foster connectivity among team members. One such evolution in communication is the use of Emojis in the workplace. A recent survey of 9,400 hybrid workers around the world highlighted that 71% of American workers found emoji-less messages lacking. As a resident emoji "power user" myself, seeing this inspired me to do some reflection around how emojis enhance our culture of communication on Slack here at Doximity . 💡 Clarity Emojis don't take away from the need to clearly and concisely communicate a point. In fact, one might posit that their variety increases the need to be thoughtful and intentional in how we use them with coworkers of all backgrounds, locations and ages. However, they do help fill in the gaps in digital communication introduced by a lack of physical cues. A researcher of body language by the name of Albert Mehrabian first broke down the components of a face-to-face conversation and found that communication is 55% nonverbal, 38% vocal and 7% words only 1 . "I'll try to get to this project by the end of the week 😬" is very different from "I'll try to get to this project by the end of the week 😀". "I loved it 😊" conveys sincerity, while "I loved it 🙄" implies sarcasm. "That's interesting 🤔" illustrates reflection, whereas "That's interesting 🤨" insinuates confusion. Without any emojis, these statements are open to interpretation and, thus, misinterpretation. Additionally, emoji's can help attach a clearer sense of priority or categorization to messages. Sometimes a message is intended to be fyi and other times it may require immediate attention . In an otherwise seemingly endless stream of constan

## Ruby Delights Built Into The Language

DevFeed: [Ruby Delights Built Into The Language](<https://devfeed.tech/articles/ruby-delights-built-into-the-language-20041.md>)

Original publisher: [Read original article](<https://technology.doximity.com/articles/ruby-delights-built-into-the-language>)

Author: Doximity

Published: 2022-12-20T16:00:00Z

Content type: article

Language: en

Sources: [Doximity](<https://devfeed.tech/sources/doximity.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [Benchmark](<https://devfeed.tech/topics/benchmark.md>), [benchmarking](<https://devfeed.tech/topics/benchmarking.md>), [Code](<https://devfeed.tech/topics/code.md>), [Terminal](<https://devfeed.tech/topics/terminal.md>)

Tags: [benchmark](<https://devfeed.tech/tags/benchmark.md>), [benchmarking](<https://devfeed.tech/tags/benchmarking.md>), [code](<https://devfeed.tech/tags/code.md>), [console](<https://devfeed.tech/tags/console.md>), [performance](<https://devfeed.tech/tags/performance.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [terminal](<https://devfeed.tech/tags/terminal.md>)

### AI overview

This article explores Ruby features and examples built into the language and its standard library. It focuses on the Benchmark module, Ruby's IRB benchmarking extension, and other example programs such as a biorhythm calculator and networking utilities.

### Source excerpt

BTW, we're ⚡ hiring Infra, SRE, Web, Mobile, and Data engineers at Doximity (see roles) -- find out more about our technical stack. Ruby Delights Built Into The Language The hidden gems that make Ruby a delight are not always... gems. There are so many Ruby features built in to the language itself. In the very first episode of this series, we dove deep into the internals of one such gem bundled with Ruby's standard library: IRB. Keeping on theme, I'd like to take some time to explore some other areas of Ruby's source. So get ready to open up that IRB console you read all about, and we'll explore some incredible Ruby examples provided to you by Ruby itself. Jump To Your Favorites benchmark.rb - Measure performance of Ruby code biorhythm.rb - A biorhythm calculator cal.rb - A simple calendar display cbreak.rb - Supress echo of terminal input using ioctl cgi-session-pstore.rb - A file-based persistence mechanism for tracking the CGI Session as a Hash clnt.rb, svr.rb and tsvr.rb - Start a TCP socket server and connect a client coverage.rb - Simple test code coverage delegate.rb - Delegating methods with ease dir.rb - Directory access DRb - Distributed object system for Ruby (think RPC for OO) dualstack-fetch.rb and dualstack-httpd.rb - A simultaneous multi-threaded IPv4/IPv6 TCP server and client eval.rb - A simple evaluator export.rb - method access example exyacc.rb - Extract BNF from the yacc file fact.rb - A factorial calculator fib.rb - Fibonacci number calculations from.rb - Scan mail spool fullpath.rb - Convert ls -lR to fullpath format iseq_loader.rb - A sample of compiler/loader for binary compiled file less.rb - A front-end for the less command Benchmark source: benchmark.rb Benchmarking can be an incredibly valuable tool, but is quite the rabbit hole of theory vs. pragmatism. The "what", and "how", of benchmarking is fraught with sharp opinions and inconsistent recommendations. For now, we'll throw all that out the window and focus on Ruby's lovely example us

[Next page](<https://devfeed.tech/sources/doximity.md?cursor=WyIyMDIyLTEyLTIwVDE2OjAwOjAwKzAwOjAwIiwgImIyZjAyZTJhLTFiZTMtNDg2Yi04NzQ3LTYyODc0Y2QwNmJiMyJd>)