Skip to main content

Scope Linking

Scope linking allows you to create parent-child relationships between scopes, enabling child scopes to inherit dimensions, materials, and other properties from a parent scope. This dramatically reduces data entry for repeated work areas with similar characteristics.

info

Scope linking is single-level only โ€” a parent scope cannot have its own parent. This keeps the hierarchy simple and predictable.


Use Casesโ€‹

๐Ÿ—‚๏ธ

Repeated Elements

Multiple foundation pads with the same dimensions but different locations

๐Ÿ“

Standardized Work

Driveway sections that all use the same mix design and rebar specs

๐Ÿ“š

Phased Construction

Parking lot bays with identical dimensions but built in separate phases

๐Ÿงฑ

Material Consistency

Ensure child scopes use the same concrete mix, rebar, and formwork as parent


How Scope Linking Worksโ€‹

Parent-Child Relationshipโ€‹

๐Ÿ” Click diagram to expand

Inheritance Rulesโ€‹

PropertyInheritedOverridable
Lengthโœ… Yesโœ… Yes
Widthโœ… Yesโœ… Yes
Height/Depthโœ… Yesโœ… Yes
Diameterโœ… Yesโœ… Yes
Cubic Yardsโœ… Yes (auto-calculated)โŒ No (derived)
Rebar Waste Overrideโœ… Yesโœ… Yes
ShapeโŒ NoโŒ No
NameโŒ NoโŒ No
note

Shape and name are NOT inherited โ€” each scope must have its own identity. Only dimensional and material properties are inherited.


Creating Linked Scopesโ€‹

1
Create Parent Scope

Create a "template" parent scope with standard dimensions:

  1. Navigate to bid detail page
  2. Click "Add Scope"
  3. Enter scope name (e.g., "Foundation Pad Template")
  4. Select shape (Slab, Cylinder, etc.)
  5. Enter dimensions:
    • Length: 20 ft
    • Width: 20 ft
    • Depth: 1.5 ft
  6. Click "Save"
2
Create Child Scope

Create a child scope that will inherit from the parent:

  1. Click "Add Scope" again
  2. Enter scope name (e.g., "Pad A - North Corner")
  3. Select shape (should match parent for consistency)
  4. Leave dimensions empty for now (will inherit)
  5. Click "Save"
3
Link Child to Parent

Link the child scope to the parent:

  1. Open the child scope (Pad A)
  2. Click the "Link to Parent" button
  3. Select parent scope from dropdown: "Foundation Pad Template"
  4. Configure inheritance settings:
    • โœ… Inherit dimensions
    • โœ… Inherit rebar waste override
  5. Click "Link"
4
Verify Inheritance

Check that child scope now has parent's dimensions:

  • Child scope shows: Length 20 ft, Width 20 ft, Depth 1.5 ft
  • Cubic yards auto-calculated: 1.11 CY
  • Badge shows: "Linked to: Foundation Pad Template"

Overriding Inherited Propertiesโ€‹

Child scopes can override any inherited property:

Scenario: Pad B is larger than the template.

Steps:

  1. Open child scope (Pad B)
  2. Click "Edit"
  3. Change dimensions:
    • Length: 25 ft (override)
    • Width: 25 ft (override)
    • Depth: 1.5 ft (inherited)
  4. Click "Save"

Result:

  • Pad B now has custom dimensions
  • Still linked to parent (can revert later)
  • Other properties still inherited
warning

Overriding a property breaks inheritance for that property only. To re-inherit, clear the field (set to blank/null).


Unlinking Scopesโ€‹

To remove the parent-child relationship:

1
Open Child Scope

Navigate to the child scope you want to unlink.

2
Click Unlink

Click the "Unlink from Parent" button.

3
Confirm Unlinking

A confirmation modal appears:

"Unlinking will preserve current values but stop inheritance. Continue?"

Click "Unlink".

4
Verify Unlinking

Child scope is now independent:

  • Current dimensions are preserved (frozen at last inherited values)
  • Link badge removed
  • Future parent changes won't affect this scope
note

Unlinking preserves current values โ€” it doesn't delete data. The child scope keeps its current dimensions but becomes independent.


