End-to-end narrative of how a Tender moves through oxFlow — from opportunity intake to client submission. This is the spine that the view inventory, navigation map, and sub-flows hang off.

Primary actors: Admin · Lead Estimator · Estimator (per foundation/roles-permissions.md)

Scope: v1 (Alpha core + Release additions per proposal).


1. Journey at a glance

┌─────────────────────────────────────────────────────────────────────┐
│ 1. OPPORTUNITY 2. STRUCTURE 3. BUILD-UP 4. PROCUREMENT │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Tender │──▶ │ Estimate │──▶ │ Items + │──▶│ Adjudications│ │
│ │ created │ │ + │ │Worksheets│ │(PBA / SPA) │ │
│ │ │ │Headings │ │ │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
│ │
│ 5. COMMERCIALS 6. REVIEW 7. PUBLISH 8. OUTCOME │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Rules + │──▶ │ Anomaly │──▶ │Publisher │──▶│ Won / Lost / │ │
│ │Submission│ │ Review + │ │ Output │ │ Archived │ │
│ │ Values │ │ sign-off │ │ │ │ │ │
│ └──────────┘ └───────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Eight stages, each anchored to a set of views and a dominant entity. Stages 3 and 4 usually run in parallel — procurement begins as soon as enough build-up exists to scope.


2. Stage 1 — Opportunity intake

Goal: Capture the pricing opportunity and optional schedule.

Who: Lead Estimator (primary); Admin can also create.

What happens:

  1. Lead Estimator creates a Tender — name, number, Client (Company with Client role), client reference, location, contract start date, tender due date, win probability (Low / Medium / High), optional Categorization tags, notes.
  2. If an MS Project file is available, they upload a Tender Program at the Tender level. The system parses the .mpp, populates Program Tasks, and sets the Tender Program’s parse status.
  3. Tender status = Active. No Estimates yet.

Key entities touched: Tender, Company (Client lookup), Tender Program, Program Task.

Sources:

  • Company records sync one-way from Xero — new Clients appear automatically when added in Xero.
  • Tender Program upload is optional. Tenders without a program skip Production Rate interactions in the Worksheet.

Exits:

  • Tender is created and visible in the Tenders list. Ready for Estimate creation.
  • If Tender Program parse failed, the Tender is still usable; an Anomaly Review flag persists until the file is re-uploaded successfully.

3. Stage 2 — Structure the Estimate

Goal: Create the Estimate shell and lay out the work tree.

Who: Lead Estimator creates the Estimate and assigns itself (or another Lead Estimator) as Lead. Estimators take over the tree build-out.

What happens:

  1. Lead Estimator creates an Estimate inside the Tender — name (e.g., “Base Case”), estimate number (e.g., “rev a”), Lead Estimator assignment (required), optional notes. Estimate status = In Progress.
  2. They lay out top-level Headings — the client schedule structure (e.g., “01. Preliminaries”, “02. Earthworks”, “03. Concrete Works”). Headings nest up to 5 levels.
  3. They start adding Items under Headings — description, unit, quantity, Item Type (Schedule / Normal / Provisional Sum / Rate-Only / Excluded / Included Elsewhere / Risk), required Workcentre Code, optional Categorization tags.
  4. Item status starts at Unpriced (empty Worksheet, no plug_rate).

Variants: A Tender can hold multiple Estimates (base, alternative, fast-track strategy). Each has its own tree and Lead Estimator.

Key entities touched: Estimate, Heading, Item, Code Option (Workcentre), Categorization Option.

Exits:

  • Work tree in place; Items exist but are all Unpriced.
  • Estimator(s) can start building Worksheets.

4. Stage 3 — Item build-up (Worksheets)

Goal: Cost each Item — either by direct plug rate or by Worksheet build-up.

Who: Estimators (primary); Lead Estimators and Admins have full edit rights.

What happens per Item:

An Item always has exactly one Worksheet. The estimator fills it out using five child element types:

  • Variables — named values (manual / Program Task duration / Calculation result / Recipe Input Parameter)
  • Calculation Blocks — named formulas that reference Variables
  • Content Blocks — structured free text (Inclusions, Exclusions, Task Breakdown, Risks, plus any admin-defined blocks)
  • Worksheet Resources — snapshot usages of Resources from Price Books
  • Worksheet Recipes — snapshot usages of Recipes with Input Parameter values

