<?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: Tummala Krishna Kishore</title>
    <description>The latest articles on DEV Community by Tummala Krishna Kishore (@webruster).</description>
    <link>https://dev.to/webruster</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F223483%2F4d8818dc-ba2f-4e50-bc1d-a75b5d02da5b.png</url>
      <title>DEV Community: Tummala Krishna Kishore</title>
      <link>https://dev.to/webruster</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/webruster"/>
    <language>en</language>
    <item>
      <title>The one design-review question that would have caught our APIM naming collision</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Sun, 02 Aug 2026 04:49:12 +0000</pubDate>
      <link>https://dev.to/webruster/the-one-design-review-question-that-would-have-caught-our-apim-naming-collision-4eho</link>
      <guid>https://dev.to/webruster/the-one-design-review-question-that-would-have-caught-our-apim-naming-collision-4eho</guid>
      <description>&lt;p&gt;"Property with the same name already exist." That's the whole error. No stack trace worth reading, no line number, just APIM refusing a PUT and a pipeline stuck red at 2pm.&lt;/p&gt;

&lt;p&gt;The instinct was to blame the script. It's always the instinct. Somebody had touched the apiops publisher config two days earlier, so that got the first look, and it was clean. The real cause was quieter and, honestly, more interesting than a script bug: Azure API Management named values carry two separate identifiers, and almost nobody designs around the fact that only one of them is actually enforced.&lt;/p&gt;

&lt;p&gt;There's &lt;code&gt;id&lt;/code&gt;: whatever apiops derives from the artifact folder name during extraction. And there's &lt;code&gt;name&lt;/code&gt;, a display property living inside that resource, which APIM enforces must be unique across the &lt;em&gt;entire service&lt;/em&gt;, independent of &lt;code&gt;id&lt;/code&gt;. Two axes, one enforced, one not. Somewhere in one environment, a named value already existed with &lt;code&gt;name: key1&lt;/code&gt;. It had been created manually through the portal months earlier, sitting under a completely different &lt;code&gt;id&lt;/code&gt; than the one our publisher was trying to write. APIM saw the collision on &lt;code&gt;name&lt;/code&gt; and rejected the write. From the pipeline's point of view, this looked exactly like corruption. It wasn't corruption. It was two people, at two different times, both being reasonable, and the platform not telling either of them about the other.&lt;/p&gt;

&lt;p&gt;I've now seen this shape of bug in three different systems this year, and every time it traces back to the same design-review gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question nobody asks
&lt;/h2&gt;

&lt;p&gt;When a design doc introduces a resource, reviewers reach for the obvious questions. Does it scale? What's the failure mode? Who owns it in prod? Fine questions, all of them, and none of them would have caught this.&lt;/p&gt;

&lt;p&gt;The question that would have caught it is smaller and gets skipped almost every time: &lt;strong&gt;does this resource have more than one identifier, and if so, which one is actually unique, and at what scope?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most engineers assume "the ID is unique" and stop there. But plenty of platforms (APIM named values being one, but far from the only one) split identity into a system-assigned key and a human-facing name, and enforce uniqueness on the one you weren't watching. Git branch names inside a protected-branch rule. DNS record names inside a zone. Feature-flag keys versus their internal flag IDs. Environment variable names across shared app-service slots. Same pattern every time: one field is globally unique, the other is scoped or arbitrary, and the design doc almost never says which is which.&lt;/p&gt;

&lt;p&gt;That gap survives review because it doesn't fail during review. It fails three weeks later, in a different environment, when someone who's never read the design doc creates something through a portal instead of a pipeline. By then nobody's connecting the failure back to a design decision at all. It just looks like an ops incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually would have helped
&lt;/h2&gt;

&lt;p&gt;Not more process. A one-line addition to the design doc template: for every resource with a compound identity, state explicitly which field is unique, at what scope, and what happens on collision.&lt;/p&gt;

