Skip to main content

Common Service Hierarchy Mistakes Reference

Purpose: Document anti-patterns and solutions for service hierarchy configuration.


Top 10 Hierarchy Mistakes

Mistake 1: Orphaned Child Services (No Parent)

Severity: CRITICAL

Description: Creating INVENTORY/ADDON/REGISTRY services without a parent service template.

Symptom:

  • Service appears in catalogue but cannot be activated
  • Error: "Parent service not found"
  • Service instance has NULL parent reference

Detection Query:

SELECT code, role, parent_service_template_id
FROM cat_service_template
WHERE role IN ('INVENTORY', 'ADDON', 'REGISTRY')
AND parent_service_template_id IS NULL;
Incorrect

Orphaned MSN service

{
code: 'SVC_MSN_STANDARD',
role: ServiceRole.INVENTORY,
parentServiceTemplate: null // ← Orphan!
}
Correct

MSN with parent

{
code: 'SVC_MSN_STANDARD',
role: ServiceRole.INVENTORY,
parentServiceTemplate: 'SVC_MOBILE_BASE'
}

Prevention:

  • Always set parent before saving service template
  • Validate parent exists with referential integrity
  • Use foreign key constraints in database

Mistake 2: Wrong Parent for Nested Services (NBN_AVC)

Severity: HIGH

Description: Assigning NBN_AVC to NBN_BASE instead of NBN_ACCESS.

Symptom:

  • NBN_AVC activates before NBN_ACCESS
  • Activation order violations
  • Service hierarchy displays incorrectly

Detection Query:

SELECT st.code, parent.code as parent_code
FROM cat_service_template st
JOIN cat_service_template parent ON st.parent_service_template_id = parent.id
WHERE st.code = 'SVC_NBN_AVC'
AND parent.code != 'SVC_NBN_ACCESS';
Incorrect

NBN_AVC parent = NBN_BASE

<update tableName="cat_service_template">
<column name="parent_service_template_id"
valueComputed="(SELECT id FROM cat_service_template WHERE code = 'SVC_NBN_BASE')" />
<where>code = 'SVC_NBN_AVC'</where>
</update>
Correct

NBN_AVC parent = NBN_ACCESS

<update tableName="cat_service_template">
<column name="parent_service_template_id"
valueComputed="(SELECT id FROM cat_service_template WHERE code = 'SVC_NBN_ACCESS')" />
<where>code = 'SVC_NBN_AVC'</where>
</update>

Prevention:

  • Document hierarchy diagrams before implementation
  • Use parent selection decision tree
  • Review nested services during code review

Mistake 3: PRIMARY Service with Parent

Severity: HIGH

Description: Assigning a parent to a PRIMARY (root) service.

Symptom:

  • Validation error during activation
  • Service cannot be purchased standalone
  • Hierarchy displays PRIMARY as child

Detection Query:

SELECT code, role, parent_service_template_id
FROM cat_service_template
WHERE role = 'PRIMARY'
AND parent_service_template_id IS NOT NULL;
Incorrect

PRIMARY with parent

{
code: 'SVC_MOBILE_BASE',
role: ServiceRole.PRIMARY,
parentServiceTemplate: 'SVC_SOME_OTHER'
}
Correct

PRIMARY with no parent

{
code: 'SVC_MOBILE_BASE',
role: ServiceRole.PRIMARY,
parentServiceTemplate: null
}

Prevention:

  • Enforce rule: role=PRIMARY ⇒ parent=null
  • Add database constraint
  • Validate during service template creation

Mistake 4: Wrong Role Assignment

Severity: HIGH

Description: Using wrong ServiceRole (e.g., ADDON for INVENTORY services).

Symptom:

  • Inventory not allocated (INVENTORY marked as ADDON)
  • Regulatory tracking missing (REGISTRY marked as ADDON)
  • Billing incorrect

Detection Query:

-- Find services with inventory fields but wrong role
SELECT code, role
FROM cat_service_template
WHERE (code LIKE '%MSN%' OR code LIKE '%SIM%' OR code LIKE '%DEVICE%')
AND role != 'INVENTORY';

-- Find registry services with wrong role
SELECT code, role
FROM cat_service_template
WHERE code LIKE '%REGISTRY%'
AND role != 'REGISTRY';
Incorrect

Device as ADDON

{
code: 'SVC_DEVICE_MODEM',
role: ServiceRole.ADDON // ← Should be INVENTORY
}
Correct

Device as INVENTORY

{
code: 'SVC_DEVICE_MODEM',
role: ServiceRole.INVENTORY
}

Prevention:

  • Use service role decision tree
  • Review role assignments during design
  • Validate role matches service characteristics

Mistake 5: Missing Lifecycle Inheritance Configuration

