@@ -108,9 +108,27 @@ const DocumentDetails = (): React.JSX.Element => {
108108 if ( isRichData ) {
109109 // Full replacement from subscription — allows clearing stale fields
110110 // (e.g., after reprocess). This is the common path during active processing.
111+ // However, protect against subscription events (e.g. claimReview/releaseReview)
112+ // that carry empty Sections/Pages overwriting data loaded by getDocument.
111113 if ( JSON . stringify ( document ) !== JSON . stringify ( incomingDoc ) ) {
112- logger . debug ( 'Full document replacement from subscription data' ) ;
113- setDocument ( incomingDoc ) ;
114+ const existingSections = ( document as Record < string , unknown > ) . sections as unknown [ ] | undefined ;
115+ const incomingSections = ( incomingDoc as Record < string , unknown > ) . sections as unknown [ ] | undefined ;
116+ if ( Array . isArray ( existingSections ) && existingSections . length > 0 && ( ! incomingSections || incomingSections . length === 0 ) ) {
117+ // Incoming would wipe sections — overlay only changed scalar fields
118+ const merged = { ...document } as Record < string , unknown > ;
119+ const incoming = incomingDoc as Record < string , unknown > ;
120+ Object . keys ( incoming ) . forEach ( ( key ) => {
121+ const val = incoming [ key ] ;
122+ if ( val === null || val === undefined ) return ;
123+ if ( Array . isArray ( val ) && val . length === 0 ) return ;
124+ ( merged as Record < string , unknown > ) [ key ] = val ;
125+ } ) ;
126+ logger . debug ( 'Preserving sections from getDocument, merging subscription fields' ) ;
127+ setDocument ( merged as MappedDocument ) ;
128+ } else {
129+ logger . debug ( 'Full document replacement from subscription data' ) ;
130+ setDocument ( incomingDoc ) ;
131+ }
114132 }
115133 return ;
116134 }
0 commit comments