## Vital References and Collections

Vital references and collections define parent-child relationships where the child entities cannot exist independently of their parent. When the parent is deleted, all vital children are automatically deleted. This pattern is essential for maintaining data integrity in hierarchical business structures.

### Understanding Vital Relationships

#### What are Vital References?

A vital reference establishes a dependency relationship where:

- **Parent Node**: The main entity that owns the relationship
- **Child Node**: The dependent entity that cannot exist without its parent
- **Automatic Lifecycle Management**: Child entities are created, updated, and deleted through the parent
- **Referential Integrity**: The framework automatically maintains consistency

#### What are Vital Collections?

A vital collection is a collection of child entities that:

- Are created and managed through their parent
- Share the same lifecycle as their parent
- Cannot exist independently
- Are automatically ordered using `_sortValue`

### Node-Level Vital Reference Declaration

#### Parent Node Configuration

The parent declares a vital reference using `isVital: true` and specifies the reverse reference:

```typescript
@decorators.node<ShowCaseProduct>({
    storage: 'sql',
    canCreate: true,
    canRead: true,
    canUpdate: true,
    canDelete: true,
    isPublished: true,
    isVitalCollectionChild: true, // If this node is also a vital child
})
export class ShowCaseProduct extends Node {
    // Vital reference to origin address
    @decorators.referenceProperty<ShowCaseProduct, 'originAddress'>({
        isVital: true,
        isPublished: true,
        lookupAccess: true,
        reverseReference: 'product', // Points to child's parent reference
        isNullable: true,
        node: () => ShowCaseProductOriginAddress,
    })
    readonly originAddress: Reference<ShowCaseProductOriginAddress | null>;
}
```

#### Child Node Configuration

The child node must declare itself as a vital child and reference its parent:

```typescript
@decorators.node<ShowCaseProductOriginAddress>({
    storage: 'sql',
    canCreate: true,
    canDelete: true,
    canRead: true,
    canUpdate: true,
    isPublished: true,
    isVitalReferenceChild: true, // Declares this as a vital child
})
export class ShowCaseProductOriginAddress extends Node {
    // Reference to the vital parent
    @decorators.referenceProperty<ShowCaseProductOriginAddress, 'product'>({
        isStored: true,
        isPublished: true,
        isVitalParent: true, // Identifies the vital parent reference
        node: () => ShowCaseProduct,
    })
    readonly product: Reference<ShowCaseProduct>;

    // Other properties of the child entity
    @decorators.stringProperty<ShowCaseProductOriginAddress, 'name'>({
        isStored: true,
        isPublished: true,
        isNotEmpty: true,
    })
    readonly name: Promise<string>;
}
```

### Vital Collection Declaration

#### Parent Node with Collection

```typescript
@decorators.node<ShowCaseOrder>({
    storage: 'sql',
    canCreate: true,
    canDelete: true,
    canRead: true,
    canUpdate: true,
    isPublished: true,
})
export class ShowCaseOrder extends Node {
    @decorators.collectionProperty<ShowCaseOrder, 'invoices'>({
        isPublished: true,
        reverseReference: 'order', // Points to child's parent reference
        isVital: true, // Makes this a vital collection
        node: () => ShowCaseInvoice,
    })
    readonly invoices: Collection<ShowCaseInvoice>;
}
```

#### Child Node in Collection

```typescript
@decorators.node<ShowCaseInvoice>({
    storage: 'sql',
    canCreate: true,
    canDelete: true,
    canRead: true,
    canUpdate: true,
    isPublished: true,
    isVitalCollectionChild: true, // Declares this as a vital collection child
})
export class ShowCaseInvoice extends Node {
    @decorators.referenceProperty<ShowCaseInvoice, 'order'>({
        isStored: true,
        isPublished: true,
        node: () => ShowCaseOrder,
        isVitalParent: true, // Identifies the vital parent reference
    })
    readonly order: Reference<ShowCaseOrder>;

    // Collection within the child
    @decorators.collectionProperty<ShowCaseInvoice, 'lines'>({
        isPublished: true,
        reverseReference: 'invoice',
        isVital: true, // Nested vital collection
        node: () => ShowCaseInvoiceLine,
    })
    readonly lines: Collection<ShowCaseInvoiceLine>;
}
```

#### Nested Vital Collection Child