Updating Parent Scopesโ€‹

When you update a parent scope, all linked child scopes update automatically:

Example Flowโ€‹

1
Initial State

Parent Scope (Foundation Pad Template):

  • Length: 20 ft
  • Width: 20 ft
  • Depth: 1.5 ft

Child Scopes (Pad A, B, C):

  • All inherit: 20 ร— 20 ร— 1.5 ft
  • Cubic Yards: 1.11 CY each
2
Update Parent

Edit parent scope dimensions:

  • Length: 22 ft (updated)
  • Width: 20 ft
  • Depth: 1.5 ft
3
Children Auto-Update

Child Scopes (Pad A, B, C) now show:

  • Length: 22 ft (inherited from parent)
  • Width: 20 ft
  • Depth: 1.5 ft
  • Cubic Yards: 1.22 CY (recalculated)

Unless overridden:

  • If Pad B had a custom length, it keeps its custom value
  • If Pad C inherited everything, it updates to 22 ft
4
Cost Rollup Triggered

All child scopes trigger cost recalculation:

  • Concrete items recalculate based on new cubic yards
  • Scope totals update
  • Bid total updates
info

Linked scopes update in real-time when parent changes. No manual refresh needed.


Single-Level Hierarchy Onlyโ€‹

ForgeX enforces single-level hierarchy to keep relationships simple:

โœ… Allowed:
Parent Scope
โ”œโ”€โ”€ Child Scope A
โ”œโ”€โ”€ Child Scope B
โ””โ”€โ”€ Child Scope C

โŒ Not Allowed:
Parent Scope
โ””โ”€โ”€ Child Scope A
โ””โ”€โ”€ Grandchild Scope (NOT SUPPORTED)

Why Single-Level?โ€‹

Simplicity

Multi-level hierarchies introduce complexity:

  • Which properties override which?
  • How do changes propagate through multiple levels?
  • What happens if middle parent is deleted?

Single-level avoids these issues.

Predictability

With single-level:

  • Changes flow in one direction: Parent โ†’ Child
  • No cascading inheritance chains
  • Easy to visualize and debug
Performance

Multi-level hierarchies require recursive queries:

  • Slow database lookups
  • Complex cost rollup calculations
  • Potential for circular references

Single-level is fast and efficient.

warning

Attempting to link a scope that already has children will fail with an error: "Parent scope cannot have its own parent."


Validation Rulesโ€‹

ForgeX enforces these rules when linking scopes:

RuleDescriptionError Message
No Self-LinkingA scope cannot be linked to itself"A scope cannot be linked to itself"
Same Bid OnlyParent and child must be in the same bid"Scopes must be in the same bid"
No Multi-LevelParent cannot have its own parent"Only single-level hierarchy is allowed"
No Circular ReferencesParent cannot be a child of the child"Cannot create circular reference"

API Validationโ€‹

const { validateLinking } = require('../services/scopeLinkingService');

// Before linking
const validation = await validateLinking(childScopeId, parentScopeId);

if (!validation.valid) {
return res.status(400).json({ error: validation.error });
}

// Proceed with linking

Viewing Linked Scopesโ€‹

Parent Scope Viewโ€‹

Parent scopes show a list of linked children:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Foundation Pad Template Editโ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Length: 20 ft โ”‚
โ”‚ Width: 20 ft โ”‚
โ”‚ Depth: 1.5 ft โ”‚
โ”‚ Cubic Yards: 1.11 CY โ”‚
โ”‚ โ”‚
โ”‚ ๐Ÿ”— Linked Children: 3 โ”‚
โ”‚ โ€ข Pad A - North Corner โ”‚
โ”‚ โ€ข Pad B - South Corner โ”‚
โ”‚ โ€ข Pad C - East Wing โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Child Scope Viewโ€‹

Child scopes show their parent link:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Pad A - North Corner Editโ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ ๐Ÿ”— Linked to: Foundation Pad โ”‚
โ”‚ Template [Unlink]โ”‚
โ”‚ โ”‚
โ”‚ Length: 20 ft (inherited) โ”‚
โ”‚ Width: 20 ft (inherited) โ”‚
โ”‚ Depth: 1.5 ft (inherited) โ”‚
โ”‚ Cubic Yards: 1.11 CY โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