&lt;p&gt;That's it. It's a sentence, sometimes two. But writing that sentence forces the author to actually go check — which means they find out, before shipping, that &lt;code&gt;name&lt;/code&gt; is global and &lt;code&gt;id&lt;/code&gt; is local, instead of finding out from a failed pipeline run with a cryptic 409.&lt;/p&gt;

&lt;p&gt;I'd also push back on the instinct to "fix" this by locking down the portal so nobody can create named values manually again. We talked about it. It's the wrong fix. Manual creation isn't the bug. Undocumented shared-identity scope is. Lock the portal and you've removed one path to the collision while leaving the actual landmine in place for the next person who imports a named value some other way, or renames a folder that changes the derived &lt;code&gt;id&lt;/code&gt;. Governance theater instead of a fix.&lt;/p&gt;

&lt;p&gt;What we actually did: added an idempotency check to the publisher step. Look up by &lt;code&gt;name&lt;/code&gt; before attempting the PUT. If a named value with that name exists under a different &lt;code&gt;id&lt;/code&gt;, fail loudly with the actual conflicting &lt;code&gt;id&lt;/code&gt; in the error, not APIM's generic message. Twenty minutes of work. It would have turned a 45-minute production debugging session into a five-second, self-explanatory pipeline failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this belongs in a Node/Python conversation, not just an Azure one
&lt;/h2&gt;

&lt;p&gt;It's tempting to file this under "Azure quirks" and move on. Don't. The exact same failure mode shows up constantly in backend services outside Azure entirely. A Python service that treats a Stripe customer ID and an internal user ID as interchangeable until a webhook arrives out of order. A Node service that keys a cache on a slug that's supposed to be unique but is only enforced unique per-tenant, not globally, until two tenants pick the same slug and one silently overwrites the other's cache entry.&lt;/p&gt;

&lt;p&gt;Compound identity is one of the most common shapes a design doc's blind spot takes, across every stack I've worked in. It's not an Azure problem wearing an Azure name. It's a resource-modeling problem that happens to have surfaced there this time.&lt;/p&gt;

&lt;p&gt;If you review backend design docs, yours or someone else's, this is worth adding as a fixed line item, not something you trust yourself to remember to ask ad hoc under deadline pressure. "What's unique, and at what scope, for every identifier this resource exposes." One question. It would have saved us a debugging session, and it's cheap enough to ask on every doc, not just the ones that feel risky.&lt;/p&gt;

</description>
      <category>node</category>
      <category>python</category>
      <category>backend</category>
    </item>
    <item>
      <title>What a .NET Core service needs before it's actually production-ready</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Fri, 31 Jul 2026 04:17:34 +0000</pubDate>
      <link>https://dev.to/webruster/what-a-net-core-service-needs-before-its-actually-production-ready-42k0</link>
      <guid>https://dev.to/webruster/what-a-net-core-service-needs-before-its-actually-production-ready-42k0</guid>
      <description>&lt;p&gt;Health checks. Structured logging. Retry policies with jitter. Everyone who writes a "production readiness checklist" for a .NET Core service reaches for the same list, and none of it is wrong. But it's the wrong list to reach for first if your services live inside a shared domain model.&lt;/p&gt;

&lt;p&gt;I spent a chunk of this month wiring up something that's not on anyone's checklist: turning our domain projects into versioned NuGet packages, pushing them to a private Artifactory feed, and building a bot whose entire job is bumping the version number and rippling that bump out to every microservice repo that consumes it.&lt;/p&gt;

&lt;p&gt;It sounds like plumbing. It is plumbing. But it's the plumbing that decides whether "production-ready" means anything across a fleet of services instead of just one.&lt;/p&gt;

&lt;p&gt;Here's the problem it solves. Once you factor shared domain logic — entities, value objects, business rules that more than one service needs — out of a monolith and into a library, you've created a dependency graph you didn't have before. Every consuming service now has an opinion, implicit or not, about which version of that library it's running. Before we packaged it properly, that opinion was enforced by copy-paste and tribal memory. Nobody actually knew which service had which version of which rule.&lt;/p&gt;

