감사 수집과 저장 장애를 게임 진행에서 분리한다

This commit is contained in:
2026-09-26 16:26:02 +00:00
parent daf7a87799
commit 6b65633324
22 changed files with 1108 additions and 550 deletions
+90 -3
View File
@@ -86,7 +86,8 @@ const install = async (
denied = false,
baseline: boolean | 'document' | 'created' | 'removed' = false,
executionStatus?: 'PREPARING' | 'BLOCKED',
dashboard = false
dashboard = false,
historyGap = false
) => {
const requests: { operation: string; input: Record<string, unknown> }[] = [];
await page.addInitScript((profile) => {
@@ -166,7 +167,59 @@ const install = async (
{
ordinal: input.cursor === undefined ? 0 : 1,
steps: [
...(input.cursor === undefined ? [{ phase: 'general', generalId: 1, nationId: 2, cityId: 3, npcState: 2, year: 190, month: 6, tick: 100, sequence: 0, kind: 'DECISION_START', reservedAction: '휴식', effectivePolicy: {"schemaVersion":1,"general":{"priority":["징병"],"flags":{"징병":true,"출병":false}},"nation":{"priority":["천도"],"flags":{"천도":true},"values":{"reqNationGold":4321,"reqNationRice":100,"reqHumanWarUrgentGold":100,"reqHumanWarUrgentRice":100,"reqHumanWarRecommandGold":100,"reqHumanWarRecommandRice":100,"reqHumanDevelGold":100,"reqHumanDevelRice":100,"reqNpcWarGold":100,"reqNpcWarRice":100,"reqNpcDevelGold":100,"reqNpcDevelRice":100,"minimumResourceActionAmount":100,"maximumResourceActionAmount":100,"minNpcWarLeadership":100,"minWarCrew":100,"minNpcRecruitCityPopulation":100,"safeRecruitCityPopulationRatio":100,"properWarTrainAtmos":100,"cureThreshold":100},"combatForce":{"1":[2,3]},"supportForce":[4],"developForce":[5]}} }] : []),
...(input.cursor === undefined
? [
{
phase: 'general',
generalId: 1,
nationId: 2,
cityId: 3,
npcState: 2,
year: 190,
month: 6,
tick: 100,
sequence: 0,
kind: 'DECISION_START',
reservedAction: '휴식',
effectivePolicy: {
schemaVersion: 1,
general: {
priority: ['징병'],
flags: { 징병: true, 출병: false },
},
nation: {
priority: ['천도'],
flags: { 천도: true },
values: {
reqNationGold: 4321,
reqNationRice: 100,
reqHumanWarUrgentGold: 100,
reqHumanWarUrgentRice: 100,
reqHumanWarRecommandGold: 100,
reqHumanWarRecommandRice: 100,
reqHumanDevelGold: 100,
reqHumanDevelRice: 100,
reqNpcWarGold: 100,
reqNpcWarRice: 100,
reqNpcDevelGold: 100,
reqNpcDevelRice: 100,
minimumResourceActionAmount: 100,
maximumResourceActionAmount: 100,
minNpcWarLeadership: 100,
minWarCrew: 100,
minNpcRecruitCityPopulation: 100,
safeRecruitCityPopulationRatio: 100,
properWarTrainAtmos: 100,
cureThreshold: 100,
},
combatForce: { '1': [2, 3] },
supportForce: [4],
developForce: [5],
},
},
},
]
: []),
{
phase: 'general',
generalId: 1,
@@ -441,7 +494,13 @@ const install = async (
});
}
case 'playAudit.coverage':
return result({ ...world, status: 'COLLECTED', samples: [], nextCursor: null });
return result({
...world,
historyGap: historyGap ? { firstYear: 190, firstMonth: 4 } : null,
status: 'COLLECTED',
samples: [],
nextCursor: null,
});
case 'playAudit.nations':
return result({
...world,
@@ -1521,3 +1580,31 @@ for (const width of [1280, 390]) {
await capture(page, `audit-ranked-${width}`);
});
}
for (const width of [390, 1280]) {
test(`audit history gap stays visible while browsing at ${width}px`, async ({ page }, testInfo) => {
await page.setViewportSize({ width, height: 900 });
await install(page, false, false, undefined, false, true);
await page.goto(gamePath('/play-audit'));
const notice = page.getByRole('status').filter({ hasText: '감사 이력에 누락된 구간' });
await expect(notice).toContainText('190년 4월');
await page.getByRole('link', { name: '장수', exact: true }).click();
await expect(notice).toBeVisible();
await page.evaluate(() => document.fonts.ready);
const geometry = await notice.evaluate((element) => {
const rect = element.getBoundingClientRect();
const style = getComputedStyle(element);
return {
x: rect.x,
width: rect.width,
height: rect.height,
fontSize: style.fontSize,
viewport: innerWidth,
};
});
expect(geometry.x).toBeGreaterThanOrEqual(0);
expect(geometry.x + geometry.width).toBeLessThanOrEqual(width);
await writeFile(testInfo.outputPath('audit-gap-geometry.json'), JSON.stringify(geometry));
await page.screenshot({ path: testInfo.outputPath('audit-gap.png'), fullPage: true });
});
}
@@ -475,6 +475,10 @@ onMounted(async () => {
현재 {{ coverage.year }}년 {{ coverage.month }}월 · {{ scopeLabel }} · 현재 기수의 수집 자료를
조회합니다.
</p>
<p v-if="coverage.historyGap" role="status">
{{ coverage.historyGap.firstYear }}년 {{ coverage.historyGap.firstMonth }}월 이후 감사 이력에 누락된
구간이 있습니다. 수집된 기록만 표시하며 게임은 계속 진행됩니다.
</p>
<p v-if="coverage.status === 'IDENTITY_MISSING'">
기수 식별자가 없어 과거 자료를 수집하지 못했습니다. 현재 상태만 확인할 수 있습니다.
</p>