Severity: MEDIUM

Description: Child services not configured to inherit parent lifecycle events.

Symptom:

  • Parent suspends but children remain active
  • Parent terminates but children remain
  • Manual cleanup required

Detection Query:

SELECT code, inherit_parent_lifecycle
FROM cat_service_template
WHERE parent_service_template_id IS NOT NULL
AND (inherit_parent_lifecycle IS NULL OR inherit_parent_lifecycle = false);
Incorrect

No lifecycle inheritance

{
code: 'SVC_MOBILE_DATA_25GB',
parentServiceTemplate: 'SVC_MOBILE_BASE',
inheritParentLifecycle: false // ← Children remain after parent terminates
}
Correct

Lifecycle inheritance enabled

{
code: 'SVC_MOBILE_DATA_25GB',
parentServiceTemplate: 'SVC_MOBILE_BASE',
inheritParentLifecycle: true
}

Prevention:

  • Default inheritParentLifecycle = true
  • Document exceptions explicitly
  • Test parent termination flows

Mistake 6: Circular Dependencies in Constraints

Severity: HIGH

Description: Creating eligibility or activation constraints that create circular dependencies.

Symptom:

  • Infinite loop during eligibility evaluation
  • Stack overflow errors
  • Service activation hangs

Detection Query:

-- Detect direct circular dependencies
WITH RECURSIVE deps AS (
SELECT st.id, st.code, st.parent_service_template_id, 1 as depth
FROM cat_service_template st
UNION ALL
SELECT st.id, st.code, st.parent_service_template_id, deps.depth + 1
FROM cat_service_template st
JOIN deps ON st.parent_service_template_id = deps.id
WHERE deps.depth < 10
)
SELECT * FROM deps WHERE depth > 5;
Incorrect

A requires B, B requires A

{
code: 'SVC_A',
eligibilityConstraints: [{ requires: 'SVC_B' }]
}
{
code: 'SVC_B',
eligibilityConstraints: [{ requires: 'SVC_A' }] // ← Circular!
}

Solution:

  • Remove circular dependency
  • Use one-way dependencies
  • Restructure constraints

Prevention:

  • Build dependency graph before implementation
  • Validate no cycles during constraint creation
  • Limit recursion depth in evaluation

Mistake 7: Missing Sort Order Configuration

Severity: LOW

Description: Child services without sortOrder, leading to random display order.

Symptom:

  • Services display in random order
  • Inconsistent UI across sessions
  • Customer confusion

Detection Query:

SELECT code, parent_service_template_id, sort_order
FROM cat_service_template
WHERE parent_service_template_id IS NOT NULL
AND (sort_order IS NULL OR sort_order = 0)
ORDER BY parent_service_template_id;
Incorrect

No sort order

[
{ code: 'SVC_MSN_GOLD', sortOrder: null },
{ code: 'SVC_MSN_STANDARD', sortOrder: null },
{ code: 'SVC_MSN_SILVER', sortOrder: null }
]
Correct

Explicit sort order

[
{ code: 'SVC_MSN_STANDARD', sortOrder: 1 },
{ code: 'SVC_MSN_SILVER', sortOrder: 2 },
{ code: 'SVC_MSN_GOLD', sortOrder: 3 }
]

Prevention:

  • Always set sortOrder for child services
  • Use consistent increment (10, 20, 30) for flexibility
  • Document display order requirements

Mistake 8: Mixing Inclusion Types Incorrectly

Severity: MEDIUM

Description: Using wrong inclusion type (e.g., MANDATORY for customer-choice services).

Symptom:

  • Customer cannot remove unwanted service
  • Free service shows as paid
  • Regulatory service can be deselected

Detection Query:

-- Paid services that are MANDATORY
SELECT st.code, st.inclusion_type, c.amount
FROM cat_service_template st
JOIN cat_charge_template c ON st.id = c.service_template_id
WHERE st.inclusion_type = 'MANDATORY'
AND c.amount > 0;

-- Regulatory services that are not MANDATORY
SELECT code, inclusion_type
FROM cat_service_template
WHERE code LIKE '%REGISTRY%'
AND inclusion_type != 'MANDATORY';
Incorrect

Paid service as MANDATORY

{
code: 'SVC_SPEED_BOOST',
price: 10.00,
inclusionType: ServiceInclusionType.MANDATORY // ← Customer cannot opt out!
}
Correct

Paid service as OPTIONAL

{
code: 'SVC_SPEED_BOOST',
price: 10.00,
inclusionType: ServiceInclusionType.OPTIONAL
}

Prevention:

  • Use inclusion type decision tree
  • Review billing impact during design
  • Test customer opt-out flows

Mistake 9: Forgetting Registry Services

Severity: CRITICAL (Regulatory)

