Persist launched coach slice in action plans

This commit is contained in:
axiomlogicnexus 2026-04-28 00:09:12 +02:00
parent 0ce610510a
commit 640cb9a676
4 changed files with 79 additions and 15 deletions

View file

@ -1282,7 +1282,8 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistContractLibrary::MakeSampleTrainin
TEXT("2026-04-28T12:05:00Z"),
0,
0,
FString()
FString(),
MakeSampleTrainingCoachBrief().FocusCaseIds
);
}
@ -1323,7 +1324,8 @@ FHyperTwistTrainingCoachActionSequenceSummary UHyperTwistContractLibrary::MakeSa
TEXT("2026-04-28T12:20:00Z"),
0,
0,
FString()
FString(),
FollowUpBrief.FocusCaseIds
);
if (FollowUpPlan.IsStructurallyValid())
{
@ -1358,7 +1360,8 @@ FHyperTwistTrainingCoachActionClosureSummary UHyperTwistContractLibrary::MakeSam
TEXT("2026-04-28T12:20:00Z"),
0,
0,
FString()
FString(),
FollowUpBrief.FocusCaseIds
);
if (FollowUpPlan.IsStructurallyValid())
{
@ -1413,7 +1416,8 @@ FHyperTwistTrainingCoachRecommendationHistorySummary UHyperTwistContractLibrary:
TEXT("2026-04-28T12:20:00Z"),
0,
0,
FString()
FString(),
FollowUpBrief.FocusCaseIds
);
if (FollowUpPlan.IsStructurallyValid())
{
@ -1448,7 +1452,8 @@ FHyperTwistTrainingCoachCarryForwardPolicySummary UHyperTwistContractLibrary::Ma
TEXT("2026-04-28T12:20:00Z"),
0,
0,
FString()
FString(),
FollowUpBrief.FocusCaseIds
);
if (FollowUpPlan.IsStructurallyValid())
{
@ -1483,7 +1488,8 @@ FHyperTwistTrainingCoachArchivePolicySummary UHyperTwistContractLibrary::MakeSam
TEXT("2026-04-28T12:20:00Z"),
0,
0,
FString()
FString(),
FollowUpBrief.FocusCaseIds
);
if (FollowUpPlan.IsStructurallyValid())
{

View file

@ -743,6 +743,24 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
return UniqueCaseIds;
}
TArray<FString> ResolveCoachActionPlanFocusCaseIds(
const FHyperTwistCoachBrief& CoachBrief,
const TArray<FString>& LaunchedCaseIds,
const int32 PlannedLaunchCaseCount)
{
TArray<FString> ResolvedCaseIds = DeduplicateCaseIds(
LaunchedCaseIds.Num() > 0 ? LaunchedCaseIds : CoachBrief.FocusCaseIds
);
if (LaunchedCaseIds.Num() == 0
&& PlannedLaunchCaseCount > 0
&& ResolvedCaseIds.Num() > PlannedLaunchCaseCount)
{
ResolvedCaseIds.SetNum(PlannedLaunchCaseCount);
}
return ResolvedCaseIds;
}
TArray<FHyperTwistTrainingMethodDrillResponseRecord> DeduplicateMethodDrillResponses(
const TArray<FHyperTwistTrainingMethodDrillResponseRecord>& Responses
)
@ -6544,7 +6562,8 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
const FString& ReferenceUtc,
const int32 RequestedLaunchCaseCount,
const int32 PlannedLaunchCaseCount,
const FString& LaunchBudgetReasonLine
const FString& LaunchBudgetReasonLine,
const TArray<FString>& LaunchedCaseIds
)
{
FHyperTwistTrainingCoachActionPlan ActionPlan;
@ -6593,6 +6612,15 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
ActionPlan.PlannedLaunchCaseCount = PlannedLaunchCaseCount > 0
? PlannedLaunchCaseCount
: ActionPlan.RequestedLaunchCaseCount;
ActionPlan.FocusCaseIds = HyperTwistTrainingRepositoryLibraryInternal::ResolveCoachActionPlanFocusCaseIds(
CoachBrief,
LaunchedCaseIds,
ActionPlan.PlannedLaunchCaseCount
);
if (ActionPlan.FocusCaseIds.Num() > 0)
{
ActionPlan.PlannedLaunchCaseCount = ActionPlan.FocusCaseIds.Num();
}
ActionPlan.LaunchBudgetReasonLine = LaunchBudgetReasonLine;
ActionPlan.bBroadenedLaunchBudget =
ActionPlan.PlannedLaunchCaseCount > ActionPlan.RequestedLaunchCaseCount
@ -6602,7 +6630,10 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
ActionPlan.PlannedLaunchCaseCount < ActionPlan.RequestedLaunchCaseCount
|| HyperTwistTrainingRepositoryLibraryInternal::ContainsLaunchBudgetTighteningHint(
ActionPlan.LaunchBudgetReasonLine);
ActionPlan.FocusCaseIds = CoachBrief.FocusCaseIds;
if (ActionPlan.FocusCaseIds.Num() == 0)
{
ActionPlan.FocusCaseIds = CoachBrief.FocusCaseIds;
}
ActionPlan.PlanState = EHyperTwistTrainingCoachActionPlanState::Draft;
ActionPlan.FollowUpDepth = FMath::Max(0, CoachBrief.FollowUpDepth);
ActionPlan.CreatedAtUtc = ActionPlan.ReferenceUtc;
@ -6611,11 +6642,11 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
ActionPlan.bNeedsVarietyRotation = CoachBrief.bNeedsVarietyRotation;
ActionPlan.bPreferRecognitionReplayReview = CoachBrief.bPreferRecognitionReplayReview;
for (int32 Index = 0; Index < CoachBrief.FocusCaseIds.Num(); ++Index)
for (int32 Index = 0; Index < ActionPlan.FocusCaseIds.Num(); ++Index)
{
FHyperTwistTrainingCoachActionPlanEntry Entry;
Entry.ActionId = FString::Printf(TEXT("%s_entry_%02d"), *PlanId, Index + 1);
Entry.CaseId = CoachBrief.FocusCaseIds[Index];
Entry.CaseId = ActionPlan.FocusCaseIds[Index];
Entry.DeckId = CoachBrief.FocusDeckId;
Entry.MethodSegmentId = CoachBrief.FocusMethodSegmentId;
Entry.ActionLabel = CoachBrief.PrimaryActionLabel;

View file

@ -106,6 +106,20 @@ namespace HyperTwistTrainingSubsystemInternal
return FString::Printf(TEXT("Launch cases: %d"), CaseCount);
}
TArray<FString> ExtractCaseIdsFromDeck(const FHyperTwistTrainingDeck& Deck)
{
TArray<FString> CaseIds;
for (const FHyperTwistTrainingCase& TrainingCase : Deck.Cases)
{
if (!TrainingCase.CaseId.IsEmpty())
{
CaseIds.Add(TrainingCase.CaseId);
}
}
return CaseIds;
}
FResolvedCoachCaseBudget ResolvePreferredCoachCaseBudget(
const int32 MaxCases,
const EHyperTwistTrainingCoachGuidanceLane DeckLane,
@ -1572,6 +1586,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachRecommendedR
ActiveCoachMemorySnapshot,
false
);
const TArray<FString> LaunchedCaseIds =
HyperTwistTrainingSubsystemInternal::ExtractCaseIdsFromDeck(CoachDeck);
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
ActiveCoachBrief,
@ -1580,7 +1596,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachRecommendedR
FString(),
LaunchBudget.RequestedCaseCount,
CoachDeck.Cases.Num(),
LaunchBudget.ReasonLine
LaunchBudget.ReasonLine,
LaunchedCaseIds
);
FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
CoachDeck,
@ -1646,6 +1663,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachFollowUpRun(
ActiveCoachMemorySnapshot,
false
);
const TArray<FString> LaunchedCaseIds =
HyperTwistTrainingSubsystemInternal::ExtractCaseIdsFromDeck(FollowUpDeck);
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
@ -1654,7 +1673,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachFollowUpRun(
FString(),
LaunchBudget.RequestedCaseCount,
FollowUpDeck.Cases.Num(),
LaunchBudget.ReasonLine
LaunchBudget.ReasonLine,
LaunchedCaseIds
);
FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
FollowUpDeck,
@ -1748,6 +1768,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartNextQueuedCoachRu
ActiveCoachMemorySnapshot,
true
);
const TArray<FString> LaunchedCaseIds =
HyperTwistTrainingSubsystemInternal::ExtractCaseIdsFromDeck(QueueDeck);
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
QueueBrief,
@ -1756,7 +1778,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartNextQueuedCoachRu
FString(),
LaunchBudget.RequestedCaseCount,
QueueDeck.Cases.Num(),
LaunchBudget.ReasonLine
LaunchBudget.ReasonLine,
LaunchedCaseIds
);
FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(
QueueDeck,
@ -1888,6 +1911,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachQueueEntry(
}
const FHyperTwistTrainingCoachSessionQueueState QueueStateBeforeStart = ActiveCoachSessionQueueState;
const TArray<FString> LaunchedCaseIds =
HyperTwistTrainingSubsystemInternal::ExtractCaseIdsFromDeck(QueueDeck);
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
(!QueueBrief.UserId.IsEmpty() && !QueueBrief.Headline.IsEmpty())
? UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
@ -1897,7 +1922,8 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachQueueEntry(
FString(),
LaunchBudget.RequestedCaseCount,
QueueDeck.Cases.Num(),
LaunchBudget.ReasonLine
LaunchBudget.ReasonLine,
LaunchedCaseIds
)
: FHyperTwistTrainingCoachActionPlan();
FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(

View file

@ -315,7 +315,8 @@ public:
const FString& ReferenceUtc,
int32 RequestedLaunchCaseCount,
int32 PlannedLaunchCaseCount,
const FString& LaunchBudgetReasonLine
const FString& LaunchBudgetReasonLine,
const TArray<FString>& LaunchedCaseIds
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Coach")