Two shortcuts exist for rough / late-stage Items:

  • Plug rate — instead of building up, enter a direct rate on the Item. Worksheet stays empty. Item status = Plugged. plug_rate and Worksheet cost-contributing children are mutually exclusive.
  • Recipe — drop in a reusable methodology from the Recipe Library; supply Input Parameter values; the Recipe’s Output Unit rate × quantity contributes to the Item cost.

Rate-edit mechanics — when a Worksheet Resource rate needs editing, three actions are available:

  • Per-instance override (default, silent)
  • “Apply to this Estimate” (bulk across the Estimate)
  • “Fork to new Resource” (creates a Resource in an auto-generated Project-Specific Price Book)

All three trigger: affected Items cascade Reviewed → Priced.

See sub-flows/worksheet-buildup.md and sub-flows/rate-edit-mechanics.md for the detail.

If the Tender has a Program:

  • Estimator can link Program Tasks to Items (M:M). Each linked Task surfaces as a Dur_{TaskName} Variable in the Worksheet.
  • Production Rate Variables cross-check quantity ÷ task duration against declared rate. Anomaly Review flags mismatches.

Outcomes per Item:

  • Empty Worksheet + no plug_rateUnpriced
  • Empty Worksheet + plug_rate set → Plugged
  • Worksheet has cost-contributing content → Priced

Exits:

  • All (or most) Items are Priced (or deliberately Plugged for rough figures).
  • Some Resources may still reference old Price Book rates → candidates for Adjudication.

5. Stage 4 — Procurement (Adjudications)

Goal: Get fresh market pricing for Resources or for Item bundles.

Who: Estimators can run both adjudication flavours. Lead Estimators oversee awards.

Two flavours, same six-step workflow: Generate → Export → Import → Compare → Normalise → Transfer.

5.1 Price Book Adjudication (PBA)

Scope: a set of Resources selected from the Estimate’s active Price Books (e.g., 8 labour rates across 3 suppliers).

On award: winning rates replace the scoped Resource rates in place. Existing Worksheet Resources that reference those Resources hold their old snapshots → Anomaly Review flags divergence and the estimator pushes the new rates through.

Rounds: PBA supports multiple rounds. Each round is a full six-step cycle; later rounds overwrite earlier awards on the same Resource set.

See sub-flows/price-book-adjudication.md.

5.2 Subcontract Package Adjudication (SPA)

Scope: a Subcontract Package — a named bundle of Items (created first, as a persistent scope object). Items can be added/removed while the current Adjudication round is Draft.

On award: the system creates (or updates) a system-generated Price Book holding one Subcontract Resource per Item in the Package, with the winning subcontractor’s rates. Each Item’s Worksheet gets a Worksheet Resource linking to its corresponding Resource.

Rounds: SPA supports multiple rounds. The system-generated Price Book persists across rounds (same ID; contents updated in place).

See sub-flows/subcontract-package-adjudication.md.

Exits:

  • Items that passed through adjudication now carry fresh, sourced rates. Items that stayed outside adjudication keep their original Price Book snapshots or plug rates.
  • Variance / inclusion / exclusion notes captured during adjudication land as Content Block instances on the affected Items.

6. Stage 5 — Commercials

Goal: Turn total cost into revenue. Derive Submission Values.

Who: Lead Estimator (primary); Admin can also edit.

What happens:

  1. Lead Estimator opens the Commercials view for the Estimate.
  2. They add Rules in sequence — name, rule type (Percentage / Lump Sum), value, scope targets (All / Direct-only / Indirect-only / specific Heading / Item Type / Resource Type / Categorization Option / Code value / specific Item).
  3. Rules apply in sequence order. Each Rule operates on the running scope total after prior Rules. Percentage Rules compound; Lump Sum Rules distribute proportionally across in-scope Items by cost weight.
  4. The system computes a Submission Value per Schedule Item. Lead Estimator can override any Submission Value with an explicit value + optional audit note.

See sub-flows/commercials.md.

Exits:

  • Every Schedule Item has a final Submission Value (computed or overridden).
  • Estimate totals reflect cost + commercials.

7. Stage 6 — Review & sign-off

Goal: Catch errors, anomalies, and outliers before submission.

Who: Estimators triage their own Items; Lead Estimator signs off.

What happens:

  1. Anomaly Review runs across the Estimate, producing three layers of flags (see sub-flows/anomaly-review.md):
  • Layer 1 — deterministic structural/rule checks (e.g., missing Unit, Plant without operator, Production Rate mismatch)
  • Layer 2 — Reference Rate comparisons (rules-first, AI-assisted at Release)
  • Layer 3 — historical AI comparison (Release; uses archived Price Books and completed estimates)
  1. Snapshot divergence: Worksheet Resources that carry snapshots older than their Resource’s current rate (e.g., post-PBA award) are flagged with a “push through” action.
  2. Estimators resolve or dismiss flags one by one. Each Item needs its flags resolved before being marked Reviewed.
  3. Lead Estimator marks each Item as Reviewed. When every Item in the Estimate is Reviewed, the Estimate’s own status automatically transitions to Reviewed.

