Joining the Backend Team
Understanding the Product Requirement
In the previous lesson, we established the context of the project.
We are going to build an Order Management Backend, and throughout this course we will follow 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.
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:
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.
We should separate:
Explicit Requirement
from:
Our Assumption
before implementation begins.
Extracting Explicit Requirements
Let's first extract only the behaviour that the requirement explicitly states.
We will not add any new rules yet.
Customer Capabilities
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
- pay for an order
Product and Inventory Rules
We explicitly know that:
- products have inventory associated with them
- a customer cannot order a product unless inventory is available
- administrators can manage products
- administrators can manage inventory
Order Behaviour
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
- 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:
Product exists in the database
OR
Product is active
OR
Product has inventory greater than zero
OR
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.
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.
Questions include:
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?
For example:
id
name
price
status
Do we also need:
description
in the first version?
Can a Product be deleted?
Can it be 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:
Customers should only be able to order products
that are currently available in inventory.
But there is still substantial ambiguity.
Suppose a Product has:
available quantity = 5
and a Customer requests:
quantity = 6
Clearly, that request should not succeed.
But what about:
quantity = 0
or:
quantity = -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
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.
Suppose:
Product A
Price: 10.00
Quantity: 2
Product B
Price: 5.00
Quantity: 3
Then:
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.
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
quantity
It may also need a purchase-time price snapshot.
Conceptually:
OrderItem
productId
quantity
unitPriceCents
For example:
10.00
→ 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:
Product A × 2
Product A × 3
Or should the system normalize that to:
Product A × 5
Must an Order contain at least one item?
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
We need to understand the Order lifecycle.
A possible lifecycle might be:
UNPAID
↓
PAID
with cancellation:
UNPAID
↓
CANCELLED
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
financial reconciliation
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.
We need to understand questions such as:
Is payment synchronous?
What does a successful response look like?
Can payment fail?
Can payment 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 / business stakeholders
Some may come from:
payment provider documentation
And some will require:
engineering decisions
This distinction matters.
Not every unanswered question should be sent to the Product Manager.
A backend engineer needs to understand what kind of question they are dealing with.
Business Questions vs Technical Questions
Consider:
Can a paid order be cancelled?
That is a business question.
A Product Manager or another business stakeholder should answer it.
Now consider:
Should we use Spring RestClient or another HTTP client
for the payment provider integration?
That is a technical question.
The Product Manager does not need to decide it.
Now consider:
Does the payment provider support idempotency keys?
That is an external-system capability question.
The answer may come from provider documentation.
Keeping these categories separate prevents inefficient communication.
Categories of Questions
When reviewing requirements, it is useful to group questions into categories.
Business Behaviour
Who can perform an action?
When is an action allowed?
What happens after the action?
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?
These categories make requirement analysis more systematic.
Do Not Solve Everything at Once
Another common mistake is trying to solve every possible commerce problem as soon as the first requirement arrives.
We might start thinking about:
discounts
coupons
tax calculation
shipping
multiple currencies
refunds
warehouse allocation
backorders
subscriptions
gift cards
fraud detection
All of these are realistic commerce capabilities.
But none of them appear in the initial requirement.
Designing them now would introduce unnecessary complexity.
Strong engineering requires knowing what to build.
It also requires knowing:
What should not be built yet.
Scope Control
The final sentence of our product requirement says:
We want the first version to support the core ordering flow.
That matters.
The requirement explicitly talks about a first version.
So our scope should remain narrow.
A reasonable initial capability boundary might include:
Products
Inventory
Authenticated customer identity
Orders
Payments
Basic order cancellation
Possible out-of-scope capabilities include:
Discounts
Coupons
Shipping
Refunds
Multiple warehouses
Multiple currencies
Product recommendations
Event-driven architecture
But remember:
We should not invent arbitrary business rules just because they sound reasonable.
Later clarification will formally establish the actual v1 scope.
Functional Requirements
We can now look at the product brief as a collection of functional behaviours.
A functional requirement describes what the system must be able to do.
For example:
Customer can view products.
Customer can create an order.
Customer can view their orders.
Customer can cancel an eligible order.
Customer can pay for an order.
Administrator can manage products.
Administrator can manage inventory.
These describe system capabilities.
But functional requirements alone are not enough to define a production system.
Non-Functional Requirements
Suppose the system can successfully create an Order.
But every request takes:
45 seconds
Technically the feature exists.
Operationally, the system may be unusable.
Non-functional requirements describe quality and operational expectations such as:
performance
availability
security
reliability
observability
scalability
maintainability
Our initial product brief does not define explicit non-functional targets.
That is normal.
At this stage, useful questions might include:
What traffic do we expect?
Are there response-time expectations?
How business-critical is the service?
Are there regulatory requirements?
Do we need an audit trail?
The important point is not to invent arbitrary answers.
If someone says:
Order history should be fast.
we should notice that fast is not yet measurable.
We should not silently decide that it means:
200 ms
without context.
The next lesson will examine functional and non-functional requirements more closely.
Identify Invariants Early
A powerful concept in backend design is the invariant.
An invariant is 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:
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.
Another possible invariant is:
An order belongs to exactly one authenticated customer identity.
Another:
An order total must match its order items.
Identifying invariants early matters because they later influence:
domain models
transaction boundaries
database constraints
concurrency strategy
tests
Requirement Analysis Should Produce Questions
The output of a good requirement review is not code.
A useful output may contain:
Known facts
Unknowns
Assumptions
Questions
Risks
Scope boundaries
Let's perform a first-pass analysis of our requirement.
First-Pass Requirement Analysis
Known
Customers can browse products.
Customers can 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.
Orders can be paid through an external payment provider.
Unknown
How customers authenticate.
Whether guest checkout exists.
Exact Product fields.
When Inventory is reduced.
Exact Order statuses.
Cancellation eligibility.
Whether paid Orders can be cancelled.
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:
if (
order.getStatus()
== OrderStatus.UNPAID
) {
order.cancel();
}
The developer has silently decided:
Only UNPAID Orders can be cancelled.
The code may compile.
Tests may even pass.
But if the business intended paid Orders to support cancellation, the implementation is wrong.
The dangerous part of a hidden assumption is that the business decision disappears into code.
A better approach is:
Requirement says "eligible orders."
Eligibility is undefined.
Clarify cancellation rules before implementation.
Clarification Does Not Mean Endless Meetings
Requirement clarification does not mean scheduling a meeting for every small detail.
Good engineering communication can be concise.
For example:
Question:
For v1, which Order states should Customers be able to cancel?
Proposed behaviour:
Only unpaid Orders can be cancelled.
Paid Orders and refunds will remain out of scope.
Now the stakeholder can easily respond:
Yes, use that behaviour.
or:
No, paid Orders also need cancellation.
This style of communication is efficient.
Ask Questions With Context
A weak question would be:
How should cancellation work?
That is too broad.
A better question is:
For the first release, can we limit cancellation
to unpaid Orders?
If an unpaid Order is cancelled, its consumed
Inventory will be restored.
Refunds for paid Orders would remain out of scope.
Now the stakeholder understands the consequence of the decision.
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.
Requirement:
A customer must not be able to purchase
more inventory than is available.
Possible technical solution:
Use a database transaction with row-level locking.
Those are not the same thing.
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
Product Language and Engineering Language
Product requirements often use human-friendly language.
For example:
Customers should be able to quickly see their previous orders.
Quickly is understandable to a human.
But it is not measurable enough for an engineering target.
A technical requirement might eventually say:
Typical Order-history requests should complete
within an agreed latency target.
But what is that target?
200 ms?
500 ms?
2 seconds?
The correct number depends on context.
Requirement analysis should identify vague language.
It should not invent arbitrary measurements.
Example: Analysing One Requirement
Let's take one requirement through the full process.
Requirement:
Customers should be able to place orders.
Step 1 — Explicit Behaviour
A Customer can create an Order.
Step 2 — Missing Information
Must the Customer be authenticated?
Can an Order be empty?
Can the same Product appear twice?
What quantity values are valid?
What happens when a Product does not exist?
What happens when Inventory is insufficient?
When is Inventory reduced?
How is the price calculated?
Step 3 — Risks
Overselling
Incorrect pricing
Invalid Order state
Duplicate requests
Step 4 — Decisions Needed Before Implementation
At minimum:
Order item validation
Inventory behaviour
Pricing behaviour
The requirement is now much more actionable.
Requirement Review Is an Engineering Skill
Junior engineers sometimes treat a requirement like an instruction:
Someone told me what to build.
I will implement it.
Experienced engineers usually treat the requirement as the beginning of a conversation.
They ask:
Do we understand the behaviour?
Are there contradictions?
What assumptions are we making?
Which failure cases matter?
What is outside the scope?
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
to create JPA entities
to define all API endpoints
to finalize the OrderStatus enum
to choose the final transaction strategy
to 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.
Engineering Principle
The most important principle from this lesson is:
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 do I know?
What am I assuming?
What must I clarify?
What can safely wait?
That awareness prevents many production bugs before code is ever written.
Before We Move Forward
Our initial product requirement is no longer just a few paragraphs.
We have extracted:
explicit behaviour
open questions
possible invariants
risks
scope uncertainty
That is the purpose of requirement analysis.
Our next step is to classify the requirements more systematically.
In particular, we will separate:
Functional Requirements
from:
Non-Functional Requirements
because implementing the correct features alone does not make a backend production-ready.
We need to understand both:
what the system does
and:
how well and under what constraints it must operate
Summary
In this lesson, we learned that:
- A product requirement is not an implementation instruction; it is the starting point of an engineering discussion.
- Explicit requirements and assumptions must be kept separate.
- Ambiguous business behaviour should be identified before implementation.
- Not every unanswered question belongs to the Product Manager.
- Business questions, technical questions, and external-system questions should be distinguished.
- Product terminology such as
available,eligible, andquicklymay require clarification before it becomes an engineering contract. - Scope and non-goals are as important as requested functionality.
- We should identify likely risks early without prematurely solving all of them.
- Invariants help us understand which conditions the system must always protect.
- Requirements should describe what must happen, while technical designs describe how we intend to make it happen.
- Strong engineers try to understand system behaviour before writing code.
- Customer identity is part of the authentication context; we do not assume that the Order Management Backend needs a separate Customer management subsystem.
- We should avoid prematurely adding discounts, refunds, multiple currencies, warehouse logic, event-driven architecture, or other unrelated commerce capabilities.
- Requirement analysis should produce questions, assumptions, risks, and scope boundaries—not implementation code.
Our Order Management Backend requirements are not final yet.
That is expected.
In the next lesson, we will explore:
Functional vs Non-Functional Requirements
and structure our current product requirements using more precise engineering language.
