Scott Bush

I build software that stays up.

Senior .NET engineer with fourteen years building products end to end, from the database to the screen, often as the only engineer on them.

Ankeny, IowaLinkedInGitHub

Certifications and education

Experience

Skills

Languages
C#, TypeScript, JavaScript, HTML, CSS, SQL, T-SQL, PowerShell
Frameworks
.NET 8 and 10, ASP.NET Core, Blazor, SignalR, REST APIs, gRPC, Protocol Buffers, Entity Framework Core, .NET Framework, xUnit
Cloud and data
Microsoft Azure (Service Bus, Web Apps, Azure SQL, Blob Storage, Traffic Manager), AWS, Microsoft SQL Server, PostgreSQL, Redis, IBM MQ
Tools
Claude Code, Azure DevOps, Git, GitHub, GitHub Actions, Visual Studio, JIRA, Aspose, PDFTron, MuleSoft Anypoint
Core competencies
System architecture, multi-tenant SaaS, legacy modernization, AI-assisted development, data integration, ETL and batch processing, Agile and Scrum, production support, requirements analysis
  1. Creator and sole developer, CardStock

    Mar 2026 – now

    Independent project, cardstock.pro

    • Designed, built and operate cardstock.pro, a live market-data terminal for the Pokémon card aftermarket, developed end to end with Claude Code: .NET 10, Blazor WebAssembly, minimal APIs, EF Core and PostgreSQL, self-hosted on Linux behind a Cloudflare Tunnel with GitHub Actions CI and systemd deployment.
    • Built the companion scraping pipeline (PokemonInvestBatch) that has archived 10.3 million price observations across 91,570 cards and 788 sets into an append-only, change-only PostgreSQL store where absent rows mean unchanged rather than missing, and designed the read layer around that distinction.
    • Enforced a hard read-only boundary between two applications sharing one database: separate schemas and migration lineages, least-privilege roles proven by testing denied writes against the live database, and EF Core view mappings locked in by model tests.
    • Specified 30 market indicators with per-metric data-sufficiency floors that render an explicit state instead of a number when unmet, governed by a 310-entry decision ledger where every verified claim requires a receipt anyone can re-run.
  2. Lead Software Engineer

    Jun 2025 – Mar 2026

    Farm Bureau Financial Services, West Des Moines

    • Re-platformed a business-critical nightly batch pipeline as the only developer on the project, syncing 22,000 to 150,000 life and annuity policies per night (ACORD TXLife) from the Verisk FAST system of record into local Microsoft SQL Server, moving from .NET Framework 2.0, WCF SOAP and ADO.NET to a .NET 8 gRPC service on Entity Framework Core.
    • Proved correctness by replaying production runs against the rewrite and diffing databases row for row before cutover.
    • Reduced per-record processing from roughly 150 ms to 30 ms by consolidating dozens of database round trips per policy into two or three, cutting the nightly batch from over 6 hours to 1–2 hours.
    • Eliminated chronic risk to a hard 6 AM deadline that every downstream consumer depended on, including correspondence, general ledger feeds, CSR screens and compliance extracts.
    • Applied Claude Code to map hundreds of undocumented legacy fields, including direct mappings, ID and IDREF relation resolution and type-code lookups, reaching roughly 90 percent accuracy up front and substantially de-risking the migration.
    • Provided production support for SSRS reports, diagnosing failures and handling deployments, and resolved a chronic timeout on a heavily used report by restructuring the underlying query with CTEs, restoring reliable on-demand execution.
    • Developed an ACORD schema validator that turned overnight payload rejections, 0 to 30 per night, from up to an hour of manual XML diagnosis into near-instant, routable findings.
    • Prototyped CQRS, Onion, N-Tier and Vertical Slice REPR architectures, drove team consensus on REPR with gRPC after benchmarks showed parity with Web API, and authored the standards playbook adopted as the team blueprint for greenfield .NET 8 development.
  3. Senior Software Engineer

    Apr 2022 – Apr 2025

    Sertifi, Chicago (remote)

    • Developed the quorum-gated, multi-level e-signature workflow engine powering ordered signing on hundreds of thousands of hospitality agreements monthly, including per-client quorum rules, edit-triggered signature resets, turn recomputation on mid-flow contract changes, and stale-link handling that told signers exactly what changed.
    • Implemented a per-signature audit trail capturing IP address, login and event metadata, used by legal teams to resolve contract disputes.
    • Built signature placement on dynamic documents with permanent burn-in to finalized PDFs using Aspose and PDFTron.
    • Introduced Redis as the platform’s first distributed cache, scoped to the highest-traffic dashboard as a trial ground, using TTL-cached aggregates over multi-million-row tables and indefinitely cached immutable IDs to cut page load from roughly 10 to 4 seconds.
    • Owned the application side of decomposing the core “room” god table on live production using feature-flagged dual read and write paths, per-tenant legacy backfills, and overnight cutovers sequenced smallest tenant first across a multi-month rollout with zero data loss.
    • Removed chronic database blocking and a structural 8-signer cap as a result of that decomposition.
    • Created dead-letter-queue recovery tooling for a new Azure Service Bus payments pipeline that grew from 0 to $150 million a quarter in processed volume, with automated failure notifications carrying the full message payload for recovery.
  4. Software Developer II

    Jul 2021 – Apr 2022

    Co-Op Financial, Des Moines

    • Developed MuleSoft Anypoint integration flows serving credit union API requests for member and transaction data across the payments network.
    • Contributed to the organization-wide Log4Shell response, auditing integration runtimes and dependencies, including precautionary log4net removal, during an industry-wide zero-day event at a payments company.
  5. Software Developer (contract)

    Feb 2021 – Jul 2021

    Kuder, Adel

    • Maintained and extended a legacy web codebase in Lasso, a language obscure enough that no usable documentation existed, ramping up entirely by reading the code and authoring the standardization documents that made it maintainable for successors.
  6. Software Engineer

    Mar 2019 – Feb 2021

    ESO Solutions, Austin (remote)

    • Designed and built a generic, reusable Excel ETL ingestion framework in C# using parameterized base classes that owned all parsing, type coercion and error handling, so onboarding a new entity or source system required only a source model and a mapper.
    • Reduced fire-department data migrations from competitor systems and the ESO legacy product from months of manual spreadsheet transformation to roughly two weeks of programming work.
    • Accumulated per-competitor mappers into a reusable library that made repeat onboardings largely configuration.
    • Implemented parsing against the ISO and OOXML Excel specifications to handle the many on-disk representations of identical-looking cells across producers.
    • Designed log-and-continue error handling so one bad row never killed a 20,000-row file, surfacing per-row failure reasons and live progress to an AngularJS UI through a polled status endpoint.
    • Routed validated rows over REST to owning bounded-context microservices.
  7. Software Developer

    Mar 2017 – Mar 2019

    Community Choice Credit Union, Johnston

    • Built Lead Manager on a two-person team, owning every architectural decision behind a multi-tenant SaaS product live across 5 credit unions and still sold commercially today as SimplyFocused.
    • Designed a stage-based lead workflow state machine with a customer-facing visual progression tracker that let credit union members follow their own loan status, years before that experience was common in financial services.
    • Implemented optimistic concurrency on every lead update with token-checked writes and rejection of stale writes, paired with a SignalR live dashboard pushing real-time pool changes, so claimed leads disappeared from every other officer’s view instantly and double-claims were prevented by design.
    • Deployed on Azure managed services including Web Apps, Azure SQL with geo-replication failover groups, Traffic Manager and Blob Storage, deliberately inheriting Azure reliability SLAs rather than building custom redundancy a two-person team could not maintain.

