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:
- 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.
- 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. - 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:
- 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. - 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.
- 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.
- Item status starts at
Unpriced(empty Worksheet, noplug_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_rateand 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_rate→Unpriced - Empty Worksheet +
plug_rateset →Plugged - Worksheet has cost-contributing content →
Priced
Exits:
- All (or most) Items are
Priced(or deliberatelyPluggedfor 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:
- Lead Estimator opens the Commercials view for the Estimate.
- 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).
- 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.
- The system computes a Submission Value per Schedule Item. Lead Estimator can override any Submission Value with an explicit value + optional audit note.
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:
- 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)
- 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.
- Estimators resolve or dismiss flags one by one. Each Item needs its flags resolved before being marked Reviewed.
- Lead Estimator marks each Item as
Reviewed. When every Item in the Estimate is Reviewed, the Estimate’s own status automatically transitions toReviewed.
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
Reviewedand clean of outstanding flags (or flags are deliberately accepted). - No Item is
UnpricedorPlugged(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:
- 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.
- They edit the cover letter, conditions, and preamble content as needed. Branding comes from the admin-managed branding config.
- They pick a file format (PDF / Excel; extensible).
- They hit Publish.
- The Submit gate runs: if any Item is
UnpricedorPlugged, the Publish action surfaces an anomaly list and blocks the transition. Otherwise:
- Publisher Output transitions
Draft → Published - A
schedule_snapshotis 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 staysSubmitted(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.
| Stage | Admin | Lead Estimator | Estimator |
|---|---|---|---|
| 1 · Opportunity intake | ✅ create / edit Tender | ✅ create / edit Tender | — (read-only on Tender metadata) |
| 2 · Structure Estimate | ✅ | ✅ | Create / edit Items only |
| 3 · Item build-up | ✅ | ✅ | ✅ (primary actor) |
| 4 · Procurement | ✅ | ✅ | ✅ (can run, edit, lock adjudications) |
| 5 · Commercials | ✅ | ✅ | Read-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 · Publish | ✅ | ✅ | Preview 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.