diff --git a/src/modules/course-plans/lib/track-event.ts b/src/modules/course-plans/lib/track-event.ts index d316706..f0225cb 100644 --- a/src/modules/course-plans/lib/track-event.ts +++ b/src/modules/course-plans/lib/track-event.ts @@ -6,14 +6,16 @@ * * 注意:此文件不得标记 "use server",因为 trackCoursePlanEvent 是同步函数, * 不涉及服务端操作。Next.js 16 要求 "use server" 文件中所有导出必须是 async 函数。 + * + * 客户端不能导入服务端 pino logger,因此当前为纯 no-op。 + * 后续接入客户端监控 SDK(如 PostHog/Amplitude)时替换实现即可。 */ export function trackCoursePlanEvent( event: string, properties?: Record, ): void { - // 预留:接入监控 SDK 后实现 - if (process.env.NODE_ENV === "development") { - console.debug(`[course-plans] ${event}`, properties) - } + // no-op: 预留接口,接入客户端监控 SDK 后实现 + void event + void properties } diff --git a/src/modules/questions/utils/track-event.ts b/src/modules/questions/utils/track-event.ts index 58ad45e..6c7ce4b 100644 --- a/src/modules/questions/utils/track-event.ts +++ b/src/modules/questions/utils/track-event.ts @@ -6,6 +6,10 @@ * 无需修改调用方代码。 */ +import { createModuleLogger } from "@/shared/lib/logger" + +const log = createModuleLogger("question-track") + /** 题库操作事件类型 */ export type QuestionEventType = | "question:create" @@ -45,7 +49,7 @@ export interface QuestionEventPayload { export function trackQuestionEvent(payload: QuestionEventPayload): void { // no-op: 预留接口,接入监控系统时替换实现 if (process.env.NODE_ENV === "development") { - console.debug("[trackQuestionEvent]", payload) + log.debug({ payload }, "question track event") } } diff --git a/src/modules/rbac/lib/track.ts b/src/modules/rbac/lib/track.ts index 29d43e0..4a153e2 100644 --- a/src/modules/rbac/lib/track.ts +++ b/src/modules/rbac/lib/track.ts @@ -6,6 +6,10 @@ * PostHog, Mixpanel, or an internal event pipeline) when ready. */ +import { createModuleLogger } from "@/shared/lib/logger" + +const log = createModuleLogger("rbac-track") + /** The RBAC action being tracked. */ export type TrackPermissionAction = | "set_role_permissions" @@ -28,13 +32,13 @@ export interface TrackPermissionChangeParams { /** * Track a permission/role change. * - * Currently a no-op (console.debug only). The interface is stable so call + * Currently a no-op (logger.debug only). The interface is stable so call * sites can be wired up without touching the actions layer again. */ export function trackPermissionChange(params: TrackPermissionChangeParams): void { // Reserved for future analytics implementation. // Intentionally minimal: avoid importing heavy SDKs until needed. if (process.env.NODE_ENV !== "production") { - console.debug("[rbac:track]", params) + log.debug({ params }, "rbac track") } } diff --git a/src/shared/lib/track-event.ts b/src/shared/lib/track-event.ts index 267e407..23b174b 100644 --- a/src/shared/lib/track-event.ts +++ b/src/shared/lib/track-event.ts @@ -1,5 +1,7 @@ import "server-only" +import { createModuleLogger } from "@/shared/lib/logger" + /** * 监控埋点接口(预留) * @@ -8,11 +10,13 @@ import "server-only" * - 通知发送失败告警 * - 用户行为漏斗分析 * - * 当前实现:输出到 console.info,不阻塞主流程。 + * 当前实现:输出到 logger.info,不阻塞主流程。 * 后续扩展:可接入外部监控服务(如 Sentry / PostHog / 自建埋点系统), * 只需在 trackEventToSink 中替换实现即可,调用方无需改动。 */ +const log = createModuleLogger("track") + /** 事件名称(使用点号分隔的命名空间,如 "announcement.published") */ export type EventName = | "announcement.created" @@ -137,12 +141,19 @@ export interface TrackEventPayload { /** * 将事件发送到外部监控服务。 * - * 当前为占位实现:仅输出到 console.info。 + * 当前为占位实现:仅输出到 logger.info。 * 接入真实服务时替换此函数体即可。 */ function trackEventToSink(payload: TrackEventPayload): void { - console.info( - `[TrackEvent] ${payload.event} userId=${payload.userId ?? "-"} targetId=${payload.targetId ?? "-"}${payload.properties ? ` properties=${JSON.stringify(payload.properties)}` : ""}` + log.info( + { + event: payload.event, + userId: payload.userId, + targetId: payload.targetId, + targetType: payload.targetType, + properties: payload.properties, + }, + "track event" ) }