From Requirements Archaeology to a Microfrontend

Taking over the Product Owner role in the final phase of a multi-year microfrontend migration at a telecommunications shop and reconstructing a five-year-old, undocumented deposit shop from interviews, production code, and old records.

Platform MigrationMicrofrontend ArchitectureRequirements Archaeology

Snapshot

  • Role: Product Owner (previously project manager on the same initiative)
  • Organization: One of Germany's four largest telecommunications providers
  • Team: 8 developers, 1 shared Scrum Master, 2 shared architects
  • Focus: Migration of the last major feature block – a deposit shop for mobile and broadband – plus continued development of existing microfrontends
  • Starting Point: The deposit shop had been live for more than five years, but was practically undocumented. The original requirements and acceptance criteria no longer existed. Outcome: The multi-year migration initiative could be fully completed. The previously separate legacy application could then be taken out of operation.

Starting point

Before taking over the Product Owner role, I was already the project manager on the same migration initiative. The switch happened for two reasons:

  1. the previous Product Owner moved to a different internal position
  2. my project management budget ran out

With the role, my perspective changed too. As project manager, I had regularly pushed for reliable dates, addressed risks, and demanded clarity from Product Owners for further planning. Now I was the one in a situation where that clarity simply did not exist yet.

At that point, the shop migration was already about 90 % complete. Most of the functionality had been migrated to a microfrontend architecture. Two tasks remained for my team:

  1. migrate the deposit shop
  2. continue developing and operating the already-migrated microfrontends

The overall initiative had been running for several years and had missed its original timeline more than once. One consequence: during the migration, new features were still being built in the old system and then had to be implemented again for the new architecture. This kept expanding the scope well beyond what was planned at the original migration kickoff.

The real reason for the microfrontend architecture was never technical elegance. Teams were supposed to develop and deploy independently, without waiting for a shared release cycle.

The Problem

The remaining feature block was the so-called deposit shop. It is not a standalone shop, but an alternative customer journey within the regular ordering process.

When a customer wants to sign up for a mobile or broadband contract, but the credit check fails, they are offered an alternative:

  1. The customer receives an email stating that the original contract cannot be completed.
  2. The email contains a link to the deposit shop along with access credentials.
  3. The credentials are valid for 14 days.
  4. After logging in, the customer sees offers based on their original tariff selection.
  5. The customer selects an offer.
  6. The required deposit amount is calculated.
  7. The customer completes the purchase.
  8. They then have seven days to pay the deposit.
  9. After successful payment, the final offer is sent out.

At first glance, the task seemed manageable. The rest of the shop was already running on the new architecture; routing, microfrontends, and backend integrations were established. I initially assumed the existing patterns could largely be reused.

That turned out to be a wrong assumption. I could not find anything usable about the deposit shop in the company documentation, and my team had never even heard of it. When I tried to test the deposit shop myself, I first did not even know where the entry point on the website was. The reason: the shop is only accessible to customers whose credit check has failed.

Requirements Archaeology

It turned out that the deposit shop had been live and practically unchanged for more than five years. Built once, put into production, never developed further since.

There was hardly any usable documentation from the original development:

  • no complete Jira tickets
  • no original acceptance criteria
  • no maintained functional specification
  • no test environment
  • no architecture decisions
  • no up-to-date documentation of the business logic

Before I could prioritize requirements or plan development, I first had to figure out what the existing system was actually supposed to do. This task was anything but linear. Whenever I believed I had understood something, a look at the interface – together with the developers – often revealed that the actual logic differed from what had been communicated.

One example was the deposit amount. After the first five tests, it looked like the deposit was always a fixed amount. On closer inspection of the interface, however, it turned out that the deposit is not fixed, but calculated from several factors. Only once a threshold is reached or exceeded does a deposit cap kick in – which is why the amount looked like a fixed value in many cases. The original statement could be refuted, and it was exactly these contradictions that made the reconstruction so laborious.

I called this step requirements archaeology for myself, because I started with stories and had parts of the code dug up to understand how the business logic actually worked underneath.

