Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/IdLE.Core/Public/Invoke-IdlePlanObject.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ function Invoke-IdlePlanObject {

.OUTPUTS
PSCustomObject (PSTypeName: IdLE.ExecutionResult)

.EXAMPLE
$result = Invoke-IdlePlanObject -Plan $plan -Providers $providers

Executes a plan with the specified provider registry and returns an execution result.
#>
[CmdletBinding()]
param(
Expand Down
69 changes: 69 additions & 0 deletions src/IdLE.Core/Public/New-IdleLifecycleRequestObject.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,73 @@
function New-IdleLifecycleRequestObject {
<#
.SYNOPSIS
Creates a lifecycle request object (core factory).

.DESCRIPTION
Constructs and returns an IdleLifecycleRequest domain object representing business intent
(e.g. Joiner/Mover/Leaver). This is the core factory function used by the IdLE module wrapper.

The function validates that no ScriptBlocks are present in the input data (IdentityKeys,
DesiredState, Changes) to enforce the data-only configuration principle. Input hashtables
are cloned to prevent external mutation after object creation.

CorrelationId is preserved if provided; otherwise, the IdleLifecycleRequest class generates
a new GUID. Actor is optional and not required by the core engine.

.PARAMETER LifecycleEvent
The lifecycle event name (e.g. Joiner, Mover, Leaver). This is a required string that
identifies the type of lifecycle operation being requested.

.PARAMETER CorrelationId
Optional correlation identifier for audit and event correlation. If omitted, a GUID is
automatically generated by the IdleLifecycleRequest constructor.

.PARAMETER Actor
Optional actor claim identifying who initiated the request. Not required by the core
engine in V1 but may be used for audit logging or workflow-specific logic.

.PARAMETER IdentityKeys
A hashtable of system-neutral identity keys (e.g. @{ EmployeeId = '12345'; UPN = 'user@contoso.com' }).
Defaults to an empty hashtable if not provided. Must not contain ScriptBlocks.

.PARAMETER DesiredState
A hashtable describing the desired state for the identity (attributes, entitlements, etc.).
Defaults to an empty hashtable if not provided. Must not contain ScriptBlocks.

.PARAMETER Changes
Optional hashtable describing changes (typically used for Mover lifecycle events to indicate
what changed from the previous state). Remains $null when omitted. Must not contain ScriptBlocks.

.EXAMPLE
$request = New-IdleLifecycleRequestObject -LifecycleEvent 'Joiner'

Creates a minimal Joiner request with auto-generated CorrelationId and empty IdentityKeys/DesiredState.

.EXAMPLE
$request = New-IdleLifecycleRequestObject -LifecycleEvent 'Joiner' -CorrelationId (New-Guid).Guid -IdentityKeys @{ EmployeeId = '12345' } -DesiredState @{ Department = 'Engineering'; MailNickname = 'jdoe'; Title = 'Engineer' }

Creates a Joiner request with specific identity keys and desired state attributes for a typical onboarding workflow.

.EXAMPLE
$request = New-IdleLifecycleRequestObject -LifecycleEvent 'Mover' -IdentityKeys @{ UPN = 'user@contoso.com' } -Changes @{ Department = 'Sales' } -Actor 'admin@contoso.com'

Creates a Mover request with identity keys, changes, and actor information for a department transfer workflow.

.OUTPUTS
IdleLifecycleRequest

.NOTES
Security Considerations:
- Input data must be data-only (no ScriptBlocks or executable objects). The function
validates this constraint and throws if violated.
- Do not embed secrets in IdentityKeys, DesiredState, or Changes. Use the AuthSessionBroker
pattern for credential/token management.
- Sensitive data in request objects may be logged or emitted in events. Rely on redaction
boundaries defined in the engine's event sink and logging layers.

This is a core engine function. For the user-facing API, use New-IdleLifecycleRequest from
the IdLE module, which delegates to this function.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)]
Expand Down
5 changes: 5 additions & 0 deletions src/IdLE.Core/Public/New-IdlePlanObject.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ function New-IdlePlanObject {

.OUTPUTS
PSCustomObject (PSTypeName: IdLE.Plan)

.EXAMPLE
$plan = New-IdlePlanObject -WorkflowPath ./workflows/joiner.psd1 -Request $request -Providers $providers

Builds a plan from a workflow definition and lifecycle request with the specified provider registry.
#>
[CmdletBinding()]
param(
Expand Down
5 changes: 5 additions & 0 deletions src/IdLE.Core/Public/Test-IdleWorkflowDefinitionObject.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ function Test-IdleWorkflowDefinitionObject {

.OUTPUTS
PSCustomObject (PSTypeName: IdLE.WorkflowDefinition)

.EXAMPLE
$workflow = Test-IdleWorkflowDefinitionObject -WorkflowPath ./workflows/joiner.psd1

Loads and validates a workflow definition, ensuring it is data-only and schema-compliant.
#>
[CmdletBinding()]
param(
Expand Down
51 changes: 51 additions & 0 deletions tests/Core/ModuleExports.Tests.ps1
Comment thread
blindzero marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,57 @@ Describe 'Module Export Consistency' {
}
}
}

It 'Exported IdLE.Core functions have comment-based help (Synopsis + Description + Examples + Parameters)' {
$commands = Get-Command -Module IdLE.Core -CommandType Function
$commands | Should -Not -BeNullOrEmpty

foreach ($cmd in $commands) {
$help = Get-Help -Name $cmd.Name -ErrorAction Stop

# Synopsis
$help.Synopsis | Should -Not -BeNullOrEmpty -Because "Function '$($cmd.Name)' should have a Synopsis"

# Description (can be structured)
$descText =
if ($help.Description -and $help.Description.Text) { ($help.Description.Text -join "`n").Trim() }
else { '' }

$descText | Should -Not -BeNullOrEmpty -Because "Function '$($cmd.Name)' should have a Description"

# Examples (can also be structured)
$exampleCount =
if ($help.Examples -and $help.Examples.Example) {
@($help.Examples.Example).Count
}
else {
0
}

$exampleCount | Should -BeGreaterThan 0 -Because "Function '$($cmd.Name)' should have at least one Example"

# Parameters - check that each non-common parameter has documentation
# Common parameters (Debug, ErrorAction, etc.) are automatically documented by PowerShell
$commonParameters = @(
'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction',
'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable',
'OutBuffer', 'PipelineVariable', 'ProgressAction'
)

$cmdParameters = @($cmd.Parameters.Keys | Where-Object { $_ -notin $commonParameters })

if ($cmdParameters.Count -gt 0) {
$helpParameters = @()
if ($help.parameters -and $help.parameters.parameter) {
$helpParameters = @($help.parameters.parameter | ForEach-Object { $_.name })
}

foreach ($paramName in $cmdParameters) {
$helpParameters | Should -Contain $paramName -Because "Function '$($cmd.Name)' should have .PARAMETER documentation for parameter '$paramName'"
}
}
}
}
}

Context 'IdLE meta-module exports' {
Expand Down
Loading