SAN ANTONIO • APPLICATION MODERNIZATION

Move legacy .NET off the basement server without breaking what works

Veteran-owned, SDVOSB-certified modernization for San Antonio healthcare networks, financial services, JBSA-adjacent contractors, and Texas public agencies. Incremental cutovers, regulated-cloud targets, real runbooks.

Veteran-Owned SDVOSB
[001 / 005] Field Conditions

The 2011-vintage .NET app still runs payroll, and nobody wants to touch it

// SITUATION

San Antonio runs on systems that were modern when the Spurs last won a title. .NET Framework 4.5 apps on Windows Server 2012 R2 that fell off Microsoft support. SQL Server 2014 instances with stored procedures nobody has read in eight years. Classic ASP.NET Web Forms wired into Salesforce, Epic, or a homegrown claims engine. The original developer left in 2018. The vendor that wrote the integration layer was acquired twice. Audit findings keep stacking up. Meanwhile the system is processing real money or real patient records every minute, so a clean rewrite is off the table.

  • Windows Server 2012 R2 and 2016 boxes past end-of-support, with no patching path and a growing pile of vulnerability scan findings
  • WCF services and SOAP integrations to Salesforce, Zendesk, or a state Medicaid portal that nobody on staff understands well enough to rewrite
  • SQL Server stored procedures encoding a decade of undocumented business rules that aren't replicated in any application code
  • Compliance pressure — HIPAA, CJIS, PCI, CMMC — colliding with infrastructure that can't meet modern control baselines
90 days
Typical time to first production cutover
SDVOSB
Certified veteran-owned, federal-eligible
100% US
US-based engineers, no offshore handoff
[002 / 005] Operational Approach

Strangler-fig modernization that doesn't take the system down on a Tuesday

  1. STEP-01

    Inventory and dependency map

    We trace every COM+ component, SQL Agent job, SSIS package, IIS app pool, and shared DLL. Output is a real dependency graph — not a slide. We mark what's load-bearing, what's dead code, and what nobody wants to touch.

  2. STEP-02

    Carve seams, not rewrites

    We pick the first bounded context with clear inputs and outputs — usually a reporting surface or an integration edge. Wrap it behind an API gateway or facade, route traffic incrementally, and keep the legacy path live until the new path proves out under production load.

  3. STEP-03

    Lift to modern .NET on GovCloud

    Port .NET Framework 4.x to .NET 8 with a real compatibility pass — WCF to gRPC or CoreWCF, System.Web to Kestrel, Web Forms isolated behind a reverse proxy. Deploy to AWS GovCloud or Azure Government when CUI, PHI, or CJIS scope demands it.

  4. STEP-04

    Data migration with dual-write

    We run dual-write or CDC from SQL Server to the target store for weeks before cutover. Reconciliation jobs catch drift. Rollback is a config flag, not a 2 a.m. restore. No big-bang weekends.

  5. STEP-05

    Hand off with runbooks that work

    Your team gets the pipelines, the IaC, the alert thresholds, and runbooks written by the engineer who built the thing. We pair with your ops staff through two on-call rotations before we step back.

// CSHARP PATTERN
// Strangler facade: route a single endpoint to the new .NET 8 service
// while the rest of the .NET Framework 4.8 monolith keeps serving traffic.
// Deployed in front of IIS via YARP. Flip per-route, per-tenant, or by %.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddReverseProxy()
    .LoadFromMemory(
        routes: new[]
        {
            // New path: claims intake rewritten on .NET 8 + Postgres
            new RouteConfig {
                RouteId = "claims-v2",
                ClusterId = "claims-modern",
                Match = new RouteMatch { Path = "/api/claims/{**catch-all}" }
            },
            // Everything else still hits the legacy monolith
            new RouteConfig {
                RouteId = "legacy",
                ClusterId = "legacy-iis",
                Match = new RouteMatch { Path = "/{**catch-all}" }
            }
        },
        clusters: new[]
        {
            new ClusterConfig { ClusterId = "claims-modern",
                Destinations = new Dictionary<string, DestinationConfig> {
                    ["d1"] = new() { Address = "https://claims.internal.gov:8443/" }
                }},
            new ClusterConfig { ClusterId = "legacy-iis",
                Destinations = new Dictionary<string, DestinationConfig> {
                    ["d1"] = new() { Address = "https://legacy-iis.internal.gov/" }
                }}
        });