&lt;p&gt;NuGet fixes the packaging half of that. Artifactory gives you a private feed so the package doesn't leak outside the org and you get an audit trail of who pulled what, when. Neither of those pieces is interesting on its own. The interesting part, and the part that actually determines whether this approach helps you or quietly wrecks you, is the bot.&lt;/p&gt;

&lt;p&gt;The bot watches the domain package repo. When a new version ships, it opens a PR against every downstream microservice repo, bumping the reference. That's the whole job. No cleverness, just a scripted dependency bump that used to be a manual chore somebody forgot to do half the time.&lt;/p&gt;

&lt;p&gt;And here's where I'll disagree with the take you see in half the "microservices done right" posts: automating that bump is good, but only if you admit you've just built an internal Dependabot, and internal Dependabot needs the same discipline the external kind does — discipline most teams skip because "it's our own code, we'll catch it."&lt;/p&gt;

&lt;p&gt;You won't catch it. Not reliably.&lt;/p&gt;

&lt;p&gt;If the bot opens the PR and someone rubber-stamps merges on domain package bumps the way they rubber-stamp a patch bump on a logging library, you are one mislabeled semver bump away from a breaking change landing in a dozen-plus services on the same afternoon. A shared domain library isn't a leaf dependency. It's load-bearing. A major-version bump there deserves the same scrutiny as a schema migration, because functionally that's what it is.&lt;/p&gt;

&lt;p&gt;So the real production-readiness question isn't "do we have a bot that bumps versions." It's "does every consuming service have a CI gate that runs its own integration suite against the new package version before that PR is mergeable — not after." We didn't have that gate on day one. We had the bot open the PR, a green build meaning "it compiles," and a merge button sitting right there. That's not readiness. That's speed dressed up as readiness.&lt;/p&gt;

&lt;p&gt;Getting the gate right meant slowing the bot down on purpose. It still opens the PR immediately, but it no longer auto-merges past a minor version bump until the consuming service's full integration suite passes against the new package — not just its unit tests, the whole suite, including the slow ones nobody likes running. That one change moved the failure mode from silent breakage in production to a red CI check somebody has to look at. Not exciting. Correct.&lt;/p&gt;

&lt;p&gt;There's a real trade-off here, and I won't pretend it away: this slows down how fast a domain fix reaches every service. In the old copy-paste world, a bug fix in a shared value object reached whichever service someone remembered to update, whenever they remembered — slow, but nobody's build broke overnight because of it. In the new world, the fix propagates fast to every service wired up to the bot, and any service where the fix collides with a local assumption finds out immediately, in CI, instead of three weeks later in an incident channel.&lt;/p&gt;

&lt;p&gt;I'd take the second failure mode every time. Fast and visible beats slow and invisible. But the cost is real, and pretending otherwise is how these systems lose the team's trust the first time a bump breaks a build at 5pm on a Friday.&lt;/p&gt;

&lt;p&gt;One more thing worth saying plainly: none of this replaces the usual checklist. A service still needs health checks, a sane retry policy, and logs that actually correlate across a request. What packaging and version-bump automation buys you is a production-readiness checklist that's true across the whole fleet, not just true for the one service you happened to test carefully. A service can pass every item on that list in isolation and still go down the moment a shared library changes underneath it in a way nobody flagged.&lt;/p&gt;

&lt;p&gt;If you're building shared .NET domain libraries and haven't worked out who reviews a major version bump, what test suite has to pass before that bump merges, and who's accountable when the bot's PR breaks something two services downstream, you don't have a production-ready fleet. You have a production-ready service, once, and a bot quietly deciding when that stops being true.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Subscription-per-environment was never the real question</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Wed, 29 Jul 2026 02:41:05 +0000</pubDate>
      <link>https://dev.to/webruster/subscription-per-environment-was-never-the-real-question-3che</link>
      <guid>https://dev.to/webruster/subscription-per-environment-was-never-the-real-question-3che</guid>
      <description>&lt;p&gt;Every landing zone conversation eventually lands on the same fork: subscription-per-team or subscription-per-environment. Pick one, defend it in the design review, move on. I used to think that fork was the decision. It isn't. It's a proxy for a question nobody actually asks, which is whether your environments are things you &lt;em&gt;have&lt;/em&gt; or things you &lt;em&gt;make&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We hit this a few weeks back building out a branching strategy for a product that needed to ship in phases — not one big release, several overlapping ones, each needing its own slice of infrastructure to validate against before merging up the chain. The instinct in every Azure reference architecture I'd read was to stand up a fixed set of subscriptions — dev, qa, uat, prod — and let teams queue for access to the shared ones. Clean org chart. Terrible fit for what we were actually doing, which was running three or four release branches at once, each wanting its own isolated environment for a week or two and then wanting to disappear.&lt;/p&gt;

