Files
cozsweet-frontend-nextjs/src/data/repositories/metrics_repository.ts
T

64 lines
1.7 KiB
TypeScript

"use client";
/**
* MetricsRepository
*
* 指标/埋点仓库:纯远程 fire-and-forget 上报,无本地状态。
*/
import { MetricsApi, metricsApi } from "@/data/services/api";
import { AppEvent, PwaEvent } from "@/data/dto/metrics";
import { Result } from "@/utils";
import type { IMetricsRepository } from "@/data/repositories/interfaces";
import { createLazySingleton } from "./lazy_singleton";
export class MetricsRepository implements IMetricsRepository {
constructor(private readonly api: MetricsApi) {}
/**
* 上报 PWA 事件。
* 自动注入当前秒级时间戳。
*/
async reportPwaEvent(input: {
deviceId: string;
deviceType: string;
pwaInstalled: boolean;
pwaSupported: boolean;
}): Promise<Result<void>> {
return Result.wrap(async () => {
await this.api.reportPwaEvent(
PwaEvent.from({
deviceId: input.deviceId,
deviceType: input.deviceType,
timestamp: Math.floor(Date.now() / 1000),
pwaInstalled: input.pwaInstalled,
pwaSupported: input.pwaSupported,
}),
);
});
}
/**
* 上报用户环境信息(浏览器、UA 等)。
*/
async reportUserInfo(input: {
userId: string;
browser: string;
userAgent: string;
}): Promise<Result<void>> {
return Result.wrap(async () => {
await this.api.reportUserInfo(
AppEvent.from({
userId: input.userId,
browser: input.browser,
userAgent: input.userAgent,
}),
);
});
}
}
/** 全局懒单例。 */
export const getMetricsRepository = createLazySingleton<IMetricsRepository>(
() => new MetricsRepository(metricsApi),
);