```typescript
@decorators.node<ShowCaseInvoiceLine>({
    storage: 'sql',
    canCreate: true,
    canDelete: true,
    canRead: true,
    canUpdate: true,
    isPublished: true,
    isVitalCollectionChild: true, // Vital child of invoice
})
export class ShowCaseInvoiceLine extends Node {
    @decorators.referenceProperty<ShowCaseInvoiceLine, 'invoice'>({
        isStored: true,
        isPublished: true,
        isVitalParent: true, // Parent reference
        node: () => ShowCaseInvoice,
    })
    readonly invoice: Reference<ShowCaseInvoice>;
}
```

### Page-Level Vital Field Usage

#### Vital Pod Field

```typescript
@ui.decorators.vitalPodField<ProductPage, ShowCaseProductOriginAddress>({
    title: 'Origin Address',
    width: 'large',
    parent() {
        return this.block;
    },
    canRemove: true, // Allow removing the vital reference
    columns: [
        ui.nestedFields.text({ bind: 'name', title: 'Name' }),
        ui.nestedFields.text({ bind: 'addressLine1', title: 'Address Line 1' }),
        ui.nestedFields.text({ bind: 'city', title: 'City' }),
        ui.nestedFields.reference({
            bind: 'country',
            title: 'Country',
            node: '@sage/xtrem-show-case/ShowCaseCountry',
        }),
    ],
    node: '@sage/xtrem-show-case/ShowCaseProductOriginAddress',
})
originAddress: ui.fields.VitalPod;
```

#### Vital Collection Field

```typescript
@ui.decorators.tableField<OrderPage, ShowCaseInvoice>({
    bind: 'invoices',
    title: 'Invoices',
    parent() {
        return this.block;
    },
    node: '@sage/xtrem-show-case/ShowCaseInvoice',
    canCreate: true,
    canUpdate: true,
    canDelete: true,
    columns: [
        ui.nestedFields.date({ bind: 'purchaseDate', title: 'Purchase Date' }),
        ui.nestedFields.reference({
            bind: 'customer',
            title: 'Customer',
            node: '@sage/xtrem-show-case/ShowCaseCustomer',
        }),
        ui.nestedFields.numeric({ bind: 'totalProductQty', title: 'Total Qty' }),
    ],
})
invoices: ui.fields.Table<ShowCaseInvoice>;
```

### The \_sortValue Property

Vital collection children automatically receive a `_sortValue` property that:

- **Maintains Order**: Preserves the order of items in the collection
- **Auto-Generated**: Framework automatically assigns values (10, 20, 30, etc.)
- **Updateable**: Can be explicitly set during updates
- **Accessible**: Available as `node.$.sortValue` in TypeScript and `_sortValue` in GraphQL

```typescript
// Accessing sort value
const sortValue = await vitalChild.$.sortValue;

// Setting sort value during creation
await parent.$.set({
    lines: [
        { code: 'LINE-1', _sortValue: 5 },
        { code: 'LINE-2', _sortValue: 15 },
        { code: 'LINE-3' }, // Auto-assigned next available value
    ],
});
```

### CRUD Operations on Vital Relationships

#### Creating with Vital Children

```typescript
// Create parent with vital reference
const product = await context.create(ShowCaseProduct, {
    product: 'New Product',
    originAddress: {
        name: 'Factory',
        addressLine1: '123 Industrial Ave',
        city: 'Manufacturing City',
    },
});

// Create parent with vital collection
const order = await context.create(ShowCaseOrder, {
    orderDate: date.parse('2025-01-01'),
    invoices: [
        {
            purchaseDate: date.parse('2025-01-15'),
            lines: [
                { orderQuantity: 5, comments: 'Rush order' },
                { orderQuantity: 10, comments: 'Standard delivery' },
            ],
        },
    ],
});
```

#### Updating Vital Collections

```typescript
// Update with action-based syntax
await order.$.set({
    invoices: [
        { _action: 'update', _id: 'invoice-1', purchaseDate: newDate },
        { _action: 'delete', _id: 'invoice-2' },
        { _action: 'create', purchaseDate: date.parse('2025-02-01') },
    ],
});

// Update with replacement syntax
await order.$.set({
    invoices: [
        { _id: 'existing-invoice-1' }, // Keep existing
        { purchaseDate: date.parse('2025-02-01') }, // Create new
    ],
});
```

