TwinCore delivered a legacy ASP.NET modernization for the Guides platform without taking it offline. Two full-stack developers rebuilt the backend on modern .NET, moved the frontend to a current Angular version, and replaced the data-access layer. They moved business logic out of stored procedures into C#. Then they added Redis caching, centralized logging, server monitoring, automated deployment, and a load balancer. The team cut over one screen at a time. Staff kept working in the old system while the new one took over module by module.

Country
Canada
Project duration
2 years
Team
  • 2 full-stack developers
Outcome
TwinCore safely modernized a business-critical ASP.NET ERP by moving it to modern .NET and Angular one endpoint at a time, with no big-bang release and no interruption to daily operations.

About the client

The client is a Canadian firm that provides geodetic and land-surveying services. Its work includes topographic base plans, legal boundary work, reference plans, and 3D scanning. Office and field teams run projects through a custom ERP that tracks each job from the first quote to the final invoice.

Surveyors, project managers, and account managers depend on this system daily to schedule field work, log hours against tasks, prepare budgets for scopes of work, and bill clients.

“Igor and his team fixed our ERP system in time and I am happy about our cooperation”

BP
Ben P.
Founder
60% Less Staff

A 2-person senior team replaced a 5-person setup to rebuild the full ERP end-to-end.

10x Faster

Worst-case page loads dropped from 10–30s to 1–2s on cached paths after optimization.

1:1 Parity

Every screen was validated against legacy behavior before cutover via internal tracking tools.

0 Downtime

Incremental, endpoint-by-endpoint cutover delivered seamless releases with no scheduled downtime.

Legacy ASP.NET modernization for a land-surveying ERP

What client received

  • A responsive job pipeline

    Problem: the Guides grid, the main working screen where staff track every job through its stages, became slow as the number of active jobs grew.

    Result: the screen stays responsive across hundreds of active jobs. Managers can see where each job stands and act without waiting for the page to load.

  • Quote and scope-of-work workflow

    Problem: staff had to use slow legacy pages to turn a quote request into a budgeted and awarded scope of work.

    Result: quoting a job now follows a single guided flow. Staff create the RFQ, locate the project on a map, build a per-task budget, and award the scope of work in one sequence. Quotes go out faster. Pricing logic that used to live in stored procedures now runs in C#, so changing a rate no longer means editing the database.

  • Per-task budgeting tied to hours

    Problem: budgets and the hours logged against them were hard to reconcile because the calculations were buried in the database.

    Result: each scope of work is broken down into tasks such as quote, research, field work, calculations, drafting, quality control, and management. Each task has editable budget hours and amounts. Project managers can compare planned and actual effort and protect the margin on a job.

  • Scheduling and capacity view

    Problem: field and office work had to be assigned using the same slow screens as the rest of the system.

    Result: schedulers see planned, scheduled, and unscheduled hours per task and assign team members in grid, board, or map views. Field and office capacity is visible before the team becomes overbooked for the week.

  • Centralized logging and monitoring

    Problem: when something broke, there were no centralized logs, so tracing a failure meant guessing.

    Result: errors and traces are now captured centrally. Server monitoring surfaces performance and availability problems as they happen, so the team can catch issues before they affect the client.

Project Goal

The firm wanted to modernize its business-critical ERP without disrupting daily operations. The goal was to improve performance, reduce recurring defects, and make future changes safer.

Solution