&lt;p&gt;So, we didn't fix the environments. We templated them.&lt;/p&gt;

&lt;p&gt;The branching strategy and the environment strategy ended up being the same decision, which surprised me at the time. Every release branch got a corresponding environment spun up from Terraform, wired into the pipeline automatically the moment the branch existed, torn down automatically once it merged or went stale. No ticket. No "can I borrow QA for the afternoon." The subscription-per-environment debate assumes environments are scarce and long-lived enough to be worth governing carefully as static things. Once provisioning is cheap and repeatable, that assumption just stops holding.&lt;/p&gt;

&lt;p&gt;Here's the number that made the case for me, not some theoretical justification. Before this, we were running four non-prod subscriptions, always on, mostly idle outside business hours, because nobody wanted to be the one who tore down an environment someone might still need. After moving to on-demand provisioning tied to branch lifecycle, we typically had one to two environments alive at any given moment instead of four sitting there permanently. That's not a rounding error. That's roughly half the standing footprint gone, for infrastructure that was doing the same job.&lt;/p&gt;

&lt;p&gt;I won't pretend this is free. Ephemeral environments push a lot of discipline requirements onto your IaC that a static model lets you get lazy about. If your Terraform templates aren't actually idempotent — if there's some manual step, some hand-configured firewall rule, some secret someone pasted in once and forgot to script — dynamic provisioning will find that gap for you, repeatedly, at the worst time. We found ours in a Key Vault access policy that had been set by hand eight months earlier and never made it into the template. First time a fresh environment failed a smoke test, it took an afternoon to figure out why "prod-like" environment #3 didn't behave like the original.&lt;/p&gt;

&lt;p&gt;There's also a real counterpoint here, and it's not a strawman: audit and compliance people like fixed environments. A subscription that's existed for two years with a known history is easier to reason about for a SOC 2 review than one that spins up Tuesday and dies Friday. If your organization's compliance posture depends on long-lived resource identity — not just "the config was correct" but "this specific resource has been continuously monitored since provisioning" — ephemeral environments genuinely complicate your story. That's a real cost. I'm not going to hand-wave it away with better logging. You need to decide whether your compliance framework cares about resource continuity or just about proving the right controls were in place at time of use and design your audit trail around whichever one it actually is.&lt;/p&gt;

&lt;p&gt;For us, it wasn't. The controls mattered, the specific subscription's birthdate didn't. So, the trade-off was worth making.&lt;/p&gt;

&lt;p&gt;What I'd push back on is treating subscription-per-team vs subscription-per-environment as the primary architectural decision in the first place. It's a structural question about naming and boundaries. The actual lever — the one that changes your cost profile, your pipeline design, and how fast a team can validate a branch before it merges — is whether "environment" means a durable thing you provision once and then manage, or a disposable output of your pipeline that happens every time you need it. Landing zone docs spend pages on the former and barely mention the latter, probably because it's harder to draw on a slide. A static subscription topology is easy to diagram. "Environments are ephemeral outputs of the release pipeline" doesn't fit neatly into an org chart, so it gets left out of the reference architecture even when it's the more honest answer for a fast-phased release model.&lt;/p&gt;

