merge: 최신 main을 자동 외교 분리 브랜치에 통합한다

This commit is contained in:
2026-08-24 08:15:37 +00:00
7 changed files with 38 additions and 16 deletions
+1 -2
View File
@@ -416,7 +416,6 @@ export const voteRouter = router({
)
.mutation(async ({ ctx, input }) => {
const general = await getMyGeneral(ctx);
const openerName = ctx.auth?.user.username ?? general.name;
const options = normalizeOptions(input.options);
if (options.length === 0) {
throw new TRPCError({ code: 'BAD_REQUEST', message: '항목이 없습니다.' });
@@ -468,7 +467,7 @@ export const voteRouter = router({
${multipleOptions},
${input.revealMode},
${general.id},
${openerName},
${general.name},
${gameTime.now},
${gameTime.tick === null ? null : BigInt(gameTime.tick)},
${endAt},
@@ -287,12 +287,16 @@ integration('generic general creation through the durable turn daemon', () => {
accountIconUpdatedAt: '2026-07-30T00:00:00.000Z',
});
const createdAccess = await db.generalAccessLog.findUniqueOrThrow({ where: { generalId: created.id } });
const acceptedEvent = await db.inputEvent.findUniqueOrThrow({
where: { requestId: `join-create:${userId}:${clientRequestId}` },
});
if (!createdAccess.lastRefresh) {
throw new Error('created general must have an initial access timestamp');
}
expect(createdAccess.lastRefresh).toEqual(acceptedEvent.createdAt);
expect(
new Date((created.meta as Record<string, unknown>).prestart_delete_after as string).getTime() -
createdAccess.lastRefresh.getTime()
acceptedEvent.createdAt.getTime()
).toBe(2 * 5 * 60 * 1_000);
expect(runtime!.world.getGeneralById(created.id)).toMatchObject({
id: created.id,
@@ -354,7 +358,7 @@ integration('generic general creation through the durable turn daemon', () => {
attempts: 1,
actorUserId: userId,
});
expect(access.lastRefresh?.getTime()).toBe(runtime!.world.getGameNow(event.createdAt).getTime());
expect(access.lastRefresh?.getTime()).toBe(event.createdAt.getTime());
const turnGridOffsetSeconds =
((created.turnTime.getTime() - runtime!.world.getState().lastTurnTime.getTime()) / 1000 + 300) % 300;
expect(turnGridOffsetSeconds).toBeGreaterThanOrEqual(35);
@@ -257,12 +257,17 @@ integration('scenario 903 select pool through the durable turn daemon', () => {
const initial = await db.general.findFirstOrThrow({ where: { userId } });
const initialRuntime = runtime!.world.getGeneralById(initial.id);
const initialAccess = await db.generalAccessLog.findUniqueOrThrow({ where: { generalId: initial.id } });
const acceptedEvent = await db.inputEvent.findFirstOrThrow({
where: { actorUserId: userId, eventType: 'selectPoolCreate', status: 'SUCCEEDED' },
orderBy: { sequence: 'desc' },
});
if (!initialAccess.lastRefresh) {
throw new Error('selected general must have an initial access timestamp');
}
expect(initialAccess.lastRefresh).toEqual(acceptedEvent.createdAt);
expect(
new Date((initial.meta as Record<string, unknown>).prestart_delete_after as string).getTime() -
initialAccess.lastRefresh.getTime()
acceptedEvent.createdAt.getTime()
).toBe(2 * 5 * 60 * 1_000);
expect(initialRuntime).toMatchObject({
id: initial.id,
+4 -3
View File
@@ -264,7 +264,7 @@ describe('vote router actor and permission boundaries', () => {
expect(fixture.redisPublish).not.toHaveBeenCalled();
});
it('publishes a global front-status projection after creating a survey', async () => {
it('stores the authenticated general name and publishes a global projection after creating a survey', async () => {
const auth = buildAuth(['admin.survey.open']);
auth.user.username = 'admin-account';
auth.user.displayName = '관리자 표시명';
@@ -285,8 +285,9 @@ describe('vote router actor and permission boundaries', () => {
const insert = fixture.queryRaw.mock.calls
.map(([query]) => query)
.find((query) => sqlText(query).includes('INSERT INTO vote_poll'));
expect(insert?.values).toContain('admin-account');
expect(insert?.values).not.toContain('관리자 장수');
expect(insert?.values).toContain('관리자 장수');
expect(insert?.values).not.toContain('admin-account');
expect(insert?.values).not.toContain('관리자 표시명');
});
it('reports the current world develcost as the legacy five-times survey reward', async () => {