1. Purpose

A Categorization is a user-defined, flexible tagging system for reporting and slicing. Categorizations are purely optional (unlike Codes, which are required for integration) and never affect system behaviour — they are strictly reporting-only. Items, Resources, Tenders, and Estimates can be tagged with Categorization Options, enabling cross-cutting analysis (e.g., “total cost by Trade”, “all Electrical work across items and resources”).

Analogy (glossary cooking model): Categorizations are labels on ingredients and finished dishes — you can organize and report on them, but labeling doesn’t change how the cooking works.

Contrast with Codes (BR-125):

  • Categorization = optional, reporting-only, never affects behaviour
  • Code = required, integration-linked, blocks downstream systems if missing

2. Attributes

Categorization (Container)

AttributeTypeRequiredDefaultNotes
idUUIDgeneratedSystem-managed
namestring (short text)The Categorization name, e.g., “Trade”, “Project Phase”, “Region”. Shown in UI and reports
scopemulti-select enumEntity types this Categorization applies to: any combo of Item / Resource / Tender / Estimate. See §3
descriptionstring (long text)nullAdmin notes on the Categorization’s purpose and usage
created_at / updated_attimestampsystemAudit
created_by / updated_byUser refsystemAudit

Categorization Option (Value)

AttributeTypeRequiredDefaultNotes
idUUIDgeneratedSystem-managed
categorization_idUUID refParent Categorization. Every Option belongs to exactly one Categorization
valuestring (text)The internal code/identifier, e.g., “concrete”, “electrical”, “auckland”. Used in data exports and APIs
display_labelstring (text)The human-readable label shown in UI, e.g., “Concrete Works”, “Electrical”, “Auckland”. Can differ from value for readability
colourpredefined palette OR hex codenullOptional colour: either a predefined palette entry (e.g., “primary-blue”, “accent-orange”) OR a custom hex code (e.g., #FF5733). Used in visualizations and reports
archived_attimestampnullSoft-delete marker. If populated, this Option is archived; visible on historical entities but unavailable for new selections. Can be un-archived (restored). Per BR-120a (no hard-delete)
display_orderintegerautoOrder within parent Categorization
created_at / updated_attimestampsystemAudit
created_by / updated_byUser refsystemAudit

3. Scope

A Categorization’s scope is a multi-select flag that defines which entity types it applies to. A single Categorization can apply to multiple entity types.

Scope OptionMeaningNotes
ItemOptions can be assigned to Items in an EstimateEnables filtering/reporting on Item categories across the build-up
ResourceOptions can be assigned to Resources in Price BooksEnables filtering/reporting on Resource categories (e.g., “Concrete Resources in this Tender”)
TenderOptions can be assigned to TendersEnables portfolio-level categorization (e.g., “Infrastructure projects”)
EstimateOptions can be assigned to EstimatesEnables categorization at the estimate level (e.g., “base case” vs “value engineered”)

Flexibility: a single Categorization can have scope = [Item, Resource]. This allows the same “Trade” (Concrete, Steel, Electrical) to tag both Items and Resources, enabling unified reporting across the cost model (e.g., “total steel cost across all items and resources”).


4. Relationships

Inbound (things referring to Categorization)

FromCardinalityNotes
Categorization OptionCatOption M:1 CategorizationEvery Option belongs to exactly one Categorization (parent); a Categorization has many Options
ItemItem M:M CatOptionIf Categorization scope includes Item. Sub-Items inherit parent’s Categorization Options at creation; estimator can override (see §4 Inheritance)
ResourceResource M:M CatOptionIf Categorization scope includes Resource
TenderTender M:M CatOptionIf Categorization scope includes Tender
EstimateEstimate M:M CatOptionIf Categorization scope includes Estimate
RuleRule M:M CatOptionFor Commercials Rule scoping (BR-073): a Rule can target “all costs tagged with Categorization Option X”
Reference RateRefRate M:0..1 CatOptionOptional scope: a Reference Rate can be scoped to a specific Categorization Option (BR-145)

Outbound (things Categorization references)

ToCardinalityRequiredNotes
Categorization OptionCategorization 1:M CatOptionEvery Categorization has at least one Option

Inheritance (sub-Items)

When a sub-Item is created under a parent Item, the sub-Item inherits the parent’s Categorization Options at creation time:

  • Sub-Item is automatically tagged with the same Categorization Options as its parent.
  • Estimator can override: the Estimator can modify, remove, or add Categorization Options on the sub-Item immediately after creation.
  • No retroactive propagation: Changes to the parent’s Categorization Options after the sub-Item is created do not retroactively update the sub-Item’s tags. Inheritance is one-time, at creation only.
  • This enables consistency across work breakdowns while preserving local control at the sub-Item level.

5. Validation / Invariants

Rules that must hold at all times:

  1. Categorization scope non-empty. scope must contain at least one entity type (Item / Resource / Tender / Estimate). Cannot be empty.
  2. Option belongs to exactly one Categorization. Every Categorization Option has a parent Categorization; no orphaned Options.
  3. Unique value within Categorization. Within a single Categorization, value must be unique (case-sensitive). Different Categorizations can have Options with the same value.
  4. Colour format (if present). If colour is populated, it must be either a predefined palette entry (e.g., “primary-blue”) OR a valid hex colour code (e.g., #FF5733, #000). Freeform colour names (e.g., “red”, “blue”) are not permitted.
  5. At least one Option per Categorization. A Categorization must have at least one Option to be usable. Deleting the last Option is prevented (or Categorization is soft-deleted).

6. Bulk tagging

Supported: Users can select multiple Items or Resources and apply the same Categorization Option in one action. This is a UX feature (not a data model rule) that improves efficiency for large estimates:

  • Estimator selects a list of Items or Resources (checkbox multi-select).
  • Estimator chooses a Categorization Option from a dropdown.
  • System applies that single Categorization Option tag to all selected entities in one batch operation.
  • Each entity’s existing Categorization Options are preserved; the new Option is added.
  • Example: select 15 Items that are all “Electrical work” and tag them with the “Electrical” Trade option in one click.

7. Usage patterns

Pattern A — Trade Categorization (Items + Resources)

A single Categorization applies to both Items and Resources, enabling unified reporting across the cost build-up.

Categorization: "Trade"
  scope: [Item, Resource]
  Options:
    - value: "concrete" / display_label: "Concrete Works" / colour: #4A7BA7
    - value: "steel" / display_label: "Structural Steel" / colour: #C0504D
    - value: "electrical" / display_label: "Electrical Systems" / colour: #FFC000
    - value: "mechanical" / display_label: "Mechanical Systems" / colour: #70AD47
    - value: "finishes" / display_label: "Finishes" / colour: #92278F

Usage:
  - Item "Supply and place concrete to piers" → tagged with "Concrete Works" Option
  - Item "Install electrical cabling" → tagged with "Electrical Systems" Option
  - Resource "Ready-mix concrete (35MPa)" → tagged with "Concrete Works" Option
  - Resource "Electrician — general (Auckland)" → tagged with "Electrical Systems" Option

Report: "Total Concrete cost (Items + Resources)" = $280,000
Report: "Cost by Trade across all Items and Resources" = breakdown across Concrete, Steel, etc.

Pattern B — Project Phase Categorization (Items only)

A Categorization scoped to Items only, used to drive time-based cost distribution linked to a Tender Program.

Categorization: "Project Phase"
  scope: [Item]
  Options:
    - value: "mobilisation" / display_label: "Mobilisation" / colour: #FFEB9C
    - value: "earthworks" / display_label: "Earthworks" / colour: #A9D08E
    - value: "structures" / display_label: "Structures" / colour: #B4C7E7
    - value: "finishes" / display_label: "Finishes" / colour: #F8CBAD

Usage:
  - Item "Site setup and accommodation" → tagged with "Mobilisation"
  - Item "Excavation and pile driving" → tagged with "Earthworks"
  - Item "Concrete pour — structural frame" → tagged with "Structures"
  - Item "Painting and cladding" → tagged with "Finishes"

Commercials Rule: "Apply schedule of values by phase" → targets Project Phase Options to drive time-based cost distribution linked to Program Tasks.

Pattern C — Regional Categorization (Resources only)

A Categorization scoped to Resources, enabling regional rate analysis.

Categorization: "Region"
  scope: [Resource]
  Options:
    - value: "auckland" / display_label: "Auckland" / colour: #0099FF
    - value: "wellington" / display_label: "Wellington" / colour: #FF6600
    - value: "christchurch" / display_label: "Christchurch" / colour: #00CC00

Usage:
  - Resource "Carpenter day rate (Auckland region)" → tagged with "Auckland" Option
  - Resource "Concrete supply (Wellington depot)" → tagged with "Wellington" Option
  - Resource "Scaffolding (Christchurch hires)" → tagged with "Christchurch" Option

Report: "Labour rates by region" = identifies regional rate variations across the Estimate.
Reference Rate: "Concrete works — Auckland" can be scoped to the "Auckland" Option.

7. Lifecycle and permissions

Admin & Lead Estimator

  • Admin (per BR-085) can create, edit, rename, and archive Categorizations and their Options. Hard-delete is not supported (BR-120a); archiving is the only removal path. Categorizations are system-wide; admin is the gate-keeper to prevent proliferation of conflicting taxonomies.
  • Lead Estimator can assign Categorization Options to Items and Resources within their Estimate (read: no special restriction; same as any Estimator under BR-095 per-Item locking).
  • Estimator can assign Categorization Options to Items they are editing; cannot edit Categorization definitions.

Soft-delete (Archive) lifecycle

Categorizations and Options support soft-delete (archive) rather than hard delete:

  • When a Categorization or Option is archived, it is marked with archived_at timestamp.
  • Archived items remain visible on all historical Tenders, Items, and Resources that used them, preserving audit and reporting integrity.
  • Archived items are unavailable for new selections (UI/API filters exclude archived Options from dropdowns and selectors).
  • Un-archive allowed: Archived Categorizations and Options can be restored by clearing the archived_at timestamp, making them available for new selections again.
  • No hard delete is supported; deletion is always soft (archive).

8. Worked Examples

Example A — Trade across Items and Resources with bulk tagging

Setup (Admin):

Categorization "Trade":
  scope: [Item, Resource]
  Options:
    1. "concrete" → Concrete Works
    2. "steel" → Structural Steel
    3. "electrical" → Electrical
    4. "mechanical" → Mechanical

Price Book "Materials Q2 2026":
  - Resource "Ready-mix concrete 35MPa" → tagged "concrete"
  - Resource "Reinforcement steel 500MPa" → tagged "steel"
  - Resource "PVC conduit DN20" → tagged "electrical"

Estimate "Bridge rebuild":
  - Item "Concrete pier caps (12×1.5m)" → tagged "concrete"
  - Item "Structural steel frame" → tagged "steel"
  - Item "Electrical distribution board & cabling" → tagged "electrical"

Reporting:

  • “Total Concrete cost (Items + Resources)” = Item cost + Material Resource cost
  • “Cost breakdown by Trade” = pie chart of Concrete / Steel / Electrical / Mechanical
  • “Anomaly Review: Reference Rate matching” = Concrete items checked against “Concrete Reference Rate” (optionally scoped to “Concrete” Option)

Example B — Project Phase for Schedule of Values

Setup (Admin):

Categorization "Project Phase":
  scope: [Item]
  Options:
    1. "mobilisation" → Mobilisation
    2. "earthworks" → Earthworks
    3. "structures" → Structures
    4. "finishes" → Finishes

Estimate "Infrastructure project":
  - Item "Site accommodation + safety setup" → "mobilisation"
  - Item "Excavation (19,000m³)" → "earthworks"
  - Item "Concrete slab (2,500m²)" → "structures"
  - Item "Painting + cladding" → "finishes"

Tender Program linked to Estimate:
  - Task "Mobilisation" (weeks 1–2)
  - Task "Earthworks" (weeks 3–8)
  - Task "Concrete pour" (weeks 9–14)
  - Task "Finishes" (weeks 15–20)

Commercials Rule "Schedule of Values by Phase":
  - Scope: Categorization Option "mobilisation" → 5% cumulative
  - Scope: Categorization Option "earthworks" → 25% cumulative
  - Scope: Categorization Option "structures" → 75% cumulative
  - Scope: Categorization Option "finishes" → 100% cumulative

Effect:

  • Client schedule of values driven by phase categories, linked to program timeline.
  • Cost is not affected by Categorization (BR-120) — the Rule uses Categorization as a scoping target, not a cost modifier.

Example D — Multi-Categorization on one entity

Setup:

Categorization "Trade": [concrete, steel, electrical]
Categorization "Supplier Tier": [preferred, alternative, budget]
Categorization "Risk Level": [low, medium, high]

Resource "Subcontractor — ABC Concrete (preferred, low-risk)":
  - Trade: "concrete"
  - Supplier Tier: "preferred"
  - Risk Level: "low"

Reporting:

  • “Preferred suppliers’ cost” = filter by Supplier Tier = “preferred”
  • “Concrete cost from preferred suppliers” = filter by Trade = “concrete” AND Supplier Tier = “preferred”
  • “High-risk costs” = filter by Risk Level = “high” (for risk review)