ソースを参照

feat(stats-reporting): add toJsonSafe function for safe serialization of bigint values in stats responses

Dave 1 ヶ月 前
コミット
584e64ae68

+ 20 - 0
apps/box-stats-api/src/common/json/bigint-json.ts

@@ -0,0 +1,20 @@
+export function toJsonSafe(value: unknown): any {
+  if (value === null || value === undefined) return value;
+
+  const t = typeof value;
+
+  if (t === 'bigint') {
+    const n = Number(value);
+    // epoch seconds and counters are safe; if you ever store huge counters, switch to string
+    return Number.isSafeInteger(n) ? n : value.toString();
+  }
+
+  if (t !== 'object') return value;
+
+  if (Array.isArray(value)) return value.map(toJsonSafe);
+
+  const obj = value as Record<string, unknown>;
+  const out: Record<string, unknown> = {};
+  for (const [k, v] of Object.entries(obj)) out[k] = toJsonSafe(v);
+  return out;
+}

+ 5 - 4
apps/box-stats-api/src/feature/stats-reporting/stats-reporting.service.ts

@@ -16,6 +16,7 @@ import {
   alignDayStart,
   alignHourStart,
 } from './stats-reporting.time';
+import { toJsonSafe } from '../../common/json/bigint-json';
 
 interface PaginatedResult<T> {
   page: number;
@@ -75,7 +76,7 @@ export class StatsReportingService {
       this.prisma.adsHourlyStats.count({ where }),
     ]);
 
-    return { page, size, total, items };
+    return { page, size, total, items: toJsonSafe(items) };
   }
 
   async getAdsDaily(dto: AdsStatsQueryDto): Promise<any> {
@@ -109,7 +110,7 @@ export class StatsReportingService {
       this.prisma.adsDailyStats.count({ where }),
     ]);
 
-    return { page, size, total, items };
+    return { page, size, total, items: toJsonSafe(items) };
   }
 
   async getChannelHourlyUsers(dto: ChannelStatsQueryDto): Promise<any> {
@@ -143,7 +144,7 @@ export class StatsReportingService {
       this.prisma.channelHourlyUserStats.count({ where }),
     ]);
 
-    return { page, size, total, items };
+    return { page, size, total, items: toJsonSafe(items) };
   }
 
   async getChannelDailyUsers(dto: ChannelStatsQueryDto): Promise<any> {
@@ -177,7 +178,7 @@ export class StatsReportingService {
       this.prisma.channelDailyUserStats.count({ where }),
     ]);
 
-    return { page, size, total, items };
+    return { page, size, total, items: toJsonSafe(items) };
   }
 
   private normalizePagination({