Selected work

Two products I directed, designed and built end to end.

Iowa Bins

One service, two audiences: customers booking a move, and the crew running the day.

Role
Product, UX direction, developer
Built with
.NET 10 on a Raspberry Pi
Scope
30 screens: booking, staff admin, emails, errors
Status
Live at iowabins.com, still in progress
Iowa Bins booking page prototype: tote count, rental length and delivery date on the left, with a running order total on the right that says nothing is charged today.
Customers: everything on one page, with the total always in view
Iowa Bins staff dispatch prototype: morning and afternoon stops in order, a capacity meter near its limit, yard inventory, and a failed-charge flag on one stop.
Staff: the day's run, capacity and yard inventory
Order confirmed prototype: headline 'You're on the schedule', a note that nothing is charged today, and the order total.
Confirmation: when the card is charged, in plain words
Emails and texts spec: twenty messages listed, with the booking confirmation's trigger, subject, preheader, text version and rendered email.
Every message the system sends, specified
404 page prototype: headline 'This one is not on the truck' with links to reserve totes, the estimator, pricing, what fits in a tote, how it works and the FAQ.
404: a way forward, not a dead end
  • Say when money moves

    "Nothing is charged until the morning of delivery" sits beside the total, because that is the question a customer has before they book.

  • One owner for every change

    Customers never edit an order themselves; they call or text and staff make the change. Every screen, email and FAQ answer was rewritten to agree.

  • Design the edges

    Twenty emails and texts are specified with their triggers, and error pages send people somewhere useful.

  • Audit the whole set

    A sweep of all 30 screens found places where they contradicted each other. I settled each one and sent a single fix list back.

