fix: 빌드 완료 뒤 오픈 공지를 복원한다

This commit is contained in:
2026-08-27 02:41:36 +00:00
parent 957c619cf8
commit c895ab18d2
5 changed files with 54 additions and 18 deletions
+3 -3
View File
@@ -1406,13 +1406,13 @@ export const adminRouter = router({
install: input.install,
requestedSource: input.sourceMode,
releaseSource: { mode: sourceMode, ref: sourceRef },
...(input.publishSchedule && selectedScenario
...(selectedScenario && input.install.preopenAt && input.install.openAt
? {
publicAnnouncement: {
enabled: true,
enabled: input.publishSchedule,
scenarioId: selectedScenario.id,
scenarioTitle: selectedScenario.title,
scheduledAt: input.scheduledAt,
scheduledAt: input.scheduledAt ?? null,
preopenAt: input.install.preopenAt,
openAt: input.install.openAt,
turnTermMinutes: input.install.turnTermMinutes,
@@ -25,7 +25,7 @@ type PublicAutorunOption = (typeof PUBLIC_AUTORUN_OPTIONS)[number];
export type LobbyUpcomingReset = {
phase: 'SCHEDULED' | 'PREPARING' | 'READY' | 'DELAYED';
scheduledAt: string;
scheduledAt: string | null;
preopenAt: string;
openAt: string;
scenarioId: number;
@@ -215,7 +215,7 @@ export const resolveUpcomingResetAnnouncement = (
if (operation.type !== 'RESET' || !['QUEUED', 'RUNNING', 'SUCCEEDED'].includes(operation.status)) return null;
const payload = asRecord(operation.payload);
const announcement = asRecord(payload?.publicAnnouncement);
if (!announcement || announcement.enabled !== true) return null;
if (!announcement || (announcement.enabled !== true && operation.status !== 'SUCCEEDED')) return null;
const scheduledAt = readDateTime(announcement.scheduledAt);
const preopenAt = readDateTime(announcement.preopenAt);
@@ -226,7 +226,7 @@ export const resolveUpcomingResetAnnouncement = (
const defaultStatTotal = readFiniteNumber(announcement.defaultStatTotal);
const autorunUser = readAutorun(announcement.autorunUser);
if (
!scheduledAt ||
(announcement.enabled === true && !scheduledAt) ||
!preopenAt ||
!openAt ||
!Number.isInteger(scenarioId) ||
@@ -248,7 +248,7 @@ export const resolveUpcomingResetAnnouncement = (
? 'DELAYED'
: operation.status === 'SUCCEEDED'
? 'READY'
: operation.status === 'RUNNING' || nowMs >= new Date(scheduledAt).getTime()
: operation.status === 'RUNNING' || (scheduledAt && nowMs >= new Date(scheduledAt).getTime())
? 'PREPARING'
: 'SCHEDULED';
return {
@@ -772,6 +772,35 @@ describe('admin operation API', () => {
},
});
await harness.caller.admin.operations.requestReset({
profileName: 'che:2',
sourceMode: 'COMMIT',
sourceRef: 'HEAD',
install,
});
expect(harness.createdInputs[1]).toMatchObject({
type: 'RESET',
scheduledAt: undefined,
payload: {
install,
publicAnnouncement: {
enabled: false,
scenarioId: 1010,
scenarioTitle: expect.any(String),
scheduledAt: null,
preopenAt: install.preopenAt,
openAt: install.openAt,
turnTermMinutes: 60,
fictionMode: '가상',
npcMode: 0,
defaultStatTotal: expect.any(Number),
otherTextInfo: expect.any(String),
autorunUser: null,
},
},
});
await expect(
harness.caller.admin.operations.requestReset({
profileName: 'che:2',
@@ -96,10 +96,21 @@ describe('resolveUpcomingResetAnnouncement', () => {
}
});
it('fails closed for an unpublished or incomplete snapshot', () => {
it('keeps an unpublished snapshot hidden until a completed build is ready', () => {
const unpublished = buildOperation();
unpublished.payload = { publicAnnouncement: { enabled: false } };
unpublished.payload = {
publicAnnouncement: {
...(unpublished.payload as { publicAnnouncement: Record<string, unknown> }).publicAnnouncement,
enabled: false,
scheduledAt: null,
},
};
expect(resolveUpcomingResetAnnouncement(unpublished, new Date('2026-08-27T04:00:00.000Z'))).toBeNull();
unpublished.status = 'SUCCEEDED';
expect(resolveUpcomingResetAnnouncement(unpublished, new Date('2026-08-27T04:00:00.000Z'))).toMatchObject({
phase: 'READY',
scheduledAt: null,
});
const incomplete = buildOperation();
incomplete.payload = { publicAnnouncement: { enabled: true, scenarioTitle: '황건적의 난' } };