Public/Invoke-Connector.ps1

<#
.SYNOPSIS
Imports configured SuccessFactors OData resources into IAM Core Connector Space.

.DESCRIPTION
Validates the configured resource definitions, authenticates to SuccessFactors, retrieves every
configured resource, generates stable external IDs, and emits connector objects. Resource
definitions may optionally emit deterministic derived outputs or protect the primary PerPerson
national ID before storage. An optional workforce-retention policy can consistently limit person,
employment, user, and job objects using EmpEmployment.endDate.

.PARAMETER ConnectorConfiguration
Connector configuration containing authentication settings and a resourcetypes JSON array.

.OUTPUTS
System.Collections.Hashtable. Source connector objects and any configured derived outputs.

.NOTES
The connector imports source rows losslessly unless an explicitly configured national-ID
protection or workforce-retention policy is enabled. Derived outputs never replace source rows.
Data-quality and projection policy otherwise belong in source-system validation and IAM Core sync
rules.
#>

function Invoke-Connector {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        $ConnectorConfiguration
    )

    $module = $ExecutionContext.SessionState.Module
    Write-ConnectorVerbose "Starting connector module '$($module.Name)' version '$($module.Version)'"

    $resourceTypes = @(ConvertFrom-SFResourceTypesConfiguration -ConnectorConfiguration $ConnectorConfiguration)
    $workforceRetentionDays = Get-SFWorkforceRetentionDay -ConnectorConfiguration $ConnectorConfiguration
    Connect-SF -ConnectorConfiguration $ConnectorConfiguration
    Write-ConnectorVerbose "Connected successfully"

    $asOfDate = [DateTimeOffset]::UtcNow

    if ($null -eq $workforceRetentionDays) {
        foreach ($resourceTypeConfiguration in $resourceTypes) {
            $resources = @(Get-SFConfiguredResource `
                -ResourceTypeConfiguration $resourceTypeConfiguration `
                -BaseUrl $ConnectorConfiguration.configuration.baseurl `
                -AsOfDate $asOfDate)

            Write-SFResourceType `
                -ResourceTypeConfiguration $resourceTypeConfiguration `
                -Resources $resources
        }
        return
    }

    # Cross-resource retention must know every retained employment before it can safely
    # emit User, EmpJob, PerPerson, and PerPersonal snapshots.
    $resourcesByType = @{}
    foreach ($resourceTypeConfiguration in $resourceTypes) {
        $resourceType = [string]$resourceTypeConfiguration.Type
        $resourcesByType[$resourceType] = @(Get-SFConfiguredResource `
            -ResourceTypeConfiguration $resourceTypeConfiguration `
            -BaseUrl $ConnectorConfiguration.configuration.baseurl `
            -AsOfDate $asOfDate)
    }

    $resourcesByType = Select-SFWorkforceRetentionResource `
        -ResourcesByType $resourcesByType `
        -RetentionDays $workforceRetentionDays `
        -AsOfDate $asOfDate

    foreach ($resourceTypeConfiguration in $resourceTypes) {
        $resourceType = [string]$resourceTypeConfiguration.Type
        $resources = @($resourcesByType[$resourceType])

        Write-SFResourceType `
            -ResourceTypeConfiguration $resourceTypeConfiguration `
            -Resources $resources
    }
}