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.
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โ
Inheritance Rulesโ
| Property | Inherited | Overridable |
|---|---|---|
| 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 |
Shape and name are NOT inherited โ each scope must have its own identity. Only dimensional and material properties are inherited.
Creating Linked Scopesโ
Create a "template" parent scope with standard dimensions:
- Navigate to bid detail page
- Click "Add Scope"
- Enter scope name (e.g., "Foundation Pad Template")
- Select shape (Slab, Cylinder, etc.)
- Enter dimensions:
- Length: 20 ft
- Width: 20 ft
- Depth: 1.5 ft
- Click "Save"
Create a child scope that will inherit from the parent:
- Click "Add Scope" again
- Enter scope name (e.g., "Pad A - North Corner")
- Select shape (should match parent for consistency)
- Leave dimensions empty for now (will inherit)
- Click "Save"
Link the child scope to the parent:
- Open the child scope (Pad A)
- Click the "Link to Parent" button
- Select parent scope from dropdown: "Foundation Pad Template"
- Configure inheritance settings:
- โ Inherit dimensions
- โ Inherit rebar waste override
- Click "Link"
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:
- Override Dimensions
- Override Rebar Waste
- Revert to Parent
Scenario: Pad B is larger than the template.
Steps:
- Open child scope (Pad B)
- Click "Edit"
- Change dimensions:
- Length: 25 ft (override)
- Width: 25 ft (override)
- Depth: 1.5 ft (inherited)
- Click "Save"
Result:
- Pad B now has custom dimensions
- Still linked to parent (can revert later)
- Other properties still inherited
Scenario: Pad C has difficult site access, needs higher waste percentage.
Steps:
- Open child scope (Pad C)
- Click "Edit"
- Change rebar waste override:
- Rebar Waste: 10% (override)
- Click "Save"
Result:
- Pad C uses 10% rebar waste (instead of parent's 5%)
- Dimensions still inherited
Scenario: Undo override and revert to parent's value.
Steps:
- Open child scope
- Click "Edit"
- Clear the overridden field (leave blank)
- Click "Save"
Result:
- Child scope re-inherits parent's value
- Link remains active
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:
Navigate to the child scope you want to unlink.
Click the "Unlink from Parent" button.
A confirmation modal appears:
"Unlinking will preserve current values but stop inheritance. Continue?"
Click "Unlink".
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
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โ
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
Edit parent scope dimensions:
- Length: 22 ft (updated)
- Width: 20 ft
- Depth: 1.5 ft
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
All child scopes trigger cost recalculation:
- Concrete items recalculate based on new cubic yards
- Scope totals update
- Bid total updates
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.
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:
| Rule | Description | Error Message |
|---|---|---|
| No Self-Linking | A scope cannot be linked to itself | "A scope cannot be linked to itself" |
| Same Bid Only | Parent and child must be in the same bid | "Scopes must be in the same bid" |
| No Multi-Level | Parent cannot have its own parent | "Only single-level hierarchy is allowed" |
| No Circular References | Parent 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โ
Link Scope to Parentโ
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
}
Unlink Scope from Parentโ
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:
- Create parent: "Foundation Pad Standard" (20ร20ร1.5 ft)
- Create 10 child scopes, link all to parent
- Override dimensions for the 2 larger pads
- 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:
- Create parent: "Parking Bay Template" (9ร18ร0.5 ft)
- Create 20 child scopes:
- Bay 1-5 (Phase 1)
- Bay 6-10 (Phase 2)
- Bay 11-15 (Phase 3)
- Bay 16-20 (Phase 4)
- All bays inherit dimensions
- 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:
- Create parent: "Driveway Section" (custom dimensions)
- Create 3 child scopes, link to parent
- Override dimensions for each child (different lengths)
- Add concrete items to parent โ children inherit mix design
- 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:
- Pick one scope as the "template" parent
- For each other scope:
- Link to parent
- Clear dimension fields (to inherit)
- Verify dimensions match parent
- Delete duplicate dimensions, keep only parent
- Future updates only need parent changes
Troubleshootingโ
Common Issuesโ
| Issue | Cause | Solution |
|---|---|---|
| Can't link scopes | Scopes in different bids | Move scopes to same bid or unlink |
| Parent has children, can't link | Attempting multi-level hierarchy | Unlink children first, then link |
| Child not updating | Property overridden in child | Clear child property to re-inherit |
| Circular reference error | Attempting to link parent to child | Check link direction |
Future Enhancementsโ
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