&lt;p&gt;If you're mid-debate on subscription topology right now, my actual advice is to shelve that question for a week and instead ask whether your team could provision a working non-prod environment from scratch, unattended, in under half an hour. If the answer is no, fix that first — the subscription boundary question becomes almost irrelevant once you can. If the answer is yes, you've probably already made the topology decision without realizing it, because ephemeral environments don't care much which subscription boundary they sit inside. They just need somewhere to land and a template that doesn't lie about what production actually looks like.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cloud</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Cherry-picking your hotfix twice is the real pipeline smell</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Mon, 27 Jul 2026 03:20:58 +0000</pubDate>
      <link>https://dev.to/webruster/cherry-picking-your-hotfix-twice-is-the-real-pipeline-smell-1i6h</link>
      <guid>https://dev.to/webruster/cherry-picking-your-hotfix-twice-is-the-real-pipeline-smell-1i6h</guid>
      <description>&lt;p&gt;We had a gitflow pipeline that looked clean on paper: develop feeds a release branch, the same build artifact promotes through dev, qa, sit, uat, and prod, and once prod is green we tag the commit on main. Textbook. Then a production bug showed up on a Tuesday afternoon, and the diagram stopped mattering.&lt;/p&gt;

&lt;p&gt;The standard gitflow answer is to branch a hotfix off the tag, PR it back into release, run it through the pipeline, and once it's proven in UAT, merge to main and cherry-pick the same commit back into develop. We built exactly that. It works. Until you ask the question nobody wants to answer out loud: release still has whatever was mid-flight when you cut the last tag. Untested code. Feature work three sprints deep in QA, sitting on the same branch you're now supposed to route your hotfix through.&lt;/p&gt;

&lt;p&gt;So the real question we ended up arguing about wasn't "how do we release a hotfix." It was "do we trust the release branch enough to put a hotfix through it." Most of the time, the honest answer is no.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gate everyone obsesses over is the wrong one&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Five environments, five sign-offs, a change ticket for each one: that's the smell people point at first when a pipeline feels slow. It's real. It's just not the dangerous one. A slow gate costs you time. A gate you route around because you didn't trust your own process costs you an incident.&lt;/p&gt;

&lt;p&gt;Here's what we landed on after the argument: release the hotfix directly from the hotfix branch, not through release. On Azure, that means deploying to the UAT slot, smoke-testing against production data shape, then toggling the slot. Same infrastructure, same config, none of release's baggage riding along. Once it's live, cherry-pick the commit into both develop and main, retag, and let the normal pipeline catch up on its own schedule whenever it gets there.&lt;/p&gt;

&lt;p&gt;That's a smaller number of gates (one real test in the slot, one human sign-off) that actually mean something, instead of five theatrical ones inherited from a process built for planned releases, not for a Tuesday-afternoon incident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cherry-picking backward is the part that actually breaks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cherry-picking isn't free. It's a manual merge decision, done twice, under time pressure, by whoever's on call. Miss a file, resolve a conflict wrong, and you've silently reintroduced the bug three weeks later when release finally catches up to main. We've had this happen. Not often. Twice in about eighteen months. Both times the root cause was identical: the hotfix touched a file that had also changed on develop, and the person doing the cherry-pick trusted the diff instead of running the test suite against the merged result.&lt;/p&gt;

&lt;p&gt;The fix wasn't "be more careful." Telling people to be careful under incident pressure doesn't work. The fix was making the cherry-pick a PR like any other, gated by the same CI as a normal merge, instead of a git command someone runs from their laptop at 6pm. One automated check catches what a tired engineer won't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trade-off nobody states plainly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploying straight from a hotfix branch means shipping less-tested code than your normal pipeline would allow. That's the actual cost, and it's worth saying plainly instead of dressing it up. If your org's risk appetite says every production deploy needs the full five-stage gauntlet, this approach is wrong for you. Don't adopt it because it sounds efficient. Adopt it because you've decided the trade-off is acceptable for a defined, narrow class of change.&lt;/p&gt;

