Õppetunnile juurdepääsu kontrollimine...
Understanding the Product Requirement
Reading the Product brief literally, finding its open questions and routing them to the right people.
Vaatad tasuta eelvaate õppetundi.
We are going to build an Order Management Backend, following a development process similar to the workflow of a real engineering team. Now our team has received its first requirement from the product side. But receiving a requirement does not mean we should immediately start coding.
The goal of this lesson is to learn how to read and analyse a requirement like a backend engineer and identify what information is still missing before implementation begins.
The Initial Product Requirement
Imagine that the Product Manager gives our team the following requirement:
We need an Order Management Backend for our commerce platform.
Customers should be able to browse available products and place orders.
An order may contain multiple products.
Customers should only be able to order products that are currently available in inventory.
The system should calculate the total price of the order.
Customers should be able to view their previous orders and cancel eligible orders.
Administrators should be able to manage products and inventory and to view orders.
Customers should be able to pay for their orders using our payment provider.
We want the first version to support the core ordering flow.
This is a perfectly reasonable product requirement. From a business perspective, it gives us a clear direction for the system. But from a backend engineering perspective, it is not yet precise enough to implement safely.
Our first job is not to immediately turn this requirement into a technical specification. Our first job is to understand:
What does the requirement actually say, and what does it not say?
Read Requirements Literally First
A common mistake during requirement analysis is filling in missing details with our own assumptions too quickly. Suppose the requirement says "Customers should be able to cancel eligible orders." If we immediately assume that an unpaid order can be cancelled, we have introduced a business rule that the Product Manager did not explicitly state.
That rule may be completely reasonable. But:
Reasonable and confirmed are not the same thing.
This distinction matters in professional engineering. Before implementation begins, we separate the explicit requirement from our assumption.
Extracting Explicit Requirements
Let's first extract only the behaviour that the requirement explicitly states, without adding any new rules yet.
According to the requirement, a customer can browse available products, place an order, include multiple products in an order, view previous orders, cancel eligible orders and pay for an order.
About products and inventory, we explicitly know that products have inventory associated with them, that a customer cannot order a product unless inventory is available, and that administrators can manage both products and inventory.
About orders, we explicitly know that an Order can contain multiple products, the system calculates the Order total, an Order can be paid through a payment provider and some Orders can be cancelled.
So far, we have not gone beyond the requirement.
What We Still Do Not Know
This is where the real engineering work begins. Behind almost every sentence in the requirement, there are unanswered questions. Consider "Customers should be able to browse available products." What exactly does available mean? Possible interpretations include:
- the product exists in the database
- the product is active
- the product has inventory greater than zero
- the product is active and has inventory greater than zero
These behaviours are not equivalent. If we choose one interpretation ourselves, we may write technically correct code while implementing the wrong business behaviour. The following sections walk through the other sentences of the requirement in the same way.
Question 1: What Is a Customer?
The requirement repeatedly refers to a customer. For the backend, we need to understand how that customer is identified:
- Must the customer be authenticated? Can guests place orders?
- Does every order belong to exactly one authenticated customer?
- Can an administrator place an order on behalf of a customer?
Later in the course, we will implement authentication. For now, the important point is that customer identity is an external identity concern that the Order Management Backend will consume. We are not assuming that this project needs its own Customer account-management subsystem. During requirement analysis, however, we still need to identify the business rules around customer identity and ownership.
Question 2: What Is a Product?
The requirement says administrators manage products and customers browse them. But what is the minimum information a Product needs? Perhaps an id, name, price and status. Do we also need a description in the first version?
Can a Product be deleted, or only deactivated? What happens to historical Orders if an already-purchased Product is later deleted? What happens to existing Orders if the Product price changes? These are not merely implementation details. Many of them define business behaviour.
Question 3: What Does Inventory Mean?
One of the most important requirements is that customers should only be able to order products that are currently available in inventory. But there is still substantial ambiguity.
Suppose a Product has an available quantity of 5 and a Customer requests a quantity of 6. Clearly, that request should not succeed. But what about a quantity of 0, or -2? Those will eventually become validation rules. A more important question is: when does inventory decrease? Possible choices include:
- when the order is created
- when payment starts
- when payment succeeds
- when the order is shipped
Each choice has consequences. If Inventory is not reduced until payment succeeds, multiple Customers may be able to create Orders for the same final available unit. If Inventory is reduced during Order creation, unpaid Orders can hold Inventory until they are cancelled or otherwise resolved.
This decision will later affect transactions, concurrency, cancellation behaviour and failure handling. That is why it should be identified during requirement analysis rather than discovered accidentally while writing code.
Question 4: How Should Price Work?
The requirement says the system should calculate the total price of the order. That sounds straightforward:
Product A price 10.00 quantity 2
Product B price 5.00 quantity 3
Order total = (10.00 × 2) + (5.00 × 3) = 35.00
But there is a more important question. Suppose Product A costs 10.00 when the Order is created, and later its price changes to 15.00. Should the historical Order total change?
Usually, we want historical Orders to preserve the price that applied when the Order was created. That means an OrderItem may eventually need more than productId and quantity: it may also need a purchase-time price snapshot, conceptually a unitPriceCents field (10.00 becomes 1000 cents).
Notice that we are still not implementing anything. We are identifying a domain consequence of the requirement.
Question 5: What Does “Multiple Products” Mean?
The requirement says an order may contain multiple products. That creates more questions. Can the same Product appear twice, for example as Product A × 2 and Product A × 3, or should the system normalize that to Product A × 5?
Must an Order contain at least one item, or is an empty Order valid? Must every quantity be a positive integer? Is there a maximum number of items in an Order?
Not every question necessarily needs an answer for the first release. Knowing which questions must be resolved now and which can safely wait is part of engineering judgement.
Question 6: What Is an Eligible Cancellation?
The requirement says customers should be able to cancel eligible orders. The ambiguous word is eligible, and to resolve it we need to understand the Order lifecycle. A possible lifecycle might be:
Diagrammi joonistamine…
But at this point, that would still be a proposed interpretation rather than an explicit requirement. If the Product Manager confirms "Only unpaid orders can be cancelled", then the rule becomes clear.
If paid Orders can also be cancelled, we immediately introduce another question: what happens to the payment? That may require refunds, payment reversal and financial reconciliation, and the initial requirement says nothing about refunds. So a useful business question is: are paid orders cancellable in the first version? A single answer can significantly change the scope of the system.
Question 7: What Does Payment Mean?
The requirement says customers should be able to pay for their orders using our payment provider. Now we have an external dependency, and we need to understand questions such as:
- Is payment synchronous? What does a successful response look like?
- Can payment fail? Can it time out?
- Can the same order be paid twice? Does the provider support idempotency?
- Do we receive webhooks?
- What payment reference should we store?
It is not realistic to expect every one of these answers in the initial product requirement. Some information may come from product and business stakeholders, some from the payment provider's documentation, and some will require engineering decisions. This distinction matters:
Not every unanswered question should be sent to the Product Manager.
Business, Technical and External-System Questions
A backend engineer needs to understand what kind of question they are dealing with:
| Question | Kind | Who answers |
|---|---|---|
| Can a paid order be cancelled? | Business question | A Product Manager or another business stakeholder |
Should we use Spring's RestClient or another HTTP client for the payment provider integration? | Technical question | The engineering team; the Product Manager does not need to decide it |
| Does the payment provider support idempotency keys? | External-system capability question | The provider's documentation |
Keeping these categories separate prevents inefficient communication.
When reviewing requirements, it is also useful to group questions by topic, which makes requirement analysis more systematic:
| Category | Typical questions |
|---|---|
| Business behaviour | Who can perform an action? When is it allowed? What happens after it? Which state transitions are valid? |
| Data | What information must be stored? What must remain historically accurate? What relationships exist between entities? |
| Validation | Which inputs are valid? What limits exist? What should happen for invalid requests? |
| Failure behaviour | What happens when a dependency fails? Can an operation be retried? Can partial success occur? |
| Security | Who can access which resource? Can one customer see another customer's order? Which operations require administrator permissions? |
| Scope | What belongs in version one? What is explicitly out of scope? |
Do Not Solve Everything at Once
Another common mistake is trying to solve every possible commerce problem as soon as the first requirement arrives: discounts, coupons, tax, shipping, multiple currencies, refunds, warehouse allocation, subscriptions, fraud detection. All of these are realistic, but none of them appear in the initial requirement, and designing them now would introduce unnecessary complexity. Strong engineering requires knowing what to build. It also requires knowing:
What should not be built yet.
The final sentence of the brief, "We want the first version to support the core ordering flow", explicitly talks about a first version, so our scope should remain narrow. A reasonable initial boundary might include products, inventory, authenticated customer identity, orders, payments and basic cancellation. But we should not invent arbitrary business rules just because they sound reasonable; later clarification will formally establish the actual v1 scope.
Functional and Non-Functional Requirements
Everything we extracted so far is functional: what the system must be able to do. Production systems also need non-functional expectations such as performance, availability and security, and our brief defines none. That is normal, but we should notice vague words such as "quickly" rather than silently deciding that "fast" means 200 ms. The next lesson examines both kinds of requirement.
Identify Invariants Early
A powerful concept in backend design is the invariant: a rule that must always remain true for the system to be in a valid state. From our current requirement, one likely invariant is:
Inventory must not become negative.
The product brief does not state that exact sentence. But it does say that customers should only be able to order products that are currently available in inventory. A natural consequence is that the system must not successfully sell more quantity than is available. We will formally confirm and define that later.
Other possible invariants are that an order belongs to exactly one authenticated customer identity, and that an order total must match its order items. Identifying invariants early matters because they later influence domain models, transaction boundaries, database constraints, concurrency strategy and tests.
First-Pass Requirement Analysis
The output of a good requirement review is not code. A useful output contains known facts, unknowns, assumptions, questions, risks and scope boundaries. Let's perform a first-pass analysis of our requirement:
### Known
- Customers can browse products and create orders.
- Orders can contain multiple products.
- Inventory availability affects ordering.
- The system calculates order totals.
- Customers can view previous orders.
- Some orders can be cancelled.
- Administrators manage products and inventory and can view orders.
- Orders can be paid through an external payment provider.
### Unknown
- How customers authenticate, and whether guest checkout exists.
- Exact Product fields.
- When Inventory is reduced.
- Exact Order statuses and cancellation eligibility.
- Whether paid Orders can be cancelled, and whether refunds are required.
- Payment provider behaviour.
- What historical pricing data must be preserved.
- Initial traffic expectations.
### Likely Risks
- Overselling Inventory.
- Incorrect Order totals.
- Duplicate payment attempts.
- Unauthorized access to another Customer's Order.
- External payment provider failures.
We do not need to solve all of these risks immediately. But identifying them early is valuable.
Avoid Hidden Assumptions
Suppose a developer reads "Customers can cancel eligible orders" and immediately writes:
<!-- fragment -->if (order.getStatus() == OrderStatus.UNPAID) {
order.cancel();
}
The code may compile, and tests may even pass, but the developer has silently decided that only UNPAID Orders can be cancelled. The dangerous part of a hidden assumption is that the business decision disappears into code. A better approach is to note that eligibility is undefined and clarify it before implementation.
Clarify Concisely, With Context
Requirement clarification does not mean scheduling a meeting for every small detail. Good engineering communication can be concise. A weak question would be "How should cancellation work?", which is too broad. A better one proposes a behaviour and states its consequences:
**Question:** For the first release, can we limit cancellation to unpaid Orders?
**Proposed behaviour:** Only unpaid Orders can be cancelled. If an unpaid Order
is cancelled, its consumed Inventory will be restored. Paid Orders and refunds
remain out of scope.
Now the stakeholder understands the consequence of the decision and can easily respond "Yes, use that behaviour" or "No, paid Orders also need cancellation." This style of communication is efficient. Senior engineers do not simply collect questions. They narrow ambiguity and turn it into actionable decisions.
Separate Requirement From Proposed Solution
Another important habit is keeping requirements separate from solutions. The requirement "A customer must not be able to purchase more inventory than is available" is not the same thing as the possible technical solution "Use a database transaction with row-level locking."
The business requirement may remain stable while the technical solution changes. A different implementation might use optimistic concurrency, or an atomic conditional database update. The correct solution depends on the system we eventually design. So our documentation should ideally distinguish what must happen from how we plan to implement it.
Requirement Review Is an Engineering Skill
Junior engineers sometimes treat a requirement like an instruction: someone told me what to build, so I will implement it. Experienced engineers treat it as the beginning of a conversation: do we understand the behaviour, are there contradictions, which failure cases matter and can this be implemented safely? That does not mean resisting the Product Manager's requirement. It means taking engineering responsibility for the implementation.
Our Current Clarification List
For the Order Management Backend, our first clarification list might look like this:
1. Are Customers required to authenticate?
2. Can guests place Orders?
3. What makes a Product "available"?
4. When should Inventory be reduced?
5. Must an Order contain at least one item?
6. Can the same Product appear multiple times in one Order?
7. Should the purchase-time Product price be stored with the Order?
8. Which Order states are cancellable?
9. Are refunds required in v1?
10. What are the initial Order states?
11. What happens after successful payment?
12. What capabilities does the payment provider expose?
13. Which Product and Inventory operations can administrators perform?
14. Are there important performance or availability expectations?
15. What is explicitly out of scope for the first release?
Not every question has the same priority. In the next lessons, we will refine them.
A Practical Requirement Review Template
On a real project, a lightweight template can help:
# Requirement Review
## Problem
What business problem are we solving?
## Users
Who uses this capability?
## Explicit Requirements
What behaviour has been requested?
## Open Questions
What is still ambiguous?
## Assumptions
What are we currently assuming?
## Risks
What could make the implementation incorrect or unsafe?
## Out of Scope
What are we deliberately not building?
This is not an RFC. It is simply a lightweight working document that helps us understand a requirement. Not every team needs such a document for every change, but the thinking model is useful regardless of whether the template is formally written down.
What We Should Not Do Yet
At this point, we still do not have enough information to design the final database schema, create JPA entities, define all API endpoints, finalize the OrderStatus enum, choose the final transaction strategy or implement payment integration.
We can form educated ideas about some of these things. But finalizing them now would allow the solution to get ahead of the requirement. Throughout this course, we will intentionally avoid that shortcut.
Practice Exercise 1: Review the Sentence Nobody Analysed
Solutions: lesson 1.09.
This lesson walked through most of the brief, but not the end of one sentence: "Administrators should be able to … view orders." Create docs/requirement-review-admin-orders.md in your workspace's docs/ folder and use the Requirement Review template above, kept short:
- Explicit Requirements: what the sentence actually says, and nothing more.
- Open Questions: at least five, each tagged business, technical or external-system.
- Assumptions: anything you caught yourself assuming while reading it.
- Out of Scope: what you would propose to leave out of the first version.
Finish with one question rewritten in the "Question / Proposed behaviour" form from "Clarify Concisely, With Context".
Practice Exercise 2: Explicit, Assumed or Something Else?
Classify each statement as explicit (the brief says it), assumption (reasonable, not confirmed), likely invariant (follows from the brief, still to confirm) or solution (a way to implement, not a requirement). One sentence of reasoning each.
- An Order can contain more than one Product.
- Only unpaid Orders can be cancelled.
- A Customer must be logged in to browse Products.
- Inventory must not become negative.
- The backend calculates the Order total.
- Use row-level locking so two Customers cannot buy the last unit.
- An Order's total keeps the prices that applied when it was created.
Practice Exercise 3: Who Answers?
Route each question to the Product Manager, the engineering team or the Payment provider's documentation:
- Is there a maximum number of items in one Order?
- Should the Order total be computed in the handler or in the domain model?
- Does the provider send a webhook when a payment settles?
- Can an Administrator place an Order on behalf of a Customer?
- How long should our backend wait for the provider before it gives up?
Knowledge Check
Question 1
A rule such as "unpaid Orders can be cancelled" sounds sensible. Why should it not go into the code until someone confirms it?
Question 2
Why does "when does Inventory decrease?" belong in requirement analysis instead of being decided while writing the Order code?
Question 3
Why is "Can we limit cancellation to unpaid Orders? Proposed behaviour: …" a better question than "How should cancellation work?"
Question 4
Why keep "a Customer must not buy more than is available" separate from "use a transaction with row-level locking"?
Question 5
Discounts, tax and refunds are all realistic for a commerce system. Why does the first-pass analysis leave them out?
Knowledge Check Answers
Answer 1
Reasonable and confirmed are different things. Once the rule is inside an if, the business decision has disappeared into code where nobody reviews it as a decision, and if Product meant something else, the code is wrong while its tests pass.
Answer 2
The choice decides what can go wrong: reducing at payment lets several Customers order the last unit, reducing at creation lets unpaid Orders hold stock. It shapes transactions, concurrency and cancellation, so it should be a conscious decision, not an accident of implementation.
Answer 3
It narrows the ambiguity to one decision and shows its consequences (Inventory restored, refunds out of scope), so the stakeholder can answer yes or no quickly. A broad question returns a broad answer that still has to be turned into rules.
Answer 4
The requirement is stable, while the solution may change: optimistic concurrency or an atomic conditional update could satisfy the same rule. Recording only the solution hides what it protects, and recording it as a requirement stops design from choosing a better one.
Answer 5
None of them is in the brief, and the brief asks for a first version of the core ordering flow. Designing them now adds complexity, and invented rules, with no confirmed need behind them.
Engineering Principle
Never turn an assumption into a business rule without noticing that you did it.
It is impossible to eliminate all uncertainty; real-world software always contains some unknowns. But a strong engineer knows the difference between what they know, what they are assuming, what they must clarify and what can safely wait. That awareness prevents many production bugs before code is ever written.
Summary
- A product requirement is not an implementation instruction; it is the starting point of an engineering discussion, and explicit requirements must be kept separate from assumptions.
- Words such as
available,eligibleandquicklymay need clarification before they become an engineering contract. - Not every unanswered question belongs to the Product Manager: business, technical and external-system questions have different owners.
- Scope and non-goals are as important as requested functionality; we do not add discounts, refunds, multiple currencies, warehouse logic or event-driven architecture before they are needed, nor a separate Customer management subsystem, since customer identity comes from authentication.
- Invariants, such as "inventory must not become negative", tell us which conditions the system must always protect.
- Requirements describe what must happen; technical designs describe how we intend to make it happen.
- Requirement analysis produces known facts, questions, assumptions, risks and scope boundaries, not implementation code.
Our Order Management Backend requirements are not final yet, and that is expected. In the next lesson, Functional vs Non-Functional Requirements, we will separate what the system does from how well and under what constraints it must operate, and structure our product requirements using more precise engineering language.
Mõtle enne
TulekulKontrollküsimused, mille puhul valid vastuse enne, kui õppetund selle näitab.