KMP PHP API Reference

RecommendationMigrationService
in package
uses LocatorAwareTrait

Audits and reconciles legacy Awards recommendations into their new lifecycle owners.

Table of Contents

Constants

WORKFLOW_EVENT  : mixed = 'Awards.ExistingRecommendationApprovalRequested'
WORKFLOW_SLUG  : mixed = 'awards-existing-recommendation-approval'
APPROVAL_GATE_MISSING_REASON  : mixed = 'Recommendation approval workflow did not creat...
APPROVAL_NO_ELIGIBLE_APPROVERS_REASON  : mixed = 'Recommendation approval process has no eligibl...
APPROVAL_OWNERSHIP_AMBIGUOUS_REASON  : mixed = 'Recommendation approval workflow ownership is...
APPROVAL_START_FAILURE_REASON  : mixed = 'Recommendation approval workflow could not be...
APPROVAL_STATES  : mixed = ['Submitted', 'In Consideration', 'Awaiting Fee...
BESTOWAL_STATES  : mixed = [\Awards\Services\RecommendationBestowalStatePo...
CLOSED_STATES  : mixed = ['Given', 'No Action', 'Deferred till Later', '...
MIGRATION_FAILURE_REASON  : mixed = 'Recommendation migration failed. Review server...

Properties

$approvalResolver  : AwardApprovalResolverService
$approvalRunsTable  : Table
$bestowalCreationService  : BestowalCreationService
$feedbackRequestItemsTable  : Table
$migrationResultsTable  : Table|null
$migrationRunsTable  : Table|null
$recommendationsTable  : Table
$transitionService  : RecommendationTransitionService
$triggerDispatcher  : TriggerDispatcher|null
$workflowApprovalsTable  : Table
$workflowDefinitionsTable  : Table|null
$workflowInstancesTable  : Table

Methods

__construct()  : mixed
auditOpenRecommendationsWithoutWorkflow()  : array{count: int, recommendations: array}
Find open recommendations that still lack workflow or bestowal ownership.
backfillOpenApprovalRecommendations()  : ServiceResult
Start approval workflows for open approval-owned recommendations that do not have an active run.
classify()  : array{target: string, reason: string}
preflight()  : ServiceResult
Validate prerequisites without mutating records.
run()  : ServiceResult
Run the migration in dry-run, apply, or resume mode.
applyApprovalWorkflow()  : array<string, mixed>
applyBestowal()  : array<string, mixed>
applyClassification()  : EntityInterface
Apply one classification and persist an audit result.
applyClosed()  : array<string, mixed>
applyRecommendationFilters()  : SelectQuery
Apply migration recommendation filters to a query.
approvalReadinessIssue()  : string|null
Check whether an approval-owned recommendation can reach its first approval gate.
assertPendingApprovalWorkflow()  : void
Confirm approval workflow ownership reached a pending approval gate.
backfillOpenApprovalRecommendation()  : array{status: string, reason?: string}
Lock, recheck, and backfill one approval-owned recommendation.
bestowalReadinessIssue()  : string|null
Check whether a bestowal-owned recommendation can safely create or link a bestowal.
buildRecommendationQuery()  : SelectQuery
Build the scoped recommendation query for a migration run.
closeActiveApprovalRuns()  : void
Mark active approval runs closed when the recommendation enters the closed path.
failedWorkflowReason()  : string
Extract a workflow failure reason from the instance context when available.
findActiveApprovalRun()  : EntityInterface|null
Find an active recommendation approval run.
findActiveWorkflowInstance()  : EntityInterface|null
Find an active existing-recommendation workflow instance.
formatOpenRecommendationAuditFailure()  : string
Format an audit failure for console/service output.
getMigrationResultsTable()  : Table
Lazily load migration results table so classifier-only tests do not require audit schema.
getMigrationRunsTable()  : Table
Lazily load migration runs table so classifier-only tests do not require audit schema.
getTriggerDispatcher()  : TriggerDispatcher
Lazily build the workflow trigger dispatcher.
getWorkflowDefinitionsTable()  : Table
Lazily load workflow definitions table for preflight checks.
hasActiveFeedbackRequest()  : bool
Determine whether the recommendation still has an open feedback request.
isManualReviewableApprovalWorkflowFailure()  : bool
Return true when an approval workflow failure should leave the recommendation for manual review.
manualReviewableApprovalWorkflowFailureReason()  : string
Map a known approval-start failure to a safe operator-facing category.
openApprovalRecommendationsWithoutRunQuery()  : SelectQuery
Find the exact population eligible for approval workflow backfill.
openRecommendationsWithoutWorkflowQuery()  : SelectQuery
Build the open recommendation audit query.
repairActiveWorkflowOwnership()  : EntityInterface
Recreate a missing approval-run projection for one active workflow instance.
saveResult()  : EntityInterface

Constants

APPROVAL_GATE_MISSING_REASON

private mixed APPROVAL_GATE_MISSING_REASON = 'Recommendation approval workflow did not create a pending approval gate.'

APPROVAL_NO_ELIGIBLE_APPROVERS_REASON

private mixed APPROVAL_NO_ELIGIBLE_APPROVERS_REASON = 'Recommendation approval process has no eligible approvers.'

APPROVAL_OWNERSHIP_AMBIGUOUS_REASON

private mixed APPROVAL_OWNERSHIP_AMBIGUOUS_REASON = 'Recommendation approval workflow ownership is ambiguous and requires manual review.'

APPROVAL_START_FAILURE_REASON

private mixed APPROVAL_START_FAILURE_REASON = 'Recommendation approval workflow could not be started. Review server logs for details.'

BESTOWAL_STATES

private mixed BESTOWAL_STATES = [\Awards\Services\RecommendationBestowalStatePolicyService::HANDOFF_STATE, 'Scheduled', 'Announced Not Given', 'King Approved', 'Queen Approved']

MIGRATION_FAILURE_REASON

private mixed MIGRATION_FAILURE_REASON = 'Recommendation migration failed. Review server logs for details.'

Properties

Methods

__construct()

public __construct([TriggerDispatcher|null $triggerDispatcher = null ][, RecommendationTransitionService|null $transitionService = null ][, BestowalCreationService|null $bestowalCreationService = null ][, AwardApprovalResolverService|null $approvalResolver = null ]) : mixed
Parameters
$triggerDispatcher : TriggerDispatcher|null = null

Optional dispatcher

$transitionService : RecommendationTransitionService|null = null

Optional transition service

$bestowalCreationService : BestowalCreationService|null = null

Optional bestowal service

$approvalResolver : AwardApprovalResolverService|null = null

Optional approval resolver

auditOpenRecommendationsWithoutWorkflow()

Find open recommendations that still lack workflow or bestowal ownership.

public auditOpenRecommendationsWithoutWorkflow([array<string, mixed> $filters = [] ]) : array{count: int, recommendations: array}
Parameters
$filters : array<string, mixed> = []

Optional recommendation filters

Return values
array{count: int, recommendations: array}

backfillOpenApprovalRecommendations()

Start approval workflows for open approval-owned recommendations that do not have an active run.

public backfillOpenApprovalRecommendations(int $actorId) : ServiceResult

This is intentionally narrower than the general legacy migration: it never closes a recommendation or creates a bestowal. Each candidate is locked and rechecked in its own transaction so one bad record cannot roll back successful backfills.

Parameters
$actorId : int

Member initiating the backfill

Return values
ServiceResult

run()

Run the migration in dry-run, apply, or resume mode.

public run(string $mode, array<string, mixed> $filters, int $actorId[, bool $allowOpenManualReview = false ]) : ServiceResult
Parameters
$mode : string

RecommendationMigrationRun::MODE_* value

$filters : array<string, mixed>

Optional recommendation filters

$actorId : int

Actor member ID for mutation/audit fields

$allowOpenManualReview : bool = false

Allow unresolved manual-review recommendations to remain open

Return values
ServiceResult

applyApprovalWorkflow()

private applyApprovalWorkflow(Recommendation $recommendation, array<string, mixed> $resultData, int $actorId) : array<string, mixed>
Parameters
$recommendation : Recommendation
$resultData : array<string, mixed>

Result data

$actorId : int
Return values
array<string, mixed>

applyBestowal()

private applyBestowal(Recommendation $recommendation, array<string, mixed> $resultData, int $actorId) : array<string, mixed>
Parameters
$recommendation : Recommendation
$resultData : array<string, mixed>

Result data

$actorId : int
Return values
array<string, mixed>

applyClassification()

Apply one classification and persist an audit result.

private applyClassification(string|int $runId, Recommendation $recommendation, array{target: string, reason: string} $classification, string $mode, int $actorId) : EntityInterface
Parameters
$runId : string|int

Migration run ID

$recommendation : Recommendation

Recommendation

$classification : array{target: string, reason: string}

Classification data

$mode : string

Run mode

$actorId : int

Actor member ID

Return values
EntityInterface

applyClosed()

private applyClosed(Recommendation $recommendation, array<string, mixed> $resultData, int $actorId) : array<string, mixed>
Parameters
$recommendation : Recommendation
$resultData : array<string, mixed>

Result data

$actorId : int
Return values
array<string, mixed>

applyRecommendationFilters()

Apply migration recommendation filters to a query.

private applyRecommendationFilters(SelectQuery $query, array<string, mixed> $filters) : SelectQuery
Parameters
$query : SelectQuery

Query to filter

$filters : array<string, mixed>

Optional filters

Return values
SelectQuery

approvalReadinessIssue()

Check whether an approval-owned recommendation can reach its first approval gate.

private approvalReadinessIssue(Recommendation $recommendation) : string|null
Parameters
$recommendation : Recommendation

Recommendation

Return values
string|null

Manual-review reason, or null when ready

assertPendingApprovalWorkflow()

Confirm approval workflow ownership reached a pending approval gate.

private assertPendingApprovalWorkflow(EntityInterface $run, int $actorId) : void
Parameters
$run : EntityInterface

Active approval run

$actorId : int

Actor member ID

backfillOpenApprovalRecommendation()

Lock, recheck, and backfill one approval-owned recommendation.

private backfillOpenApprovalRecommendation(int $recommendationId, int $actorId) : array{status: string, reason?: string}
Parameters
$recommendationId : int

Recommendation selected by the bulk scan

$actorId : int

Member initiating the backfill

Return values
array{status: string, reason?: string}

bestowalReadinessIssue()

Check whether a bestowal-owned recommendation can safely create or link a bestowal.

private bestowalReadinessIssue(Recommendation $recommendation) : string|null
Parameters
$recommendation : Recommendation

Recommendation

Return values
string|null

Manual-review reason, or null when ready

buildRecommendationQuery()

Build the scoped recommendation query for a migration run.

private buildRecommendationQuery(array<string, mixed> $filters) : SelectQuery
Parameters
$filters : array<string, mixed>

Optional filters

Return values
SelectQuery

closeActiveApprovalRuns()

Mark active approval runs closed when the recommendation enters the closed path.

private closeActiveApprovalRuns(int $recommendationId, int $actorId) : void
Parameters
$recommendationId : int

Recommendation ID

$actorId : int

Actor member ID

failedWorkflowReason()

Extract a workflow failure reason from the instance context when available.

private failedWorkflowReason(EntityInterface $instance) : string
Parameters
$instance : EntityInterface

Workflow instance

Return values
string

findActiveApprovalRun()

Find an active recommendation approval run.

private findActiveApprovalRun(int $recommendationId) : EntityInterface|null
Parameters
$recommendationId : int

Recommendation ID

Return values
EntityInterface|null

findActiveWorkflowInstance()

Find an active existing-recommendation workflow instance.

private findActiveWorkflowInstance(int $recommendationId) : EntityInterface|null
Parameters
$recommendationId : int

Recommendation ID

Return values
EntityInterface|null

formatOpenRecommendationAuditFailure()

Format an audit failure for console/service output.

private formatOpenRecommendationAuditFailure(array{count: int, recommendations: array$audit) : string
Parameters
$audit : array{count: int, recommendations: array}

Audit result

Return values
string

getMigrationResultsTable()

Lazily load migration results table so classifier-only tests do not require audit schema.

private getMigrationResultsTable() : Table
Return values
Table

getMigrationRunsTable()

Lazily load migration runs table so classifier-only tests do not require audit schema.

private getMigrationRunsTable() : Table
Return values
Table

getWorkflowDefinitionsTable()

Lazily load workflow definitions table for preflight checks.

private getWorkflowDefinitionsTable() : Table
Return values
Table

hasActiveFeedbackRequest()

Determine whether the recommendation still has an open feedback request.

private hasActiveFeedbackRequest(int $recommendationId) : bool
Parameters
$recommendationId : int

Recommendation ID

Return values
bool

isManualReviewableApprovalWorkflowFailure()

Return true when an approval workflow failure should leave the recommendation for manual review.

private isManualReviewableApprovalWorkflowFailure(Throwable $exception) : bool
Parameters
$exception : Throwable
Return values
bool

manualReviewableApprovalWorkflowFailureReason()

Map a known approval-start failure to a safe operator-facing category.

private manualReviewableApprovalWorkflowFailureReason(Throwable $exception) : string
Parameters
$exception : Throwable
Return values
string

openApprovalRecommendationsWithoutRunQuery()

Find the exact population eligible for approval workflow backfill.

private openApprovalRecommendationsWithoutRunQuery() : SelectQuery
Return values
SelectQuery

openRecommendationsWithoutWorkflowQuery()

Build the open recommendation audit query.

private openRecommendationsWithoutWorkflowQuery() : SelectQuery
Return values
SelectQuery

repairActiveWorkflowOwnership()

Recreate a missing approval-run projection for one active workflow instance.

private repairActiveWorkflowOwnership(Recommendation $recommendation, EntityInterface $instance, int $actorId) : EntityInterface

The workflow instance, approval gates, and responses are the durable evidence. Repair only relinks their run projection; it never replaces a gate or response.

Parameters
$recommendation : Recommendation

Recommendation being repaired

$instance : EntityInterface

Active existing-recommendation workflow

$actorId : int

Member initiating the repair

Return values
EntityInterface

saveResult()

private saveResult(array<string, mixed> $resultData) : EntityInterface
Parameters
$resultData : array<string, mixed>

Result data

Return values
EntityInterface
On this page

Search results