Skip to content

Commit 3ffe2f1

Browse files
committed
✨ feat(updates): add recovered and recovery-failed operation phases
- Add recovered-cleanup-temp, recovered-rollback, recovered-active, recovery-failed, and recovery-missing-containers phases to the operation phase enum - Mirror the phase list in the UI update-operation type so mappers and filters accept them - List handler and container mapper preserve recovered phases from valid terminal operations
1 parent c6a9930 commit 3ffe2f1

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed

app/api/container/handlers/list.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,30 @@ describe('attachInProgressUpdateOperation', () => {
9696
});
9797
});
9898

99+
test('keeps recovered rollback phases from valid terminal operations', () => {
100+
const container = createContainer();
101+
const context = createMockContext({
102+
id: 'op-recovered',
103+
status: 'rolled-back',
104+
phase: 'recovered-rollback',
105+
updatedAt: '2026-04-01T12:00:00.000Z',
106+
fromVersion: '1.0.1',
107+
toVersion: '1.0.0',
108+
});
109+
110+
expect(attachInProgressUpdateOperation(context, container)).toEqual({
111+
...container,
112+
updateOperation: {
113+
id: 'op-recovered',
114+
status: 'rolled-back',
115+
phase: 'recovered-rollback',
116+
updatedAt: '2026-04-01T12:00:00.000Z',
117+
fromVersion: '1.0.1',
118+
toVersion: '1.0.0',
119+
},
120+
});
121+
});
122+
99123
test('keeps valid batch queue metadata from active operations', () => {
100124
const container = createContainer();
101125
const context = createMockContext({

app/model/container-update-operation.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ describe('container update operation guards', () => {
1414

1515
test('accepts known phases and rejects non-phase values', () => {
1616
expect(isContainerUpdateOperationPhase('pulling')).toBe(true);
17+
expect(isContainerUpdateOperationPhase('recovered-rollback')).toBe(true);
1718
expect(isContainerUpdateOperationPhase('rollback-deferred')).toBe(true);
1819
expect(isContainerUpdateOperationPhase('rollback-failed')).toBe(true);
1920
expect(isContainerUpdateOperationPhase('unknown')).toBe(false);

app/model/container-update-operation.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export const CONTAINER_UPDATE_OPERATION_PHASES = [
2121
'health-gate',
2222
'health-gate-passed',
2323
'succeeded',
24+
'recovered-cleanup-temp',
25+
'recovered-rollback',
26+
'recovered-active',
27+
'recovery-failed',
28+
'recovery-missing-containers',
2429
'rollback-started',
2530
'rolled-back',
2631
'rollback-deferred',

ui/src/types/update-operation.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,14 @@ export const CONTAINER_UPDATE_OPERATION_PHASES = [
2121
'health-gate',
2222
'health-gate-passed',
2323
'succeeded',
24+
'recovered-cleanup-temp',
25+
'recovered-rollback',
26+
'recovered-active',
27+
'recovery-failed',
28+
'recovery-missing-containers',
2429
'rollback-started',
2530
'rolled-back',
31+
'rollback-deferred',
2632
'rollback-failed',
2733
] as const;
2834

ui/tests/utils/container-mapper.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,30 @@ describe('container-mapper', () => {
198198
targetImage: 'nginx:1.1.0',
199199
});
200200
});
201+
202+
it('maps recovered rollback phases from valid terminal update-operation payloads', () => {
203+
const c = mapApiContainer(
204+
makeApiContainer({
205+
updateOperation: {
206+
id: 'op-recovered',
207+
status: 'rolled-back',
208+
phase: 'recovered-rollback',
209+
updatedAt: '2026-04-01T12:00:00.000Z',
210+
fromVersion: '1.0.1',
211+
toVersion: '1.0.0',
212+
},
213+
}),
214+
);
215+
216+
expect(c.updateOperation).toEqual({
217+
id: 'op-recovered',
218+
status: 'rolled-back',
219+
phase: 'recovered-rollback',
220+
updatedAt: '2026-04-01T12:00:00.000Z',
221+
fromVersion: '1.0.1',
222+
toVersion: '1.0.0',
223+
});
224+
});
201225
});
202226

203227
describe('deriveRegistry', () => {

0 commit comments

Comments
 (0)