Cascade reminder: If a rate edit happens after Reviewed, affected Items drop back to Priced and the Estimate reverts to In Progress. Review must be re-done for those Items.

Exits:

  • Estimate is Reviewed and clean of outstanding flags (or flags are deliberately accepted).
  • No Item is Unpriced or Plugged (required by the Submit gate).

8. Stage 7 — Publish

Goal: Generate the client-submittable artifact and lock the Estimate.

Who: Lead Estimator (primary); Admin can also publish.

What happens:

  1. Lead Estimator opens the Publisher view. They see a preview of the submission: Schedule structure, Submission Values per Schedule Item, applied branding, cover letter, conditions, inclusions, exclusions.
  2. They edit the cover letter, conditions, and preamble content as needed. Branding comes from the admin-managed branding config.
  3. They pick a file format (PDF / Excel; extensible).
  4. They hit Publish.
  5. The Submit gate runs: if any Item is Unpriced or Plugged, the Publish action surfaces an anomaly list and blocks the transition. Otherwise:
  • Publisher Output transitions Draft → Published
  • A schedule_snapshot is frozen (JSON record of Schedule structure + Submission Values at publish time)
  • Estimate transitions Reviewed → Submitted
  • All child Items cascade to Locked
  • Tender transitions Active → Submitted (if this is the first publish on that Tender)

Only the latest Publisher Output is retained per Estimate. Republishing replaces the prior record.

See sub-flows/commercials.md §Publisher.

Exits:

  • Published artifact is downloadable and ready to send to the client.
  • Estimate is read-only. Adjudications are frozen.

9. Stage 8 — Outcome

Goal: Record the client decision; cascade to related records.

Who: Admin or Lead Estimator.

What happens:

  • Won: Manual transition on Tender → Won. The submitted Estimate stays Submitted (as the winning version). All other Estimates on the Tender → Archived. The kept Estimate is then promoted to a project — the Workbench integration kicks in (downstream, outside Estimate scope).
  • Lost: Manual transition on Tender → Lost. All Estimates → Archived.
  • Withdrawn / not pursued: Manual transition on Tender → Archived. All Estimates → Archived.

Archived Estimates remain viewable (read-only) for audit and retrospective. Admin-only recovery is available for rare cases.

Exits:

  • Tender is in a terminal state; no further transitions via the state machine.

10. Collaboration throughout

All stages support concurrent editing of the same Estimate with explicit per-Item locks:

  • When a User begins editing an Item (or any of its Worksheet children), the Item is locked to other Users. They see “currently edited by [User]” and read-only view of that Item.
  • Concurrent editing on different Items is unrestricted.
  • Lock releases on User exit, idle timeout (default 10 min, admin-configurable), or Admin override.

🟡 Oxcon to confirm the locking model vs. field-level concurrent editing.


11. Where each Role lives in the journey

Drawn from foundation/roles-permissions.md.

StageAdminLead EstimatorEstimator
1 · Opportunity intake✅ create / edit Tender✅ create / edit Tender— (read-only on Tender metadata)
2 · Structure EstimateCreate / edit Items only
3 · Item build-up✅ (primary actor)
4 · Procurement✅ (can run, edit, lock adjudications)
5 · CommercialsRead-only (view totals; cannot edit Rules or overrides)
6 · Review & sign-off✅ (sign-off authority)Triage own Items (run Anomaly Review, resolve / dismiss flags)
7 · PublishPreview only
8 · Outcome

12. Cross-Tender activities (not journey-linear)

A handful of activities happen alongside the per-Tender journey rather than inside it:

  • Recipe Library curation — creating, editing, and retiring Recipes in the workspace-wide library. Lives under Admin / Price Library navigation.
  • Price Book management — maintaining External and Internal Price Books, refreshing rates, archiving expired books. Not Tender-scoped.
  • Admin lookups — Units, Categorizations, Flag Catalog, Modifier Catalog, Codes (including sync config), Reference Rates, Content Block Definitions, Branding, Integrations.
  • Integrations — Xero sync (Companies), M365 sync (Users), Workbench export (on project promotion).

These are surfaced in the view inventory and navigation map but don’t belong to a specific Tender.