diff --git a/lambda/aggregator/handler.py b/lambda/aggregator/handler.py index c4cef1e..72dcb5b 100644 --- a/lambda/aggregator/handler.py +++ b/lambda/aggregator/handler.py @@ -193,6 +193,7 @@ def process_quest(event_id: str, quest: dict, event_items: set[str]) -> None: { "id": report.get("id", report.get("report_id", "")), "reporter": report.get("reporter", ""), + "reporterId": report.get("reporter_id", ""), "reporterName": report.get("reporter_name", ""), "runcount": report.get("runcount", 0), "timestamp": report.get("timestamp", ""), diff --git a/lambda/aggregator/test_handler.py b/lambda/aggregator/test_handler.py index 141d790..b72edd2 100644 --- a/lambda/aggregator/test_handler.py +++ b/lambda/aggregator/test_handler.py @@ -2,7 +2,7 @@ import os import sys -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch # boto3 はテスト環境に存在しないため、インポート前にモック化する os.environ.setdefault("S3_BUCKET_NAME", "test-bucket") @@ -10,8 +10,6 @@ sys.modules["botocore"] = MagicMock() sys.modules["botocore.exceptions"] = MagicMock() -from unittest.mock import patch - from handler import detect_event_items, is_raw_count_report, process_quest, transform_report # noqa: E402 diff --git a/viewer/src/aggregate.test.ts b/viewer/src/aggregate.test.ts index 6981bf3..7e4b843 100644 --- a/viewer/src/aggregate.test.ts +++ b/viewer/src/aggregate.test.ts @@ -6,6 +6,7 @@ function makeReport(id: string, runcount: number, items: Record{children}; + if (!id || id === "anonymous") return <>{children}; return ( {children} @@ -172,17 +172,17 @@ export function ReporterSummary({ eventId, quests, exclusions }: Props) { {i + 1} - {r.reporter} - + - + {r.xId} - + {r.reportCount.toLocaleString()} {r.totalRuns.toLocaleString()} diff --git a/viewer/src/reportTableUtils.test.ts b/viewer/src/reportTableUtils.test.ts index 068fab3..b38d355 100644 --- a/viewer/src/reportTableUtils.test.ts +++ b/viewer/src/reportTableUtils.test.ts @@ -7,6 +7,7 @@ function makeReport(overrides: Partial = {}): Report { return { id: "r1", reporter: "user1", + reporterId: "", reporterName: "User 1", runcount: 100, timestamp: "2026-01-01T00:00:00Z", diff --git a/viewer/src/reporterSummaryUtils.test.ts b/viewer/src/reporterSummaryUtils.test.ts index 54e2121..bd385e1 100644 --- a/viewer/src/reporterSummaryUtils.test.ts +++ b/viewer/src/reporterSummaryUtils.test.ts @@ -11,6 +11,7 @@ function makeQuestData( reporter: string; reporterName: string; runcount: number; + reporterId?: string; }>, ): QuestData { return { @@ -18,6 +19,7 @@ function makeQuestData( lastUpdated: "2026-01-01T00:00:00Z", reports: reports.map((r) => ({ ...r, + reporterId: r.reporterId ?? "", timestamp: "2026-01-01T00:00:00Z", note: "", items: {}, @@ -118,13 +120,46 @@ describe("aggregateReporters", () => { expect(rows[0].details[0].runcount).toBe(50); expect(rows[0].details[0].reportId).toBe("r1"); }); + + test("reporterId を ReporterRow に伝える", () => { + const data = [ + makeQuestData("q1", "Quest 1", [ + { + id: "r1", + reporter: "user1", + reporterName: "User 1", + runcount: 100, + reporterId: "owner-abc", + }, + ]), + ]; + const rows = aggregateReporters(data, {}); + expect(rows[0].reporterId).toBe("owner-abc"); + }); + + test("最初の報告の reporterId が空でも後続報告の値で補完する", () => { + const data = [ + makeQuestData("q1", "Quest 1", [ + { id: "r1", reporter: "user1", reporterName: "User 1", runcount: 100, reporterId: "" }, + { + id: "r2", + reporter: "user1", + reporterName: "User 1", + runcount: 50, + reporterId: "owner-abc", + }, + ]), + ]; + const rows = aggregateReporters(data, {}); + expect(rows[0].reporterId).toBe("owner-abc"); + }); }); describe("sortRows", () => { const rows: ReporterRow[] = [ - { reporter: "A", xId: "a", reportCount: 3, totalRuns: 100, details: [] }, - { reporter: "B", xId: "b", reportCount: 1, totalRuns: 300, details: [] }, - { reporter: "C", xId: "c", reportCount: 2, totalRuns: 200, details: [] }, + { reporter: "A", reporterId: "", xId: "a", reportCount: 3, totalRuns: 100, details: [] }, + { reporter: "B", reporterId: "", xId: "b", reportCount: 1, totalRuns: 300, details: [] }, + { reporter: "C", reporterId: "", xId: "c", reportCount: 2, totalRuns: 200, details: [] }, ]; test("totalRuns 昇順", () => { diff --git a/viewer/src/reporterSummaryUtils.ts b/viewer/src/reporterSummaryUtils.ts index 16c85b7..01adb79 100644 --- a/viewer/src/reporterSummaryUtils.ts +++ b/viewer/src/reporterSummaryUtils.ts @@ -11,6 +11,7 @@ export interface ReportDetail { export interface ReporterRow { reporter: string; + reporterId: string; xId: string; reportCount: number; totalRuns: number; @@ -46,11 +47,14 @@ export function aggregateReporters( const name = getReporterName(r); const entry = map.get(name) ?? { reporter: name, + reporterId: r.reporterId || "", xId: r.reporter || "", reportCount: 0, totalRuns: 0, details: [], }; + if (!entry.reporterId && r.reporterId) entry.reporterId = r.reporterId; + if (!entry.xId && r.reporter) entry.xId = r.reporter; entry.reportCount += 1; entry.totalRuns += r.runcount; entry.details.push({ diff --git a/viewer/src/types.ts b/viewer/src/types.ts index 83a0f91..cbd5197 100644 --- a/viewer/src/types.ts +++ b/viewer/src/types.ts @@ -26,6 +26,7 @@ export interface EventsResponse { export interface Report { id: string; reporter: string; + reporterId: string; reporterName: string; runcount: number; timestamp: string;