-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
294 lines (287 loc) · 18 KB
/
Copy pathindex.html
File metadata and controls
294 lines (287 loc) · 18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#0e151f" media="(prefers-color-scheme: dark)">
<title>Ivan Ball-llovera · Senior Software Architect</title>
<meta name="description" content="Ivan Ball-llovera is a Senior Software Architect with 25+ years building cloud-native systems on the Microsoft stack: .NET, Azure, Domain-Driven Design, Clean Architecture, CQRS, and microservices.">
<link rel="canonical" href="https://ivanball.github.io/">
<!-- Search-engine verification. A crawler will not accept a token injected by JavaScript, so this
has to sit in the served HTML. Do not remove it: verification is re-checked periodically, not
just once. Property: URL-prefix https://ivanball.github.io/ in Google Search Console.
Bing needs no tag of its own: import the verified property from Search Console at
https://www.bing.com/webmasters instead. -->
<meta name="google-site-verification" content="7g3J_vtFMyqN3OHbL5yOAX7IEojC8X4JIUCDYEEt5GU">
<link rel="icon" href="assets/img/favicon.svg" type="image/svg+xml">
<link rel="alternate" type="application/rss+xml" title="Ivan Ball-llovera: deep dives on enterprise .NET" href="https://ivanball.github.io/feed.xml">
<meta property="og:type" content="website">
<meta property="og:site_name" content="Ivan Ball-llovera">
<meta property="og:title" content="Ivan Ball-llovera · Senior Software Architect">
<meta property="og:description" content="25+ years building cloud-native systems on the Microsoft stack: .NET, Azure, DDD, Clean Architecture, CQRS, and microservices.">
<meta property="og:url" content="https://ivanball.github.io/">
<meta property="og:image" content="https://ivanball.github.io/assets/img/og-image.png">
<meta property="og:image:alt" content="Ivan Ball-llovera, Senior Software Architect">
<meta property="og:locale" content="en_US">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Ivan Ball-llovera · Senior Software Architect">
<meta name="twitter:description" content="25+ years building cloud-native systems on the Microsoft stack: .NET, Azure, DDD, Clean Architecture, CQRS, and microservices.">
<meta name="twitter:image" content="https://ivanball.github.io/assets/img/og-image.png">
<!-- BEGIN head-assets -->
<script>(function(){try{var t=localStorage.getItem('mmca-theme');if(t==='light'||t==='dark')document.documentElement.setAttribute('data-theme',t);}catch(e){}})();</script>
<link rel="preload" href="assets/fonts/inter-latin-wght-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="assets/fonts/jetbrains-mono-latin-400-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="assets/css/styles.css">
<script defer src="assets/js/main.js"></script>
<script defer src="assets/js/search.js"></script>
<script defer src="assets/js/analytics.js"></script>
<!-- END head-assets -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Ivan Ball-llovera",
"jobTitle": "Senior Software Architect",
"url": "https://ivanball.github.io/",
"image": "https://ivanball.github.io/assets/img/ivan-ball-llovera.jpg",
"sameAs": [
"https://github.com/ivanball",
"https://www.linkedin.com/in/ivan-ball-llovera-6549a911"
],
"address": { "@type": "PostalAddress", "addressLocality": "Douglasville", "addressRegion": "GA", "addressCountry": "US" },
"knowsAbout": [".NET", "C#", "Azure", "Domain-Driven Design", "Clean Architecture", "CQRS", "Microservices", "Blazor", ".NET Aspire", "Event-Driven Architecture"],
"alumniOf": { "@type": "CollegeOrUniversity", "name": "University of Havana" }
}
</script>
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- BEGIN site-header -->
<header class="site-header">
<div class="container nav">
<a class="brand" href="index.html">
<span class="brand-mark" aria-hidden="true">IB</span>
<span>Ivan Ball-llovera</span>
</a>
<nav aria-label="Primary">
<ul class="nav-links" id="nav-links">
<li><a href="index.html" aria-current="page">Home</a></li>
<li><a href="resume.html">Résumé</a></li>
<li><a href="platform.html">Platform</a></li>
<li><a href="docs/index.html">Reference</a></li>
<li><a href="writing.html">Writing</a></li>
<li><a href="speaking.html">Speaking</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
</nav>
<div class="nav-tools">
<button class="icon-btn search-open" type="button" aria-label="Search the site" data-search-open>
<span aria-hidden="true">⌕</span>
</button>
<button class="icon-btn theme-toggle" type="button" aria-label="Switch color theme">
<span class="sun" aria-hidden="true">☀</span><span class="moon" aria-hidden="true">☾</span>
</button>
<button class="icon-btn nav-toggle" type="button" aria-label="Toggle navigation menu" aria-expanded="false" aria-controls="nav-links">☰</button>
</div>
</div>
</header>
<dialog class="search-dialog" id="site-search" aria-label="Search this site">
<form class="search-box" method="dialog" role="search">
<span class="search-icon" aria-hidden="true">⌕</span>
<input class="search-input" type="search" id="site-search-input" placeholder="Search ADRs, guides, chapters, articles…"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
aria-controls="site-search-results" aria-describedby="site-search-status">
<button class="btn btn--ghost search-close" type="button" data-search-close>Esc</button>
</form>
<p class="search-status" id="site-search-status" role="status" aria-live="polite"></p>
<ul class="search-results" id="site-search-results"></ul>
<p class="search-foot">
<span><kbd>↑</kbd><kbd>↓</kbd> to navigate</span>
<span><kbd>Enter</kbd> to open</span>
<span><kbd>"…"</kbd> exact phrase</span>
<span><kbd>AND</kbd><kbd>OR</kbd> to combine</span>
</p>
</dialog>
<!-- END site-header -->
<main id="main">
<!-- Hero. The ink band is the site's signature surface: it carries the portrait,
the positioning line, and the four headline figures as one object. -->
<section class="hero ink">
<div class="container">
<div class="hero-grid">
<div>
<p class="eyebrow">Senior Software Architect</p>
<h1>Ivan Ball-llovera</h1>
<p class="role">Cloud-native enterprise architecture on the Microsoft stack</p>
<p class="lede">I design and ship production-grade .NET platforms: modular monoliths that extract cleanly into microservices, event-driven messaging, and Azure-native delivery, with architecture discipline enforced at build time, not in a wiki.</p>
<div class="btn-row">
<a class="btn btn--primary" href="platform.html">Explore the platform</a>
<a class="btn btn--ghost" href="resume.html">View résumé</a>
<a class="btn btn--ghost" href="contact.html">Get in touch</a>
</div>
</div>
<!-- alt is empty on purpose: the h1 immediately beside it already gives the
name, so describing the portrait too would just repeat it to a screen
reader. Eager and fetchpriority high because it is above the fold. -->
<img class="avatar" src="assets/img/ivan-ball-llovera.webp" alt="" width="200" height="200" fetchpriority="high">
</div>
<div class="stats">
<!-- BEGIN home-stats -->
<div class="stat"><div class="num">25+</div><div class="label">Years on the Microsoft stack</div></div>
<div class="stat"><div class="num">15</div><div class="label">Open-source NuGet packages</div></div>
<div class="stat"><div class="num">64</div><div class="label">Architecture Decision Records</div></div>
<div class="stat"><div class="num">2</div><div class="label">Atlanta tech conferences organized</div></div>
<!-- END home-stats -->
</div>
</div>
</section>
<!-- About -->
<section class="section section--alt">
<div class="container split">
<div class="split-head">
<div class="section-head">
<p class="eyebrow">About</p>
<h2>Architecture that earns its keep</h2>
</div>
</div>
<div class="prose">
<p>I am a Senior Software Architect with more than 25 years designing and delivering scalable, cloud-native systems on the Microsoft stack. My focus is Domain-Driven Design, Clean Architecture, CQRS, and microservices, paired with hands-on Azure cloud architecture and DevOps (Bicep, Docker, Kubernetes, CI/CD).</p>
<p class="mb-0">I have a proven record of leading architectural refactors, modernizing legacy platforms, and mentoring cross-functional teams to raise engineering standards. Right now I am architecting production-grade .NET 10 platforms that span the modular-monolith-to-microservices path, event-driven messaging, and AI/RAG integration, while using AI-assisted development workflows to ship faster without trading away quality.</p>
</div>
<div class="split-full grid grid--3" style="margin-top:1rem" data-reveal>
<div class="card">
<h3>Architecture & design</h3>
<p class="mb-0">DDD, Clean Architecture, CQRS, modular monolith to microservices, event-driven and the outbox pattern, gRPC, and API gateways (YARP).</p>
</div>
<div class="card">
<h3>Cloud & DevOps</h3>
<p class="mb-0">Azure Container Apps, Service Bus, Cosmos DB, SQL, and App Insights, with Bicep IaC, containers, Kubernetes, and OIDC / managed identity.</p>
</div>
<div class="card">
<h3>Quality & delivery</h3>
<p class="mb-0">xUnit, Playwright, TDD, accessibility (axe, WCAG 2.1 AA), architecture fitness functions, and AI-assisted development with Claude Code and Copilot.</p>
</div>
</div>
</div>
</section>
<!-- Featured platform -->
<section class="section">
<div class="container">
<div class="feature ink" data-reveal>
<div class="feature-grid">
<div>
<p class="eyebrow">Featured work</p>
<h2>The MMCA platform</h2>
<p>A production-grade .NET 10 framework and a set of reference apps that demonstrate modern enterprise architecture end to end. It is built as a modular monolith that extracts cleanly into independent microservices: modules load in topological order and run behind a YARP gateway with gRPC contracts and typed clients, keeping transport reversible at the edge. The conference application was deployed to Azure and powered the live 2026 Atlanta Cloud + AI Conference, and will also power the 2026 Atlanta Developers Conference.</p>
<div class="btn-row">
<a class="btn btn--primary" href="platform.html">See the architecture</a>
<a class="btn btn--ghost" href="https://github.com/ivanball/MMCA.Common" target="_blank" rel="noopener">View on GitHub ↗</a>
</div>
</div>
<ul class="lead-list">
<li><span class="check" aria-hidden="true">▸</span><span><strong>Modular monolith, extractable.</strong> Modules are discovered and loaded in topological order, then run as their own service with no domain rewrite.</span></li>
<li><span class="check" aria-hidden="true">▸</span><span><strong>Database-per-service with an outbox.</strong> Events persist atomically with the data and deliver at least once, in process or over a broker.</span></li>
<li><span class="check" aria-hidden="true">▸</span><span><strong>Rules that fail the build.</strong> A compile-time layer guard plus a shared NetArchTest library run as fitness functions in every repo.</span></li>
<li><span class="check" aria-hidden="true">▸</span><span><strong>Graded in the open.</strong> Every repo is scored against a 34-category rubric, with the evidence and the gaps published.</span></li>
</ul>
</div>
</div>
</div>
</section>
<!-- Featured writing. The three cards are GENERATED from assets/data/articles.js:
the newest published pieces, with the same hero art as the Writing page. -->
<section class="section section--alt">
<div class="container">
<div class="section-head">
<p class="eyebrow">Writing</p>
<h2>Deep dives on enterprise .NET</h2>
<p>A long-form series turning the framework's decisions into teachable patterns, every claim grounded in real source. The three most recent:</p>
</div>
<div class="grid grid--3" data-reveal>
<!-- BEGIN featured-articles -->
<a class="card card--link article-card" href="https://medium.com/@ivanball76/google-and-github-login-without-leaking-tokens-external-oauth-behind-your-own-jwts-d68ba5e3aca4" target="_blank" rel="noopener">
<div class="thumb"><img src="assets/img/articles/article-26.webp" alt="" width="800" height="420" loading="lazy" decoding="async"></div>
<div class="body">
<span class="kicker">Auth & the edge · No. 26</span>
<h3>External OAuth login behind your own JWTs</h3>
<p>Sign in with Google or GitHub without leaking provider tokens: external identity exchanged for your own JWTs at the boundary.</p>
<div class="card-foot"><span class="go">Read on Medium ↗</span></div>
</div>
</a>
<a class="card card--link article-card" href="https://medium.com/@ivanball76/browser-session-cookie-auth-for-blazor-ssr-surviving-the-f5-eb0ea317820e" target="_blank" rel="noopener">
<div class="thumb"><img src="assets/img/articles/article-25.webp" alt="" width="800" height="420" loading="lazy" decoding="async"></div>
<div class="body">
<span class="kicker">Auth & the edge · No. 25</span>
<h3>Browser session-cookie auth for Blazor SSR</h3>
<p>HttpOnly session cookies and an SSR-time scheme so [Authorize] passes during prerender, with the API still the boundary.</p>
<div class="card-foot"><span class="go">Read on Medium ↗</span></div>
</div>
</a>
<a class="card card--link article-card" href="https://medium.com/@ivanball76/permission-based-authorization-capabilities-over-role-checks-ea6574cbee27" target="_blank" rel="noopener">
<div class="thumb"><img src="assets/img/articles/article-24.webp" alt="" width="800" height="420" loading="lazy" decoding="async"></div>
<div class="body">
<span class="kicker">Auth & the edge · No. 24</span>
<h3>Permission-based authorization over roles</h3>
<p>A capability layer over RBAC: permission policies that resolve on demand from a central registry.</p>
<div class="card-foot"><span class="go">Read on Medium ↗</span></div>
</div>
</a>
<!-- END featured-articles -->
</div>
<div class="btn-row btn-row--spaced">
<a class="btn btn--ghost" href="writing.html">Browse all articles</a>
<a class="btn btn--ghost" href="feed.xml">Subscribe by RSS</a>
</div>
</div>
</section>
<!-- Speaking / community -->
<section class="section">
<div class="container split">
<div class="split-head">
<div class="section-head">
<p class="eyebrow">Community</p>
<h2>Speaking & giving back</h2>
<p>I help run two community-driven Atlanta technology conferences and keep production-grade patterns free and in the open.</p>
</div>
<div class="btn-row">
<a class="btn btn--ghost" href="speaking.html">See talks & community work</a>
</div>
</div>
<div class="grid" data-reveal>
<div class="card">
<span class="kicker kicker--accent">Organizer & speaker</span>
<h3>Two Atlanta conferences</h3>
<p class="mb-0">Lead organizer of the Atlanta Cloud + AI Conference (324 attendees, 53 speakers, 50 sessions in 2026) and the Atlanta Developers Conference, where I also speak on Clean Architecture and DDD.</p>
</div>
<div class="card">
<span class="kicker kicker--accent">Open source & mentorship</span>
<h3>Patterns in anyone's hands</h3>
<p class="mb-0">My framework is Apache-2.0 licensed and documented so production-grade enterprise patterns are free to use. I mentor engineers at every level, in English and Spanish.</p>
</div>
</div>
</div>
</section>
</main>
<!-- BEGIN site-footer -->
<footer class="site-footer">
<div class="container">
<div class="footer-grid">
<p class="footer-meta mb-0"><strong>Ivan Ball-llovera</strong> · Senior Software Architect · Douglasville, GA</p>
<ul class="footer-links">
<li><a href="resume.html">Résumé</a></li>
<li><a href="platform.html">Platform</a></li>
<li><a href="docs/index.html">Reference</a></li>
<li><a href="writing.html">Writing</a></li>
<li><a href="speaking.html">Speaking</a></li>
<li><a href="contact.html">Contact</a></li>
<li><a href="https://github.com/ivanball" target="_blank" rel="me noopener">GitHub</a></li>
<li><a href="https://www.linkedin.com/in/ivan-ball-llovera-6549a911" target="_blank" rel="me noopener">LinkedIn</a></li>
</ul>
</div>
<p class="footer-meta" style="margin-top:1rem">© <span class="js-year">2026</span> Ivan Ball-llovera. Built as a static site.</p>
</div>
</footer>
<!-- END site-footer -->
</body>
</html>