Back-End & Infrastructure

The Maintenance Tax PMs Miss When Adopting New Tech

A new backend framework can make a legacy ERP change look smaller on the roadmap while making every later change harder to support. My position is that a product manager should treat framework adoption as a recurring maintenance commitment, not a one-time delivery dependency, because the new stack will need its own upgrades, diagnostics, contract checks, and on-call knowledge even if the ERP remains the system of record.

The framework inherits ERP obligations that the launch estimate leaves out

The first adoption estimate usually prices the endpoint: build it, test it, release it. That estimate is incomplete when the endpoint reads ERP data, because the team must also keep its interpretation of that data correct through ERP patches, configuration changes, and exceptions entered by staff. An order status that appears to be a simple field may depend on posting rules or permissions that the new service does not own. Every such dependency creates a future investigation path, whether or not the integration code changes.

Before accepting a delivery estimate, ask for a maintenance map with four entries for each ERP interaction: the source of truth, the person who can explain its business rules, the test that detects a changed rule, and the team that responds when the test fails. This is more useful for scoping than a count of API endpoints, because two endpoints can have very different support costs if one reads a stable reference table and the other interprets a configurable posting workflow.

The shipping question in Can this framework ship on time A PM checklist for adoption deserves a second gate: who maintains the integration after the delivery team moves on? I would not approve adoption on the strength of a working demo, because a demo proves that one path worked with one set of ERP rules and says little about how the team will detect a rule change six months later.

Put discovery time in the scope before putting feature dates on the roadmap. As a planning example, if interviews identify 12 ERP writes but the prototype exercises only 3, the remaining 9 are unknown maintenance obligations rather than completed integration work; those counts are illustrative, so replace them with an inventory from your own system. Record scheduled jobs and manual corrections alongside API calls, because they may change the data the framework reads without ever calling its code.

Do not hide this work in a generic contingency percentage. A named owner needs time to answer questions after launch, and a test environment needs representative ERP configuration, because otherwise each incident becomes an improvised investigation in production. The deliverable for this phase is a dependency register that a support engineer can use, not a diagram that merely shows which service talks to which database.

Contract drift becomes a standing task even when nobody releases code

Many teams budget for breaking changes made by their own developers but not for changes in the ERP surface beneath them. A changed field meaning, a permission adjustment, or a newly required value can break an integration while its deployed binary stays untouched. This is why contract ownership belongs in the maintenance estimate: someone must notice a difference, determine whether it matters, and coordinate a fix with the ERP owner.

For HTTP interfaces, publish an OpenAPI 3.1 document for the boundary the new service owns and keep a reviewed snapshot in version control. A structural diff is an inexpensive early warning, not a compatibility verdict, because a schema can stay identical while the meaning of a status value changes. The following Bash check runs in CI when the current document is reachable and the baseline is a JSON file already normalized with jq:

#!/usr/bin/env bash
set -euo pipefail
: "${ERP_OPENAPI_URL:?set ERP_OPENAPI_URL}"
: "${ERP_OPENAPI_BASELINE:?set ERP_OPENAPI_BASELINE}"
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
curl --fail --silent --show-error "$ERP_OPENAPI_URL" | jq -S . > "$tmp"
diff -u "$ERP_OPENAPI_BASELINE" "$tmp"

A failing diff should open a review, not automatically block every release, because harmless description edits and consequential schema edits need different responses. Add tests for business examples that OpenAPI cannot express: an order reversed after posting, a customer whose permissions changed, and a retry after the ERP accepted a write but the network response was lost. Those cases earn their place in the test suite because each can leave the new service reporting a plausible but incorrect result.

The dependency work in Legacy ERP Modernization: Identify Dependencies and Scale Backends is a useful starting inventory, but I would attach a drift detector and a response owner to each critical dependency, because identification alone does not reveal when an assumption stops being true. Give each detector a scheduled review date as well as a CI run: an automated failure without an accountable reviewer simply moves the maintenance burden into an alert queue.

Set a provisional response target of 4 working hours for triaging a failed critical contract check, then tune that target against staffing and the actual consequence of bad data. The point is not to promise a universal service level; it is to expose whether the adoption plan includes anyone who can meet the target. If the only ERP specialist is also assigned to the next release, that conflict belongs in the product plan before launch.

