@@ -72,6 +72,8 @@ public class ClientStrategy : IStrategy
7272 private Download . Abstractions . IDownloadExecutor ? _customDownloadExecutor ;
7373 private Func < string ? , Download . Abstractions . IDownloadPipeline > ? _customDownloadPipelineFactory ;
7474 private int _mainRecordId ;
75+ private int _upgradeRecordId ;
76+ private int _reportType = 1 ; // 1=Upgrade(active poll), 2=Push(SignalR push)
7577
7678 /// <summary>
7779 /// Update scenario determined by the server validation result, indicating which update targets are needed.
@@ -160,6 +162,16 @@ public ClientStrategy(Download.Abstractions.IDownloadOrchestrator? orchestrator)
160162 /// </remarks>
161163 public void SetOrchestrator ( Download . Abstractions . IDownloadOrchestrator ? orchestrator ) => _orchestrator = orchestrator ;
162164
165+ /// <summary>
166+ /// Sets the report type for status reporting. Injected by the bootstrap for push-triggered updates.
167+ /// </summary>
168+ /// <param name="reportType">1 = Upgrade (active poll), 2 = Push (SignalR push). Default is 1.</param>
169+ /// <remarks>
170+ /// When a push notification triggers the update (via SignalR hub), the caller should set this to 2
171+ /// so the server can distinguish push-triggered updates from active poll updates.
172+ /// </remarks>
173+ public void SetReportType ( int reportType ) => _reportType = reportType ;
174+
163175 /// <summary>
164176 /// Sets a custom download retry policy. Registered and injected by the bootstrap via <c>.DownloadPolicy<T>()</c>.
165177 /// </summary>
@@ -427,8 +439,13 @@ private async Task ExecuteStandardWorkflowAsync()
427439
428440 var updateInfoArgs = new UpdateInfoEventArgs ( versionResp ) ;
429441
430- // Capture the first RecordId for status reporting to GeneralSpacestation
431- _mainRecordId = downloadPlan . Assets . FirstOrDefault ( ) . RecordId ;
442+ // Capture RecordIds per AppType for status reporting.
443+ // Client packages are reported by UpdateStrategy (Bowl) via IPC; Upgrade packages
444+ // are applied in-place and reported by ClientStrategy.
445+ _mainRecordId = downloadPlan . Assets
446+ . FirstOrDefault ( a => ( a . AppType ?? ( int ) AppType . Client ) == ( int ) AppType . Client ) ? . RecordId ?? 0 ;
447+ _upgradeRecordId = downloadPlan . Assets
448+ . FirstOrDefault ( a => a . AppType == ( int ) AppType . Upgrade ) ? . RecordId ?? 0 ;
432449 EventManager . Instance . Dispatch ( this , updateInfoArgs ) ;
433450
434451 var isForcibly = downloadPlan . IsForcibly ;
@@ -504,6 +521,7 @@ private async Task ExecuteStandardWorkflowAsync()
504521 // Build VersionInfo list with AppType preserved from server response.
505522 var downloadVersions = downloadPlan . Assets . Select ( a => new VersionInfo
506523 {
524+ RecordId = a . RecordId ,
507525 Name = a . Name ,
508526 Hash = a . SHA256 ,
509527 Url = a . Url ,
@@ -523,24 +541,29 @@ private async Task ExecuteStandardWorkflowAsync()
523541 case UpdateScenario . UpgradeOnly :
524542 await ApplyUpgradePackagesAsync ( upgradeVersions ) . ConfigureAwait ( false ) ;
525543 await SafeOnAfterUpdateAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
526- await SafeReportUpdateAppliedAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
544+ await SafeReportUpdateAppliedAsync ( hooksCtx , _upgradeRecordId ) . ConfigureAwait ( false ) ;
527545 GeneralTracer . Info ( "ClientStrategy: Upgrade-only update applied, client continues running." ) ;
528546 break ;
529547
530548 case UpdateScenario . MainOnly :
531549 SendProcessIpc ( clientVersions ) ;
550+ await SafeOnAfterUpdateAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
551+ await SafeReportUpdateAppliedAsync ( hooksCtx , _mainRecordId ) . ConfigureAwait ( false ) ;
532552 await SafeOnBeforeStartAppAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
533553 await LaunchUpgradeProcessAsync ( ) . ConfigureAwait ( false ) ;
534554 break ;
535555
536556 case UpdateScenario . Both :
537557 await ApplyUpgradePackagesAsync ( upgradeVersions ) . ConfigureAwait ( false ) ;
538558 await SafeOnAfterUpdateAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
539- await SafeReportUpdateAppliedAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
559+ await SafeReportUpdateAppliedAsync ( hooksCtx , _upgradeRecordId ) . ConfigureAwait ( false ) ;
540560 SendProcessIpc ( clientVersions ) ;
541561 await SafeOnBeforeStartAppAsync ( hooksCtx ) . ConfigureAwait ( false ) ;
542562 await LaunchUpgradeProcessAsync ( ) . ConfigureAwait ( false ) ;
543563 break ;
564+ case UpdateScenario . None :
565+ default :
566+ throw new ArgumentOutOfRangeException ( ) ;
544567 }
545568 }
546569
@@ -584,7 +607,8 @@ private void SendProcessIpc(List<VersionInfo> clientVersions)
584607 _configInfo ! , clientVersions ,
585608 _configInfo ! . BlackFormats ?? BlackListDefaults . DefaultBlackFormats ,
586609 _configInfo . BlackFiles ?? BlackListDefaults . DefaultBlackFiles ,
587- _configInfo . SkipDirectorys ?? BlackListDefaults . DefaultSkipDirectories ) ;
610+ _configInfo . SkipDirectorys ?? BlackListDefaults . DefaultSkipDirectories ,
611+ _reportType ) ;
588612
589613 _configInfo . ProcessInfo = JsonSerializer . Serialize ( processInfo ,
590614 ProcessInfoJsonContext . Default . ProcessInfo ) ;
@@ -883,7 +907,7 @@ private async Task SafeReportUpdateStartedAsync(Hooks.UpdateContext ctx)
883907 {
884908 await Reporter
885909 . ReportAsync ( new Download . Reporting . UpdateReport ( _mainRecordId ,
886- ( int ) Download . Reporting . UpdateStatus . Updating , 1 ) ) . ConfigureAwait ( false ) ;
910+ ( int ) Download . Reporting . UpdateStatus . Updating , _reportType ) ) . ConfigureAwait ( false ) ;
887911 }
888912 catch ( Exception ex )
889913 {
@@ -901,7 +925,7 @@ private async Task SafeReportDownloadCompletedAsync(Hooks.UpdateContext ctx)
901925 {
902926 await Reporter
903927 . ReportAsync ( new Download . Reporting . UpdateReport ( _mainRecordId ,
904- ( int ) Download . Reporting . UpdateStatus . Updating , 1 ) ) . ConfigureAwait ( false ) ;
928+ ( int ) Download . Reporting . UpdateStatus . Updating , _reportType ) ) . ConfigureAwait ( false ) ;
905929 }
906930 catch ( Exception ex )
907931 {
@@ -920,7 +944,7 @@ private async Task SafeReportUpdateFailedAsync(Hooks.UpdateContext ctx, Exceptio
920944 {
921945 await Reporter
922946 . ReportAsync ( new Download . Reporting . UpdateReport ( _mainRecordId ,
923- ( int ) Download . Reporting . UpdateStatus . Failure , 1 ) ) . ConfigureAwait ( false ) ;
947+ ( int ) Download . Reporting . UpdateStatus . Failure , _reportType ) ) . ConfigureAwait ( false ) ;
924948 }
925949 catch ( Exception ex )
926950 {
@@ -932,13 +956,13 @@ await Reporter
932956 /// Safely reports the update applied success status. If the report fails, logs a warning.
933957 /// </summary>
934958 /// <param name="ctx">The update context.</param>
935- private async Task SafeReportUpdateAppliedAsync ( Hooks . UpdateContext ctx )
959+ private async Task SafeReportUpdateAppliedAsync ( Hooks . UpdateContext ctx , int recordId )
936960 {
937961 try
938962 {
939963 await Reporter
940- . ReportAsync ( new Download . Reporting . UpdateReport ( _mainRecordId ,
941- ( int ) Download . Reporting . UpdateStatus . Success , 1 ) ) . ConfigureAwait ( false ) ;
964+ . ReportAsync ( new Download . Reporting . UpdateReport ( recordId ,
965+ ( int ) Download . Reporting . UpdateStatus . Success , _reportType ) ) . ConfigureAwait ( false ) ;
942966 }
943967 catch ( Exception ex )
944968 {
0 commit comments