Instead of deriving requirements from existing tickets, I had to reconstruct them from the remains of the old system:

  • interviews with people who had been involved in the original development or in support
  • old emails and documents
  • analysis of the existing production code
  • observation of the actually implemented behavior

Approach

1. Reconstructing requirements

I first documented the entire process before creating any Jira tickets. I kept showing this process in refinements, interviews, and sprint plannings, so that everyone involved shared the same holistic view.

The business rules around these areas were especially relevant:

  • validity of the access credentials
  • available offers
  • mapping to the original tariff selection
  • deposit calculation
  • payment deadline
  • handover after successful payment

Only once these rules were traceable could the requirements and acceptance criteria be made concrete for development. I deliberately refused to allow a reliable sprint plan based on incomplete requirements, because money and time-critical business rules were at stake. A wrong assumption in the deposit calculation or the payment deadline could have led to serious errors – and the company could have suffered reputational damage as a result.

2. Separating business logic from UI legacy

In parallel to the functional reconstruction, I worked with development and the architects to analyze which parts of the existing system actually had to be carried over. I distinguished between three categories:

  • existing business logic that had to be preserved
  • technical implementation details that could be rebuilt
  • UI elements that had merely grown historically

The business logic was validated and recorded as functional requirements. The interface, on the other hand, could be adapted to the current shop and the existing design system. That way, the migration did not become a 1:1 replica of the old interface, but a complete rebuild of the UI combined with a refactoring of the business logic.

3. Dealing with uncertainty

The schedule pressure of the overall program remained. At the same time, the Scrum Master and architects were not exclusively available to my team:

  • 1 Scrum Master worked across several teams.
  • 2 architects were also spread across three teams.
  • 8 developers worked in the team overall.

Instead of addressing architecture questions individually and at short notice, the team collected open points and sent them bundled ahead of architecture meetings. The questions were on the table at least a day before the meetings. This had a simple effect: the scarce shared time was used for decisions rather than for first figuring out what the meeting was even about.

Team and Stakeholder Management

Because I had been the project manager before and already knew parts of the team, the team-forming phase was significantly faster and easier than in projects I joined from scratch. But the perspective changed a lot: as project manager, I reported on the entire initiative – not in detail, but at a high level for management. The main point was naming concrete target dates: when the project would be finished and what content the next releases would contain. Budget had not been reported for this initiative in a long time; it was all about delivery and demonstrating delivery reliability.

As Product Owner, I was now several levels closer to the actual doing and saw the obstacles with my own eyes. The team was already well established, had years of migration experience, and was noticeably more relaxed than I was – it had been through deeper valleys than the unclear and vague requirements of the deposit shop.

The Perspective Shift

The move from project manager to Product Owner is what made this case special for me. As project manager, I had frequently demanded reliable statements on effort, dates, and risk from Product Owners. In this project, I was suddenly the one who had to say:

A reliable estimate is not possible yet, because we do not sufficiently understand the requirements.

This initially led to discussions in the project steerings, because a reliable delivery date was still expected – but I had to make that statement, because it was a concrete product decision. I explained to the project environment why additional time for analysis and validation was more sensible than issuing a seemingly precise plan based on incomplete information. I named a date for when the validation would be finished and coupled that date to the completion of two artifacts:

  1. a complete list of acceptance criteria
  2. an agreed architecture, provided by the architects as an ADR.

This created transparency and tied the target date to clear, measurable checkpoints – which could then serve as the basis for a release date.

This also changed my view of product ownership considerably. Naming target dates just to pretty up management slides and report green status based on incomplete requirements is not professional. Instead, you shift the focus to concretizing the requirements and commit to a date for that – to protect the team and the product from unnecessary rushed actions and forced pushbacks. I understand every perspective in this context, because I have gathered experience both in management and in operations. The most important rule when communicating dates is honesty and reliability. When I name a date, I do so with the intention of keeping it – a promise. If I cannot keep that promise due to obstacles, those obstacles have to be communicated and justified clearly.

