Feature breakdown · built with CraftHQ
Two-step review & approval workflow
Whole-team time at this build's pace
2 people incl. the product owner, requirements to merge
Estimate at this build's pace, not a measurement of this feature
Nothing is finalised until a reviewer and then a customer approver have both signed off, and neither can approve their own work.
How long a feature this size usually takes
Whole-team time — this build vs a typical team
~16 FP · FP × 6.8 to 9.4 h (ISBSG 2023)
Estimate at this build's pace, not a measurement of this feature
Both figures are whole-team time over the whole lifecycle, so they compare like for like. Ours is this build's pace — about 0.8 hours per function point across the whole build (two people, including the product owner, with requirements and review time). The industry range is an ISBSG project-level figure applied to one feature, so it is indicative.
Workflow
How it moved through the workflow
Select a stage. The build shipped, so every stage is complete; a person approved the merge.
Request
Nothing should be finalised on one person's say-so. An item needs a reviewer's sign-off and then the customer approver's, with a clean way back if either sends it back, and no one approving their own work.
Questions
One design decision was recorded before building: what happens to an item sent back after it has already reached the second step.
Approved
The product owner signs off the breakdown by moving the story into the approved state, and the build runs against that reference.
Definition of ready
Building
CraftHQ's build agents write the code and the tests together, run as a loop; a failing check halts the work until it passes.
Checks
Three checks run on every pull request: one on the product owner's machine as CraftHQ builds, one on the engineer's machine before review, and a code-quality scan in CI. Merging is gated by the CI check passing and a person's approval, enforced by branch protection.
Review
An engineer reviews the pull request and merges it.
Merged
The pull request is merged to main after a person approves it. Nothing merges without that approval.
Definition of done
Breakdown
The feature breakdown
Business first, then the engineering view. Tab through it.
Overview
The gap it closes
Work can slip out the door after one person looks at it. Two sign-offs, one internal and one from the customer, close that gap, and the item is locked between them so nothing changes under review.
Who uses it
A submitter puts an item up for review; a reviewer approves it or sends it back at the first level; a customer approver gives the final approval through their portal. No one can approve their own work: the submitter is not the reviewer, and the reviewer is not the customer approver.
User story
As a reviewer, I want to approve an item or send it back, and let a customer approver give the final approval, so that nothing is finalised without two independent sign-offs.
Examples
Example 1
A reviewer approves an item at the first level, pinned to the submitted revision. It is locked and moves to the customer approver, who approves it through the portal once the package is ready at the current revision, and the item is finalised.
Example 2
An item that already reached the customer is sent back with a reason. It re-opens and returns to the submitter, who corrects it and submits again; the earlier approval no longer holds, and it is re-reviewed before it can be finalised.
Dependencies & risks
Depends on
A reviewer surface inside the product, an approval surface in the customer portal, and a record of the revision the first-level approval applied to.
Risk & mitigation
Two risks: an item could be approved by the person who wrote it, or its content could change after approval so the hand-over no longer matches what was signed off. Reduced by a maker-checker rule (no self-approval) and by pinning the first-level approval to the submitted revision, so a later change drops the approval and forces a re-review.
State machine
An item moves: draft -> in review (locked) -> sent back (re-opened, returned to the submitter) -> resubmitted (locked) -> customer approval -> final. A send-back is the only thing that re-opens an item, and it always names the state it returns to.
How it works
Simplified diagrams of the parts involved, the steps of one request, and where it runs.
Architecture
- 1submit for review
- 2approve or send back
- 3lock and record the version
- 4approve or send back (portal)
- 5finalise, or re-open and return
- 6record the outcome
Sequence
- 1approve at the first level
- 2lock the item, record the approved version
- 3append the first sign-off to audit
- 4approve or send back (once the package is ready)
- 5finalise, or re-open and return to the submitter
- 6append the outcome to audit
Infrastructure
- 1approve or send back (authenticate + tenant check)
- 2read and write item state, append audit
Acceptance criteria
Each scenario is written as a Gherkin spec. The Engineering tab shows the test that covers each one, or notes where it was verified by review.
@review @workflowFeature: Two-step review and approval workflowAs a reviewerI want to approve an item or send it back, and let a customer approver give the final approvalSo that nothing is finalised without two independent sign-offsAn item is finalised only after a reviewer approves it and then a customer approver approves it. No one approves their own submission, the item is locked between sign-offs, and the first-level approval is pinned to the submitted revision.Background:Given an item has been submitted into first-level reviewAnd the submitter, the reviewer and the customer approver are three different peopleRule: An item needs two independent sign-offs before it is finalisedScenario: A reviewer approves at the first levelGiven an item is in first-level reviewWhen the reviewer approves itThen the item is lockedAnd it moves to the customer approver for the second approvalScenario: The customer approves at the second levelGiven an item has passed first-level reviewWhen the customer approver approves it through the portal once the package is ready at the current revisionThen the item is finalisedRule: No one may approve their own workScenario: The submitter cannot approve their own itemGiven the submitter tries to approve their own itemWhen they submit the approvalThen the approval is refusedScenario: The reviewer cannot give the customer-side approvalGiven the reviewer gave the first-level approvalWhen the same person tries to give the customer-side approvalThen the approval is refusedRule: An item is locked while under review and only a send-back re-opens itScenario: A submitted item cannot be editedGiven an item has been submitted into reviewWhen someone tries to change its contentsThen the change is refused server-side while the item is lockedScenario: A reviewer sends an item backGiven an item is in first-level reviewWhen the reviewer sends it back with a reasonThen the item re-opensAnd it returns to the submitter with the reasonAnd it can be corrected and submitted againRule: The first-level approval is pinned to the submitted revisionScenario: A change after approval drops the approvalGiven an item was approved at the first level, pinned to that revisionWhen its contents change afterwardsThen the first-level approval no longer holdsAnd the item must be re-reviewed before it can be finalised@edge-casesScenario Outline: A send-back always names the state it returns toGiven an item is at "<stage>"When it is sent back with a reasonThen it re-opens and returns to "<target>"Examples:| stage | target || first-level review | the submitter || second-level approval | the submitter |
Questions
Questions raised in planning, each with the decision taken.
What happens to an item that is sent back after it has already reached the second step?
If a send-back from the customer left the item with no route forward, it would be stuck.
How we sized it
A function point measures what the software does — its inputs, outputs, lookups and the data it stores — regardless of language or how many lines it took. Each counted item is weighted by complexity: a user input counts 3–6 points, an output or report 4–7, a lookup 3–6, data the feature owns 7–10, and data read from elsewhere 5–7.
- Submit into first-level review, approve or send backUser input4
- Second-level approvalUser input4
- Re-entry into review after a send-backUser input4
- The review surfaceLookup4
- Total16
Not counted here
- The approval state is part of the item's own store, not counted again here
Components touched
State machine
An item moves draft -> in review (locked) -> sent back (re-opened, to the submitter) -> resubmitted (locked) -> customer approval -> final. The lock is enforced server-side; a send-back is the only transition that re-opens.
Approval gate
Holds an item at each level until it is approved, records the revision the first-level approval applied to, and refuses a sign-off by the item's assigned owner or the author of the submission (two checks). Status changes go through one writer, and a database trigger refuses an illegal jump.
Portal approval surface
Lets the customer approver give the second-level approval once the package is ready at the current revision, or send the item back with a reason.
Re-entry path
Returns a sent-back item to the submitter, re-opened, with the reason and the named target state; the prior approval no longer holds.
Data touched
Item statewrite
The review and approval state of each item, and the revision the first-level approval applied to; updated at each transition.
Approval recordswrite
Who approved or sent back, at which level, with the send-back reason, and when.
Audit logappend
Each sign-off and send-back is recorded.
Security decisions
- Maker-checker: the submitter cannot approve their own item, checked on the server on two counts (the item's assigned owner, and the author of the submission); illegal status jumps are refused by a database trigger.
- An item's inputs are locked server-side once it is submitted into review, so they cannot change under review; only a send-back re-opens it.
- The first-level approval is pinned to the submitted revision; a change after approval drops that approval and forces a re-review, so a hand-over cannot be built from an edited-after-approval item.
- Every sign-off and send-back is recorded in the audit log.
Subtasks
- A server-enforced state machine with the lock and the single re-open-on-send-back transition.
- An approval gate that records the approved version and refuses self-approval.
- A portal approval surface for the customer approver, available once the package is ready at the current revision.
- A re-entry path that re-opens a sent-back item and names the state it returns to.
How each scenario is verified
- A submitter cannot approve their own itemAn integration test refuses the item's assigned owner as first-level approver with a distinct audit event, refuses an author swapped into the reviewer seat, then lets a different approver succeed.
- A change after approval re-enters reviewAn integration test confirms a change after the first-level approval voids it and re-enters the first level, and a change after the second-level approval voids both approvals and re-locks.
- Only legal transitions are allowedA transitions test asserts exactly the canonical edges, and a database trigger refuses a raw illegal status jump.
- A send-back returns to the maker and re-enters reviewAn integration test confirms a customer send-back goes to the maker and re-enters the first level.
- The review screen does not auto-submitAn end-to-end test confirms the review screen fires no write on load and submits only on an explicit click.
Risk tier
Core A person approves every merge. This is a Core-tier change, so it also carries the fullest set of automated tests; a regression here affects the whole product, not one page.
Start here
Want this on your backlog?
Get a free baseline report on one repository, or scope a 3-month pilot measured against what your team’s work costs today.