&lt;p&gt;But when the choice is "wait six hours for a full pipeline run while the bug keeps costing money" versus "deploy a scoped, reviewed, slot-tested fix in twenty minutes," speed usually wins the math. We're not skipping testing. We're skipping the parts of testing that exist to catch problems unrelated to the fix: the ones baked into whatever else happens to be sitting on release that particular week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I'd tell a team setting this up today&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't design your hotfix path as a stripped-down version of your normal release path. Design it as its own thing: its own artifact, its own single meaningful gate, its own explicit rule for re-entering the trunk.&lt;/p&gt;

&lt;p&gt;Ours is three rules. Hotfix branches from the last production tag, never from release. It deploys through slot swap, never through the shared release pipeline. It re-enters develop and main through a real PR with CI attached, not a raw cherry-pick run from someone's terminal.&lt;/p&gt;

&lt;p&gt;Three rules. They fit on a sticky note. The gitflow diagram we started with had no room for any of them, because it assumed every deploy was a planned one, and incidents don't wait for the plan to catch up.&lt;/p&gt;

&lt;p&gt;If your next incident retro says "we need more approval gates," check first whether the actual failure was a rushed cherry-pick nobody tested. In our case, it always was — and no amount of extra sign-off in the normal pipeline would have caught it, because the bug never went through the normal pipeline at all.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>What actually belongs in an architecture decision record (and what doesn't)</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Sat, 25 Jul 2026 06:35:30 +0000</pubDate>
      <link>https://dev.to/webruster/what-actually-belongs-in-an-architecture-decision-record-and-what-doesnt-1ke6</link>
      <guid>https://dev.to/webruster/what-actually-belongs-in-an-architecture-decision-record-and-what-doesnt-1ke6</guid>
      <description>&lt;p&gt;Most architecture decision records fail for the opposite reason people think. The issue usually isn't that teams forget to write them. It's that the ones they write are filled with the wrong content. The key information a reader needs—why this option instead of the others—often gets buried on page three under a list of API changes.&lt;/p&gt;

&lt;p&gt;An ADR has one job: capture a decision that is costly to reverse, along with the reasoning that led to it, while that reasoning is still fresh. That's all. It isn't a design document, a specification, or a collection of research. If you keep that focus, everything else about what to include or leave out will follow naturally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The format that still works&lt;/strong&gt;&lt;br&gt;
Michael Nygard's original ADR template from 2011 (title, status, context, decision, consequences) has lasted for a reason. It directly addresses the key questions a future reader has: What was the situation? What did we decide? What did we give up? Teams that add ten extra sections, like owners, review dates, risk matrices, or approval lists, usually end up with a document no one finishes reading, which defeats the purpose. If your ADR template is longer than the time it takes to fill it out for a simple decision, cut sections until it’s more concise.&lt;/p&gt;

&lt;p&gt;A useful rule of thumb is that an ADR longer than a page and a half is often a design document masquerading as an ADR. This isn’t a strict rule, but I haven’t seen a truly good ADR exceed 600 words. The decisions worth documenting this way can be stated, justified, and owned in about a page. If that's not possible, the record isn’t the issue. The decision is probably still tied up with other unresolved matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What belongs&lt;/strong&gt;&lt;br&gt;
The decision, stated clearly. "We will use event-driven integration between the order and inventory services instead of synchronous REST calls" is a decision. "The order service integrates with inventory" simply describes the current state and belongs in a wiki, not an ADR.&lt;/p&gt;

&lt;p&gt;The challenges faced. Describe the two or three actual constraints that were in conflict, not a comprehensive literature review. For example, a latency budget versus consistency guarantees, team ownership boundaries versus a shared database that made those ownership lines unclear, or cost limits versus the vendor lock-in that comes with a cheaper option. If there was no real conflict, you probably didn't need an ADR.&lt;/p&gt;

&lt;p&gt;The alternatives you seriously considered, along with why they weren’t chosen. Focus on the options a competent engineer would likely ask about six months later. For example, "We looked at a shared database with row-level locking; we rejected it because it recreated the coupling we wanted to eliminate between the two teams' deployment cycles." This simple statement saves the next person from rehashing a decision that's already been made.&lt;/p&gt;

&lt;p&gt;The consequences, including the ones you’re not thrilled about. This is often the section teams skip, but it offers the highest value. Every genuine architectural decision comes with costs. If you adopt event-driven integration, you trade the simplicity of synchronous actions for eventual consistency and a tougher debugging process when a message is lost. Document that. An ADR that lists only the benefits isn't a valid record of a decision. It's a sales pitch to your future self, and future-you won’t be fooled more than once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What doesn’t belong&lt;/strong&gt;&lt;br&gt;
Implementation details. Class names, endpoint paths, table schemas, retry counts—these change frequently and can quickly make the document outdated. If the ADR needs a code example to clarify its point, it likely indicates that the decision being documented is more about implementation than architecture, and it should belong in the code or design document instead.&lt;/p&gt;

&lt;p&gt;Decisions that are not settled yet. If three options are still in play and no one has chosen one, that's a design document or a spike ticket. Writing an ADR for a decision still in progress creates a record that contradicts itself by the time it gets approved. Contradictory records are worse than having no records; they mislead the following reader.&lt;/p&gt;

&lt;p&gt;A decision made after the fact to meet process requirements. This rubber-stamp scenario is more common than teams want to admit. Someone builds the solution and then creates the ADR retroactively because it's required by the checklist. The "alternatives considered" section becomes fictional, as nothing was actually considered. The option that got released is the only one that ever existed on paper. Readers can tell the difference. An ADR written after the code is merged feels different from one written beforehand. Once a team’s ADRs acquire a reputation for being just for show, people stop reading them, which is worse than never having them required.&lt;/p&gt;

&lt;p&gt;Every decision, regardless of its importance. This is the trade-off people often avoid stating clearly: requiring an ADR for every non-trivial pull request leads to a pile of records. For example, both the choice to follow field-naming conventions and the decision to go fully async receive the same template and attention. The signal-to-noise ratio diminishes, and the truly important records—those concerning team boundaries, data ownership, or long-term platform choices—get lost among many similar entries about logging formats. Save ADRs for decisions that are genuinely challenging to reverse: those that affect team boundaries, data ownership, or a platform choice you'll live with for years. Smaller considerations can go in a pull request description or a design note.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The crucial test&lt;/strong&gt;&lt;br&gt;
Before you write the next one, ask yourself: if this decision turns out to be wrong in eighteen months, would the person troubleshooting it appreciate this document? If the answer is that they would skim through the generic content looking for the paragraph explaining why the obvious choice wasn’t made, write that paragraph first and build the rest of the record around it. Everything else, like the status field, review date, and approval chain, is optional. The reasoning is the key part; treat it that way, and the format will fall into place.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>softwaredesign</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Open In-line video in fullscreen</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Tue, 01 Feb 2022 05:55:24 +0000</pubDate>
      <link>https://dev.to/webruster/open-in-line-video-in-fullscreen-28ge</link>
      <guid>https://dev.to/webruster/open-in-line-video-in-fullscreen-28ge</guid>
      <description>&lt;p&gt;Its been a long time i have written my posts, so got some free time to publish some articles which are usefull for the people who are implementing In-line video and make it fullscreen in Ionic.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Config.xml&lt;/strong&gt; we need to Add this Block of code to Make it full screen&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;preference name="AllowInlineMediaPlayback" value="true" /&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which Triggers the Native app to play in Inline. while coming to the HTML5 there is a intresting fact that was stated in &lt;a href="https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html" rel="noopener noreferrer"&gt;Apple Developer Site&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;on iPhone and iPod touch, which are small screen devices, Video is NOT presented within the Web Page&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ionic</category>
      <category>angular</category>
      <category>iphone</category>
    </item>
    <item>
      <title>Publish from Visual Studio and automatically encrypt appSettings using aspnet_regiis</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Tue, 17 Aug 2021 06:04:18 +0000</pubDate>
      <link>https://dev.to/webruster/publish-from-visual-studio-and-automatically-encrypt-appsettings-using-aspnetregiis-1m1e</link>
      <guid>https://dev.to/webruster/publish-from-visual-studio-and-automatically-encrypt-appsettings-using-aspnetregiis-1m1e</guid>
      <description>&lt;p&gt;After going through your all edits and a bit of research from me , you want to execute the following command after the publish from the Visual Studio&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pe "appSettings" -site Default -app "/" &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If I understood right , You can try wrapping the&amp;nbsp;&lt;em&gt;ItemGroup&lt;/em&gt;&amp;nbsp;in a Target with&amp;nbsp;&lt;em&gt;AfterTargets&lt;/em&gt;&amp;nbsp;set to&amp;nbsp;&lt;strong&gt;AddIisSettingAndFileContentsToSourceManifest&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Target Name="executeinHosts" AfterTargets="AddIisSettingAndFileContentsToSourceManifest"&amp;gt;
    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;MsDeploySourceManifest Include="runCommand"&amp;gt;
       //here would be your path that need to run after the publish
      &amp;lt;/MsDeploySourceManifest&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
  &amp;lt;/Target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in Your case this is how that part should look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Target Name="executeinHosts" AfterTargets="AddIisSettingAndFileContentsToSourceManifest"&amp;gt;
    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;MsDeploySourceManifest Include="runCommand"&amp;gt;
         &amp;lt;path&amp;gt;C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pe "appSettings" -site $(DeployIisAppPath) -app "/"&amp;lt;/path&amp;gt;
      &amp;lt;/MsDeploySourceManifest&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
  &amp;lt;/Target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Additional Info:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AddIisSettingAndFileContentsToSourceManifest&lt;/strong&gt;&amp;nbsp;target works just right before Web Deploy copying files from local to server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aspnet_regiis&lt;/strong&gt; can be run in&amp;nbsp;&amp;nbsp;node by&amp;nbsp;&lt;em&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Exec Command="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -pef connectionStrings $(ProjectDir)obj\Debug\Package\PackageTmp" WorkingDirectory="$(publishUrl)" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dotnet</category>
      <category>iis</category>
    </item>
    <item>
      <title>Display datetime correctly in iOS/Safari using ionic2/angular2</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Tue, 06 Jul 2021 07:58:39 +0000</pubDate>
      <link>https://dev.to/webruster/display-datetime-correctly-in-ios-safari-using-ionic2-angular2-lof</link>
      <guid>https://dev.to/webruster/display-datetime-correctly-in-ios-safari-using-ionic2-angular2-lof</guid>
      <description>&lt;p&gt;The issue is caused by the Intlapi because DatePipe for Angular 2. Release is working fine only for FireFox and Chrome with custom format strings. it Doesn’t work on Safari due to lack of Intl. so as a temporary work around is to include the Intl polyfill&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Solution 2 You can use the moment.js which can format your required date as follows&lt;/p&gt;

&lt;p&gt;&lt;code&gt;moment(singleTable[0].FromCurrentDate).format("dd/MM/yyyy,h:mm:ss a")&lt;/code&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>ionic</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Pass multiple Eval field in one command argument in Repeater Control</title>
      <dc:creator>Tummala Krishna Kishore</dc:creator>
      <pubDate>Thu, 01 Jul 2021 10:11:47 +0000</pubDate>
      <link>https://dev.to/webruster/pass-multiple-eval-field-in-one-command-argument-in-repeater-control-10m7</link>
      <guid>https://dev.to/webruster/pass-multiple-eval-field-in-one-command-argument-in-repeater-control-10m7</guid>
      <description>&lt;p&gt;This is the most common problem that generally users face while dealing with Repeater control. I gave this solution in Stackoverflow. want to post it here for users coming from search&lt;/p&gt;

&lt;p&gt;Add the below snippet in in template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CommandArgument='&amp;lt;%#Eval("ScrapId")+","+ Eval("UserId")%&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In code behind you can use retrieve values like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected void GridViews_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "Comment")
    {
        string[] commandArgs = e.CommandArgument.ToString().Split(new char[] { ',' });
        string scrapid = commandArgs[0];
        string uid = commandArgs[1];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>nuggets</category>
    </item>
  </channel>
</rss>