Rejected: self-service changes

Letting customers move or cancel from My Order meant instant charges and edge cases a small crew could not support. A read-only order page and a phone number were kinder.

From the owner decisions log.

CardStock

Designing honest interfaces for incomplete data.

Role
Product, UX direction, sole developer
Built with
.NET 10, Blazor WebAssembly, PostgreSQL
Status
Live at cardstock.pro, still in progress
CardStock screener backtest prototype: saved screens on the left; entry and exit rules; a plain-language summary that 11 buy signals were found, 75% of the 4 aged entries made money, and 7 entries have not aged 30 days yet; an equity curve against the market index; and result tiles with a return distribution.
Screener backtest, prototype. The result is written as a sentence, including what is not known yet.
Home prototype: market strip, a feed of cards entering and leaving saved screens, a binder summary against the market index, and a watchlist with sparklines.
Home, prototype
Card page prototype for Umbreon VMAX Alt Art: prices for six grade tiers, a signals panel showing 25 evaluated and 3 firing, and a 12-month price chart.
Card page, prototype
Binder prototype: holdings with the screen each card came from, shown as Exited or Active badges with arrows, and EST badges on values no recent sale supports.
Binder, prototype. EST marks values no recent sale supports.
  • A state, not a fake number

    Each of the 30 indicators has a data-sufficiency floor. Below it, the screen shows a dash and says why, never a misleading figure.

  • Label every estimate

    Prices you enter never change. Current values move with the market, and any value without recent sales behind it carries an EST badge.

  • Say it in a sentence

    A backtest ends with plain words: how many signals, how many made money, and how many have not aged long enough to count.

  • Colour is never the only signal

    Gains carry signs, screen status carries a word and an arrow, and the app ships light, dark and two colourblind palettes.

Rejected: animating the jump

Validation messages made the transaction modal resize abruptly. Two fixes were built and compared live: animating the resize, or reserving space for the messages. I chose to reserve the space, so nothing moves at all.

One of 310 entries in the CardStock decision ledger.

From the live app

Sales data has been paused since mid-October while the Back Office replaces the blocked scraper, so the live charts are thin. They still show how the app handles what it has.

Live CardStock chart page for Mega Charizard X EX: card art, PSA 10 price, grade tier chips, indicator values shown as dashes where data is too thin, and a price history with individual sales as dots and a dotted segment where no sales were recorded.
Indicators without enough data show dashes. Dotted segments mark days with no sales, instead of a line that pretends to know.

CardStock Back Office

Rebuilding a data pipeline after the source shut the door.

When PriceCharting blocked the scraper that fed CardStock, I didn't work around the block. I researched replacements on a $100-a-month budget, asked sources for permission, and wrote a design spec before any code. The new .NET worker keeps a catalogue linked across three sources and collects eBay and TCGplayer sales through a paid sales-data API.

  • 481 commits and 866 tests
  • Sources never overwrite each other. A nightly cross-check turns every disagreement into an open issue.
  • Built on a staging Pi while production keeps running. CI refuses a deploy when a test fails.
  • One daily report email, and no routine hand work
Built with
.NET 10 worker, PostgreSQL, GitHub Actions
Status
In staging, cutover pending

Cipher cracker

Teaching myself cryptanalysis on a cipher I haven't cracked yet.

A 29,411-digit ciphertext, digits only, believed to hide English. I used it to learn classical cryptanalysis from the ground up: frequency and n-gram analysis, index of coincidence, Kasiski examination, entropy, and simulated annealing for key search. Two .NET 10 apps ran on Raspberry Pi 5s for days at a time, with Claude proposing strategies and me running, checking and steering them.

  • 8 hypotheses refuted and 2 still open, each with the evidence that decided it
  • 222.5 billion straddling-checkerboard candidates tested. None read as English.
  • 32 hours of simulated annealing ruled out every Gronsfeld key from length 2 to 20.
  • Digit-pair substitution hit a hard ceiling across 288 billion candidates, which ruled out a fixed pair code.

What it taught me: proving what a cipher isn't takes the same rigour as proving what it is.

Built with
.NET 10, two Raspberry Pi 5s
Status
Paused, unsolved