The ADR I had tied the target date to was not about the technical integration of the microfrontend, but about the business logic itself. Specifically, it was about which of the rules reconstructed from interviews and production code – such as the deposit calculation or the validity period of the credentials – would apply as the binding basis for the new development, whenever witness statements and the actual code behavior did not match. The architects deliberately documented this decision as an ADR rather than just a functional specification, because it directly determined how validation and the data model in the new microfrontend had to be built. Only with this accepted ADR could development even begin – without the risk that a later correction of the business rule would call an already-built validation logic into question again.

Architecture

Technically, the deposit shop was a separately hosted monolith before the migration: a self-contained application with its own hosting, reachable only via the email link. During the migration, this monolith was not rebuilt as a single microfrontend, but split along the customer journey into four independent microfrontends:

Microfrontend Route Domain Access
Auth-MFE /login Identity/Auth Anonymous
Catalog-MFE /produkte Product catalog Auth required
Offer-MFE /warenkorb Offer/Pricing Auth required
Contract-MFE /vertrag Contract/Compliance/Confirmation Auth required

The split follows the logic that carried the entire migration program:

Every area can be developed, deployed, and evolved independently.

The compliance part (contract completion, deposit confirmation) is deliberately separated as its own microfrontend, so that changes to contract terms never have to be rolled out together with changes to catalog or pricing – and of course vice versa.

Business Continuity

The deposit shop was not an ordinary e-commerce use case. Customers only gained access when their original order had been rejected due to the credit check. The deposit solution was the way to still complete the purchase.

A bug in the deposit calculation, in the validity of the credentials, or in the payment deadline would have created friction at a particularly sensitive point of the customer journey. For me, that was another reason not to shorten the functional validation in favor of a faster sprint plan. With a normal UI adjustment, uncertainty can be treated differently than with business logic that determines how much a customer has to pay, and by when.

Results

The deposit shop was implemented as a standalone microfrontend and integrated into the existing shop architecture. What had been a productive but largely undocumented system for years became a traceable functional foundation for further development:

  • Roughly four weeks passed between project start and the first line of code. All of that time went exclusively into reconstruction, interviews, code and interface analysis, and the alignment of acceptance criteria.
  • The original deposit shop was split along the customer journey into four independently deployable microfrontends.
  • Business logic was reconstructed from interviews, production code, and available documents, and translated into concrete development tickets and acceptance criteria.
  • Credentials, offer logic, deposit calculation (including threshold and deposit cap), and payment deadlines were documented in a traceable way.
  • The existing UI was not copied blindly, but adapted to the current platform and design system.
  • The multi-year migration initiative could be fully completed. The previously separate legacy application could then be taken out of operation.
  • The initiative subsequently moved from the actual migration into the phase of further development and maintenance.

Due to confidentiality, I cannot publish specific conversion or revenue figures.

What I Learned

The biggest surprise

I had expected the technical implementation to be relatively straightforward thanks to the established microfrontend patterns. Instead, reconstructing the requirements was extremely laborious. Those four weeks made it clear that the bottleneck was understanding what the code was even supposed to do. A system can technically work and still be hard to maintain from a product perspective when nobody can retrace why it behaves the way it does – and that was exactly the case I had in front of me.

Documentation

Part of the original business logic could only be reconstructed because a few people were still with the company and remembered the decisions from back then. If those people had no longer been available, I would have had to rely far more heavily on the production code – an unnecessary risk, especially for rules like the deposit calculation or the payment deadlines.

Documentation is not just a technical artifact, but a means of making product decisions and business logic traceable years later. Which artifacts make sense depends on the context. For this project, I created the requirements and acceptance criteria and a process diagram, and the ADR was produced by the architects.

Product Owner

This case changed my view of the Product Owner role. As project manager, my focus was more on when something could be delivered. As Product Owner, I additionally had to ensure it was clear at all what was to be delivered and which assumptions lay behind it. Especially with legacy systems, this work is not always visible. Sometimes product ownership does not mean writing the next requirement into a ticket as quickly as possible, but first finding out which requirement still exists at all and how the system actually works.