var app = builder.Build();
app.MapReverseProxy();
app.Run();

YARP-based strangler facade — route one endpoint at a time off the legacy monolith without a cutover weekend.

[003 / 005] Common Questions

Field FAQ.

How long does a typical .NET Framework to .NET 8 modernization take?

For a mid-size line-of-business app — say 200k to 500k lines, a few dozen integrations, one or two SQL Server databases — plan on 6 to 12 months end to end. The first production traffic on the new stack usually happens inside 90 days behind a strangler facade. Full decommission of the legacy footprint is the long tail and depends mostly on how many internal teams consume the old endpoints.

Why AWS GovCloud or Azure Government instead of commercial cloud?

If you handle CUI, ITAR-controlled data, CJIS-scoped records, or you're a contractor inside the JBSA orbit working toward CMMC Level 2, the regulated regions are usually the path of least resistance. They give you FedRAMP High inheritance, US-person operator controls, and audit trails the assessors already understand. For purely commercial healthcare or financial workloads, standard regions with proper controls are often fine.

We have a 24/7 operational system. How do you modernize without downtime?

Strangler-fig pattern, dual-write data migration, and feature flags. We never do big-bang cutovers on production systems that page somebody at 3 a.m. We put a routing layer in front of the legacy app, move one bounded context at a time, run the old and new paths in parallel until reconciliation reports clean for at least two weeks, then retire the old path. Rollback is always a config change.

Do you work with City of San Antonio, Bexar County, or State of Texas agencies?

Yes. As an SDVOSB, we're eligible for set-aside and sole-source vehicles at the federal level, and we work as a sub or prime on state and local contracts. We've handled DIR-adjacent procurement scenarios and understand HUB subcontracting plans. If you're a Texas agency or a prime looking for a qualified veteran-owned subcontractor on a modernization scope, that's a natural fit.

What about Web Forms and classic ASP.NET MVC apps that can't be ported cleanly?

Not everything ports. Web Forms in particular has no clean .NET 8 path. Our usual approach is to isolate the Web Forms surface behind a reverse proxy on Windows, freeze it, and rebuild new functionality as Razor Pages or a SPA against modern APIs. The old UI keeps serving until usage drops below a threshold worth rewriting. Sometimes that takes two years. That's fine.

How do you handle SQL Server databases with thousands of stored procedures?

We don't pretend they don't exist. Stored procs often encode a decade of business logic that lives nowhere else. The realistic path is to keep SQL Server (lifted to RDS or Azure SQL Managed Instance), refactor procs incrementally as the calling code moves to .NET 8, and only consider a different data store for new bounded contexts where the access patterns clearly justify it. Postgres-everywhere is a religious position, not an engineering one.

Can you augment our existing team instead of taking the whole project?

Yes — staff augmentation is a real offering, not a fallback. We embed senior .NET, cloud, and DevOps engineers into your team under your tech lead, your standups, your repos. Typical engagement is 2 to 5 engineers for 6 to 18 months. All US-based, all background-check eligible, and we can scope to US-person-only or cleared personnel when the contract requires it.

What does a modernization engagement actually cost?

Discovery and architecture assessment is typically a fixed-fee 4 to 6 week engagement in the $40k–$90k range depending on scope. Implementation is usually time-and-materials or milestone-based against a written SOW, with monthly burn ranging from roughly $60k to $250k depending on team size. We'll give you a written estimate with assumptions and risks before you sign anything. No surprise change orders.

Do you handle the FedRAMP or ATO paperwork, or just the engineering?

Both, but honestly. We build to FedRAMP Moderate or High control baselines and produce the technical artifacts — SSP technical sections, architecture diagrams, control implementation summaries, POA&M inputs. We partner with 3PAOs and compliance specialists for the assessment itself rather than pretending to be auditors. If you need full ATO sherpa services, we'll tell you who to call and integrate with them.

[ NEXT ACTION ]

Got a 15-year-old .NET system that nobody wants to touch? Let's talk.

Talk to a VooStack operator. We respond within one business day.