API Endpointsโ€‹

POST /api/scopes/:scopeId/link

Request Body:
{
"parentScopeId": "parent-scope-uuid"
}

Response:
{
"id": "child-scope-uuid",
"parentScopeId": "parent-scope-uuid",
"length": 20, // Inherited
"width": 20, // Inherited
"depth": 1.5 // Inherited
}
DELETE /api/scopes/:scopeId/link

Response:
{
"id": "child-scope-uuid",
"parentScopeId": null,
"length": 20, // Preserved (no longer inherited)
"width": 20, // Preserved
"depth": 1.5 // Preserved
}

Get Linked Childrenโ€‹

GET /api/scopes/:scopeId/children

Response:
[
{
"id": "child-1-uuid",
"name": "Pad A - North Corner",
"length": 20,
"width": 20
},
{
"id": "child-2-uuid",
"name": "Pad B - South Corner",
"length": 25, // Overridden
"width": 25 // Overridden
}
]

Best Practicesโ€‹

๐Ÿท๏ธ

Name Templates Clearly

Use names like "Foundation Pad Template" or "Driveway Bay Standard" for parent scopes.

โฌ‡๏ธ

Start with Parent First

Create parent scope before children. It's easier to link during creation than retrofit later.

๐Ÿ“

Document Overrides

Add notes to child scopes explaining why they override parent properties.

๐Ÿ‘๏ธ

Review Before Unlinking

Unlinking is irreversible. Verify you want to break inheritance before proceeding.


Common Scenariosโ€‹

Multiple Foundation Pads

Scenario: 10 foundation pads, all 20ร—20ร—1.5 ft, but 2 are larger.

Steps:

  1. Create parent: "Foundation Pad Standard" (20ร—20ร—1.5 ft)
  2. Create 10 child scopes, link all to parent
  3. Override dimensions for the 2 larger pads
  4. If standard size changes, update parent โ†’ 8 scopes update automatically
Phased Parking Lot Bays

Scenario: 20 parking lot bays, built in 4 phases of 5 bays each.

Steps:

  1. Create parent: "Parking Bay Template" (9ร—18ร—0.5 ft)
  2. Create 20 child scopes:
    • Bay 1-5 (Phase 1)
    • Bay 6-10 (Phase 2)
    • Bay 11-15 (Phase 3)
    • Bay 16-20 (Phase 4)
  3. All bays inherit dimensions
  4. Use scope multipliers (5ร—) per phase if bays are identical
Driveway Sections with Consistent Mix

Scenario: 3 driveway sections, different dimensions, same concrete mix.

Steps:

  1. Create parent: "Driveway Section" (custom dimensions)
  2. Create 3 child scopes, link to parent
  3. Override dimensions for each child (different lengths)
  4. Add concrete items to parent โ†’ children inherit mix design
  5. If mix design changes, update parent โ†’ all children update
Converting Unlinked Scopes to Linked

Scenario: You have 5 scopes with duplicate dimensions. Retrofit them to use linking.

Steps:

  1. Pick one scope as the "template" parent
  2. For each other scope:
    • Link to parent
    • Clear dimension fields (to inherit)
    • Verify dimensions match parent
  3. Delete duplicate dimensions, keep only parent
  4. Future updates only need parent changes

Troubleshootingโ€‹

Common Issuesโ€‹

IssueCauseSolution
Can't link scopesScopes in different bidsMove scopes to same bid or unlink
Parent has children, can't linkAttempting multi-level hierarchyUnlink children first, then link
Child not updatingProperty overridden in childClear child property to re-inherit
Circular reference errorAttempting to link parent to childCheck link direction

Future Enhancementsโ€‹

note

Planned features for scope linking:

  • Bulk linking: Link multiple scopes to parent at once
  • Link inheritance toggles: Choose which properties to inherit per child
  • Visual hierarchy view: Tree view showing parent-child relationships
  • Template library: Save parent scopes as reusable templates
  • Multi-level hierarchy (optional): Configurable depth limit for complex projects

Next Stepsโ€‹