### Database Considerations

#### Automatic Index Creation

The framework automatically creates:

- **Foreign Key**: Child table references parent with CASCADE DELETE
- **Unique Index**: `[_tenantId, parent_reference]` for vital references
- **Sorting Index**: `[_tenantId, parent_reference, _sortValue]` for vital collections

#### Storage Pattern

```sql
-- Child table stores parent reference
CREATE TABLE show_case_product_origin_address (
    _id BIGINT PRIMARY KEY,
    _tenant_id BIGINT NOT NULL,
    product BIGINT NOT NULL, -- Reference to parent
    name VARCHAR(255),
    address_line1 VARCHAR(255),
    FOREIGN KEY (product) REFERENCES show_case_product(_id) ON DELETE CASCADE
);

-- Vital collection child with sort value
CREATE TABLE show_case_invoice_line (
    _id BIGINT PRIMARY KEY,
    _tenant_id BIGINT NOT NULL,
    invoice BIGINT NOT NULL, -- Reference to parent
    _sort_value BIGINT NOT NULL,
    order_quantity INT,
    FOREIGN KEY (invoice) REFERENCES show_case_invoice(_id) ON DELETE CASCADE
);
```

### Advanced Patterns

#### Multi-Level Vital Hierarchies

```typescript
// Three-level hierarchy: Order -> Invoice -> InvoiceLine
// Each level can have its own vital children
@decorators.node<ShowCaseOrder>({
    isPublished: true,
    // ... other properties
})
export class ShowCaseOrder extends Node {
    @decorators.collectionProperty<ShowCaseOrder, 'invoices'>({
        isVital: true,
        reverseReference: 'order',
        node: () => ShowCaseInvoice,
    })
    readonly invoices: Collection<ShowCaseInvoice>;
}
```

#### Conditional Vital References

```typescript
@decorators.referenceProperty<Product, 'originAddress'>({
    isVital: true,
    isNullable: true, // Can be null
    reverseReference: 'product',
    node: () => ProductOriginAddress,
    // Only create if certain conditions are met
    async defaultValue() {
        if (await this.requiresOriginTracking) {
            return { name: 'Default Origin' };
        }
        return null;
    },
})
readonly originAddress: Reference<ProductOriginAddress | null>;
```

#### Required Vital Collections

```typescript
@decorators.collectionProperty<Order, 'lines'>({
    isVital: true,
    isRequired: true, // Collection cannot be empty
    reverseReference: 'order',
    node: () => OrderLine,
})
readonly lines: Collection<OrderLine>;
```

### Best Practices for Vital Relationships

1. **Use for True Dependencies**: Only make relationships vital when children truly cannot exist without parents
2. **Consider Performance**: Vital operations can involve multiple entities - design accordingly
3. **Plan Hierarchies**: Design multi-level vital structures carefully to avoid deep nesting
4. **Handle Nullability**: Use nullable vital references for optional dependent data
5. **Leverage Sort Values**: Use `_sortValue` to maintain meaningful ordering in collections
6. **Test Thoroughly**: Vital relationships involve complex lifecycle management - test all scenarios
7. **Document Dependencies**: Clearly document vital relationships for maintainability

### Common Patterns

#### Document-Line Pattern

```typescript
// Order -> OrderLine (vital collection)
// Invoice -> InvoiceLine (vital collection)
// Quote -> QuoteLine (vital collection)
```

#### Master-Detail Pattern

```typescript
// Product -> ProductSpecification (vital reference)
// Customer -> CustomerSettings (vital reference)
// Employee -> EmployeeProfile (vital reference)
```

#### Nested Document Pattern

```typescript
// Order -> Invoice -> InvoiceLine (nested vital collections)
// Project -> Phase -> Task (nested vital collections)
```

### Specialized Libraries Quick Reference

For advanced value type handling, refer to the [Specialized Value Types](#specialized-value-types) section:

- **`@sage/xtrem-date-time`** - Date and DateTime manipulation with DateValue class
- **`@sage/xtrem-decimal`** - Precise decimal arithmetic with Decimal class
- **`@sage/xtrem-show-case`** - Reference implementations and examples

These libraries provide production-ready implementations for complex business requirements including financial calculations, date processing, and UI integration.

