Skip to main content

Scopes

Overview

Scopes represent the work breakdown structure within a bid (e.g., "Foundation", "Grade Beam", "Slab"). Each scope contains estimation items across six modules and can have a parent-child hierarchy.

Base Operations

List Scopes for Bid

GET /api/scopes/bid/:bidId
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Get Scope

GET /api/scopes/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Create Scope

POST /api/scopes
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"bidId": "uuid",
"name": "Grade Beam",
"typeId": "uuid",
"multiplier": 1.0
}

Roles: ADMIN, ESTIMATOR

Required Fields:

  • bidId (string, UUID) - Parent bid
  • name (string) - Scope name
  • typeId (string, UUID) - Scope type (required as of BM-39)

Optional Fields:

  • multiplier (number, default: 1.0) - Cost scaling factor for repeated scopes

Update Scope

PUT /api/scopes/:id
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"name": "Updated Scope Name",
"multiplier": 2.0
}

Roles: ADMIN, ESTIMATOR


Delete Scope

DELETE /api/scopes/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR

warning

Deleting a scope will cascade delete all associated items (concrete, labor, equipment, materials, subcontractor, misc).


Batch Update Scope Positions

PATCH /api/scopes/bid/:bidId/batch
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"scopes": [
{ "id": "uuid1", "position": 0 },
{ "id": "uuid2", "position": 1 },
{ "id": "uuid3", "position": 2 }
]
}

Roles: ADMIN, ESTIMATOR (owner only)

info

Use this endpoint to reorder scopes within a bid. This is useful for drag-and-drop UI implementations.

Scope Types

Get Required Material Categories

GET /api/scopes/:id/required-material-categories
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM

Fallback Behavior:

  • If scope has no type assigned → returns ALL categories with isFallback: true
  • If scope type has no categories configured → returns ALL categories with isFallback: true
  • Used by Materials module to display "missing category" chips

Scope Hierarchy

PUT /api/scopes/:id/link
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"parentScopeId": "uuid",
"inheritanceSettings": {
"concreteDimensions": {
"enabled": true,
"inheritLength": true,
"inheritWidth": true,
"inheritDepth": true
},
"materials": {
"enabled": false
},
"rebar": {
"enabled": false
}
}
}

Roles: ADMIN, ESTIMATOR

Constraints:

  • Single-level hierarchy only (parent cannot have parent)
  • Must be within same bid
  • One parent per scope
  • Circular reference prevention

PUT /api/scopes/:id/unlink
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR


Get Scope Hierarchy

GET /api/scopes/:id/hierarchy
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Get All Scopes with Hierarchy

GET /api/scopes/bid/:bidId/hierarchy
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR, PM


Update Inheritance Settings

PUT /api/scopes/:id/inheritance
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"concreteDimensions": {
"enabled": true,
"inheritLength": true,
"inheritWidth": false,
"inheritDepth": true
}
}

Roles: ADMIN, ESTIMATOR


Sync Child with Parent

PUT /api/scopes/:id/sync
Cookie: sAccessToken=...; sRefreshToken=...

Roles: ADMIN, ESTIMATOR

Applies current inheritance settings to sync data from parent.

Data Model

interface Scope {
id: string; // UUID
bidId: string; // Parent bid UUID
typeId: string; // Scope type UUID (required)
name: string; // Scope name
multiplier: number; // Cost scaling factor (default: 1.0)

// Dimensions (optional, for concrete calculations)
shape: string | null; // RECTANGLE, CIRCULAR, etc.
length: number | null;
width: number | null;
height: number | null;
diameter: number | null;
cubicYards: number | null;

// Cost Totals (read-only, auto-calculated)
concreteCost: number;
laborCost: number;
equipmentCost: number;
materialCost: number;
subcontractorCost: number;
miscCost: number;
totalCost: number;

// Hierarchy
parentScopeId: string | null;
inheritanceSettings: InheritanceSettings | null;
lastSyncedAt: DateTime | null;

// Relations
scopeType: ScopeType;
parent: Scope | null;
children: Scope[];
concreteItems: ConcreteItem[];
laborItems: LaborItem[];
equipmentItems: EquipmentItem[];
materialItems: MaterialItem[];
subcontractorItems: SubcontractorItem[];
miscItems: MiscItem[];
}

interface InheritanceSettings {
concreteDimensions?: {
enabled: boolean;
inheritLength: boolean;
inheritWidth: boolean;
inheritDepth: boolean;
};
materials?: {
enabled: boolean;
};
rebar?: {
enabled: boolean;
};
}

Multiplier

The multiplier field scales all costs within a scope. Useful for repeated scopes (e.g., "Grade Beam x 4").

Example:

  • Scope has $10,000 in items
  • Multiplier set to 4.0
  • Scope totalCost = $40,000