Description: Creating MSN/phone number services without corresponding Registry service.

Symptom:

  • IPND compliance violation
  • Numbers not registered with regulator
  • Audit failures

Detection Query:

-- MSN services without Registry child
SELECT msn.code
FROM cat_service_template msn
LEFT JOIN cat_service_template reg ON reg.parent_service_template_id = msn.id
AND reg.role = 'REGISTRY'
WHERE msn.code LIKE '%MSN%' OR msn.code LIKE '%NUMBER%'
AND reg.id IS NULL;
Incorrect

MSN without Registry

{
code: 'SVC_MSN_STANDARD',
role: ServiceRole.INVENTORY,
parentServiceTemplate: 'SVC_MOBILE_BASE'
// Missing: NUMBER_REGISTRY child service!
}
Correct

Registry service as child of parent

{
code: 'SVC_NUMBER_REGISTRY_AU_IPND',
role: ServiceRole.REGISTRY,
parentServiceTemplate: 'SVC_MOBILE_BASE',
inclusionType: ServiceInclusionType.MANDATORY
}

Prevention:

  • Include Registry services in hierarchy design
  • Validate Registry exists for all number services
  • Automate IPND compliance checks

Mistake 10: Incorrect Activation Order

Severity: MEDIUM

Description: Services activating in wrong order due to missing dependencies.

Symptom:

  • Child activates before parent
  • Inventory allocated before subscription confirmed
  • Billing recorded incorrectly

Detection Query:

-- Check activation order constraints
SELECT st.code, st.sort_order, parent.code as parent_code, parent.sort_order as parent_order
FROM cat_service_template st
JOIN cat_service_template parent ON st.parent_service_template_id = parent.id
WHERE st.sort_order < parent.sort_order; -- Child before parent
Incorrect

Child activates first

{
code: 'SVC_NBN_AVC',
activationOrder: 1 // ← Before parent NBN_ACCESS (order 2)
}
{
code: 'SVC_NBN_ACCESS',
activationOrder: 2
}
Correct

Parent activates first

{
code: 'SVC_NBN_ACCESS',
activationOrder: 1
}
{
code: 'SVC_NBN_AVC',
activationOrder: 2 // After parent
}

Prevention:

  • Parent must activate before children
  • Use dependency constraints for complex order
  • Test activation sequences

Automated Validation Scripts

Pre-Deployment Validation

#!/bin/bash
# validate-hierarchy.sh - Run before deployment

echo "=== Service Hierarchy Validation ==="

# Check 1: Orphaned services
echo "Checking for orphaned services..."
psql -c "
SELECT code FROM cat_service_template
WHERE role IN ('INVENTORY', 'ADDON', 'REGISTRY')
AND parent_service_template_id IS NULL;
" | grep -q "0 rows" && echo "✅ No orphans" || echo "❌ ORPHANS FOUND"

# Check 2: PRIMARY with parent
echo "Checking PRIMARY services..."
psql -c "
SELECT code FROM cat_service_template
WHERE role = 'PRIMARY'
AND parent_service_template_id IS NOT NULL;
" | grep -q "0 rows" && echo "✅ PRIMARY OK" || echo "❌ PRIMARY HAS PARENTS"

# Check 3: NBN_AVC parent
echo "Checking NBN_AVC parent..."
psql -c "
SELECT st.code, p.code as parent
FROM cat_service_template st
JOIN cat_service_template p ON st.parent_service_template_id = p.id
WHERE st.code = 'SVC_NBN_AVC';
" | grep -q "SVC_NBN_ACCESS" && echo "✅ NBN_AVC OK" || echo "❌ NBN_AVC WRONG PARENT"

echo "=== Validation Complete ==="

Runtime Health Check

// hierarchy-health-check.ts
async function validateHierarchyHealth(): Promise<HealthCheckResult> {
const checks = [
checkOrphanedServices(),
checkPrimaryServices(),
checkNestedServices(),
checkRegistryServices(),
];

const results = await Promise.all(checks);
return {
healthy: results.every(r => r.passed),
checks: results,
};
}

Summary Matrix

MistakeSeverityDetectionPrevention
Orphaned servicesCRITICALSQL queryFK constraints
Wrong nested parentHIGHSQL queryDecision tree
PRIMARY with parentHIGHSQL queryDB constraint
Wrong roleHIGHSQL queryRole decision tree
No lifecycle inheritMEDIUMSQL queryDefault true
Circular constraintsHIGHGraph analysisCycle detection
Missing sort orderLOWSQL queryTemplate validation
Wrong inclusion typeMEDIUMSQL queryInclusion tree
Missing RegistryCRITICALSQL queryCompliance check
Wrong activation orderMEDIUMSQL queryParent-first rule