TwinCore owned the migration end to end and replaced the stack layer by layer instead of all at once. The team worked through the application module by module. Each screen moved to the new backend only after the new implementation matched the old behavior. Daily operations never stopped.

  • Backend on modern .NET — the ASP.NET application was rebuilt on a current version of .NET. The new backend did less work per request, and frequently requested data was cached instead of recomputed.
  • Angular upgrade — the frontend moved from a legacy Angular version to a current one, screen by screen. Old and new pages ran side by side during the transition.
  • New data-access layer — the old ORM (object-relational mapper, the layer that maps database rows to objects in the application) was replaced with a modern one. Business logic was also moved out of stored procedures into C#, where it can be unit-tested and reviewed.
  • Redis caching — Redis (an in-memory data store used as a cache) now serves hot read paths. The slowest pages no longer hit the database on every request.
  • Scheduled background jobs — Quartz.NET handled recurring jobs and scheduled backend tasks in the modernized stack.
  • Centralized logging — errors and traces are collected in one place, turning “something failed somewhere” into a searchable record.
  • Automated deployment — the deployment process moved from manual steps to a pipeline that builds Docker images and deploys them to Google Cloud using GitHub Actions. Shipping a fix became routine instead of risky.
  • Infrastructure hardening — TwinCore added a load balancer (which spreads traffic across application instances) and server monitoring. Moving logic out of stored procedures also improved maintainability and made safer query and authorization patterns possible at the endpoint level.
  • Legacy ASP.NET modernization for a land-surveying ERP screenshot 1
  • Legacy ASP.NET modernization for a land-surveying ERP screenshot 2
  • Legacy ASP.NET modernization for a land-surveying ERP screenshot 3
  • Legacy ASP.NET modernization for a land-surveying ERP screenshot 4
  • Legacy ASP.NET modernization for a land-surveying ERP screenshot 5
  • Legacy ASP.NET modernization for a land-surveying ERP screenshot 6
Previous slide
    Next slide

    Who needs a platform like this

    The platform is designed for companies that manage temperature data across multiple customers and sites, rather than for a single warehouse. Typical users include 3PL cold-chain warehouses, pharma and medical distributors, and food operators working under GDP or HACCP requirements. They need to produce complete monitoring records on request. This can be difficult with slow, single-site tools, especially when an inspector requests twelve months of historical data.

    One tradeoff we made

    TwinCore separated the data based on its structure and usage. Relational data (clients, sites, sensors, users, and permissions) stays in one PostgreSQL database, where relationships and access rules are easiest to enforce. High-volume time-series data (readings recorded continuously over time) is stored in MongoDB. Each client has a separate MongoDB database, allowing each tenant's history to scale independently.

    The tradeoff is the need to maintain two data stores and manage synchronization between them. In return, dashboard and reporting queries remain efficient as the number of readings grows into the millions.

    Architecture and UI

    The data flows from the sensors to the screen as follows: Sensors → Ingestion/Alarm engine → PostgreSQL (entities) + MongoDB (readings) → SignalR → React console

    Operators use a filterable sensor list for daily monitoring, with status, signal strength, last activity time, and site information. The trend report lets auditors review temperature history, safe ranges, and out-of-range readings at a glance.

    Previous slide
      Next slide

      Technologies used

      .NET
      Angular
      MS SQL
      Redis
      Quartz.NET
      Docker
      GitHub Actions
      Google Cloud API
      Google Cloud Storage
      centralized logging
      load balancer
      server monitoring

      Why TwinCore

      TwinCore fit the project because it combined production-safe legacy modernization with full-stack .NET and Angular delivery.

      • TwinCore had experience modernizing production systems that could not go offline.
      • The team could handle .NET and Angular across the full stack.
      • The project also needed performance, deployment, logging, and infrastructure improvements.

      That mix of experience let the client move off the legacy stack one screen at a time instead of betting the whole ERP on a single release.

      Results in numbers

      • Worst-case page loads were cut from roughly 10–30 seconds to 1–2 seconds on cached paths, based on internal before-and-after checks during the migration, after moving hot reads off synchronous stored procedures onto Redis.
      • The migration was completed with zero scheduled downtime because each endpoint was cut over individually.
      • The release process moved from infrequent manual deployments to automated, on-demand releases. Fixes no longer had to wait for a manual release window.
      • Centralized logging replaced manual server investigation and made failures easier to diagnose.
      • The modernization improved security practices in the data-access layer and at the endpoint level.

      Ready to modernize your legacy ERP?

      Book a 30-minute modernization review if your team runs a business-critical ERP or line-of-business application on legacy ASP.NET, Angular, or MS SQL. We will review your current stack, outline the main migration risks, and map an incremental path that keeps the system running during the transition.

      Scroll to top