A parallel service costs more to operate than a framework upgrade sounds like

Consider two named options for an ERP-adjacent feature. Extend the existing ERP integration layer wins when its release process and diagnostics are understood and the feature needs little outside traffic; it costs the team continued work within the old stack and may make changes slower. Adopt ASP.NET Core 10 as a parallel service wins when the team needs an independently deployed boundary and can staff it; it costs a separate runtime, deployment path, security configuration, telemetry pipeline, and upgrade calendar. The second option is not inherently better, because its autonomy only pays off if the team can operate what it has separated.

Write those operating items as backlog work with acceptance criteria. An ASP.NET Core service using EF Core 10 needs a documented migration policy even if it owns only a small PostgreSQL database, because an emergency rollback is harder when application code and schema have advanced together. A service that authenticates through OpenID Connect and authorizes via OAuth 2.0 scopes needs a process for rotating credentials and checking claims, because ERP permissions and service permissions can drift apart. TLS 1.3 at the boundary does not settle who may perform a reversal; transport protection and business authorization answer different questions.

Instrument the new boundary before customers depend on it. OpenTelemetry traces should carry a correlation ID across the service and its ERP call, with sensitive order and customer values excluded, because a trace that cannot connect both sides of a failed operation saves little investigation time while excessive attributes create a data-handling problem. Prometheus can collect request counts, error rates, and latency histograms; Grafana can display them, but a dashboard needs an owner who will change its alerts when normal traffic changes.

For a pilot, choose a tentative p95 ERP-call latency alert at 750 ms only if the first measured baseline shows that it separates abnormal calls from ordinary variation; otherwise adjust the alert rather than training on-call staff to ignore it. Also measure the fraction of writes that require manual reconciliation, because a fast service can still impose substantial support work if it leaves ambiguous outcomes. These are maintenance measures for the product manager, not merely performance details for engineers.

Upgrade dates create another backlog that a feature estimate can miss. Microsoft publishes support for .NET 10 through November 2028, so a service adopted now needs a funded path to its successor before that date rather than an assumption that the launch version will remain supported indefinitely. Put a named upgrade window on the roadmap, because an unowned support deadline tends to surface only when security or hosting requirements force the issue.

Support ownership must be priced before the feature is called done

A framework adoption changes who gets paged and what that person must know. If the ERP team can explain the transaction but cannot inspect the new service, and the service team can inspect its logs but cannot interpret an ERP rejection, a single incident may require both teams. Price that handoff explicitly: assign a primary responder, an ERP escalation contact, and a decision maker for correcting disputed records, because “the integration team owns it” does not identify who can safely act.

Run one failure exercise before launch. Have the ERP test environment accept a write and then interrupt the response, because this exposes whether a retry creates a duplicate, returns a safe result, or requires reconciliation. Record the operator’s steps in a runbook and time the exercise; that elapsed time is an observed maintenance cost that can replace a planning guess. If the team cannot reproduce the condition safely, reserve engineering time to make it reproducible rather than declaring the endpoint complete.

Scope a small queue for post-launch corrections as product work. For example, reserve an adjustable allowance of 6 engineer-days in the first quarter for integration defects and rule clarifications, then replace it with the actual hours recorded in tickets. Keep that allowance separate from feature capacity, because otherwise the same engineers are implicitly committed twice. Review the tickets for repeated causes: a recurring permission mismatch calls for a rule or test change, while a one-off data correction may call for a clearer escalation path.

The acceptance decision should be conditional, not ceremonial. Approve the new framework only when the team can show the dependency register, contract checks, telemetry, runbook, upgrade window, and named support capacity, because each item addresses a different way the product can fail after launch. If funding covers the endpoint but not those obligations, reduce the initial feature’s scope or keep it in the existing integration layer; that is a product trade-off, not resistance to a newer framework.

The first scope change should be an ownership interview

Schedule a working session with the ERP owner, the proposed service owner, and whoever handles production incidents. Pick one high-value write operation and trace its rules, failure cases, alerts, and correction procedure all the way to a named responder. Estimate that continuing work before approving the framework ticket, because the gap between a successful request and a supportable product is where the unplanned maintenance budget will appear.