All features

Feature breakdown · built with CraftHQ

Review & recordsWorkflow

Two-step review & approval workflow

Whole-team time at this build's pace

Estimated ~13 h

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.

Size: ~16 FP · Proxy estimate; an in-house count, not independently checked. Parts 4+4+4+4 = 16. Range 12 to 24. · How we counted 16 FP

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)

Whole-team time at this build's pace2 people incl. the product owner, requirements to merge
~13 h10 to 19 h

Estimate at this build's pace, not a measurement of this feature

A typical team, whole lifecycleRequirements to release · middle half of 512 comparable projects (Java, Agile), ISBSG 2023
~109 to 150 habout 2.5–4 person-weeksmedian ~126 h
grey band = a typical team, middle halfhatched = our whole-team estimate

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

The questions are answered.
The acceptance criteria are testable.
The size is estimated.
The scope is checked for splitting.
The product owner has signed off.

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

Every acceptance criterion is checked; where a scenario has a dedicated test it is cited, and where it was verified by review that is stated.
The three checks are green.
A person approved the merge.

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

People
Submitterputs the item up
Reviewerfirst sign-off
Customer approverfinal sign-off
Your app
App serverruns the state machine
Approval gatelocks, records the version
Audit logsign-offs and send-backs
  • 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
Simplified.

Sequence

Reviewerfirst level
Customer approversecond level
App serverthe approval gate
Item state + auditread and append
  • 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
Simplified.

Infrastructure

Client (untrusted)
Web appruns in the browser
Your app
App serverauthenticates, pins the tenant, runs the gate
Databaseper-tenant isolation, item state
  • 1approve or send back (authenticate + tenant check)
  • 2read and write item state, append audit
Simplified.

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 @workflow
Feature: Two-step review and approval workflow
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
An 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 review
And the submitter, the reviewer and the customer approver are three different people
Rule: An item needs two independent sign-offs before it is finalised
Scenario: A reviewer approves at the first level
Given an item is in first-level review
When the reviewer approves it
Then the item is locked
And it moves to the customer approver for the second approval
Scenario: The customer approves at the second level
Given an item has passed first-level review
When the customer approver approves it through the portal once the package is ready at the current revision
Then the item is finalised
Rule: No one may approve their own work
Scenario: The submitter cannot approve their own item
Given the submitter tries to approve their own item
When they submit the approval
Then the approval is refused
Scenario: The reviewer cannot give the customer-side approval
Given the reviewer gave the first-level approval
When the same person tries to give the customer-side approval
Then the approval is refused
Rule: An item is locked while under review and only a send-back re-opens it
Scenario: A submitted item cannot be edited
Given an item has been submitted into review
When someone tries to change its contents
Then the change is refused server-side while the item is locked
Scenario: A reviewer sends an item back
Given an item is in first-level review
When the reviewer sends it back with a reason
Then the item re-opens
And it returns to the submitter with the reason
And it can be corrected and submitted again
Rule: The first-level approval is pinned to the submitted revision
Scenario: A change after approval drops the approval
Given an item was approved at the first level, pinned to that revision
When its contents change afterwards
Then the first-level approval no longer holds
And the item must be re-reviewed before it can be finalised
@edge-cases
Scenario Outline: A send-back always names the state it returns to
Given an item is at "<stage>"
When it is sent back with a reason
Then 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.

AIt re-opens and returns to the submitter with a reason, then is re-reviewed before it can be finalised. · recommended
BIt stays where it is and has to be re-created.
Decided: It re-opens and returns to the submitter, then re-enters review (option A).

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 back
    User input
    4
  • Second-level approval
    User input
    4
  • Re-entry into review after a send-back
    User input
    4
  • The review surface
    Lookup
    4
  • Total
    16
16 function points (range 12–24). IFPUG-style count: each user action, lookup, output and stored data set, weighted by complexity. Technical plumbing is excluded, and a data store is counted once in the feature that owns it.

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 item
    An 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 review
    An 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 allowed
    A 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 review
    An integration test confirms a customer send-back goes to the maker and re-enters the first level.
  • The review screen does not auto-submit
    An 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.

Measured from your own git history
Every pull request tested before review
A person approves every merge