feat(msg): 完整实现 msg 消息服务
包含 channels/preferences/templates/grpc/kafka/outbox/push/redis 等完整实现
This commit is contained in:
84
services/msg/src/grpc/preferences.grpc.controller.ts
Normal file
84
services/msg/src/grpc/preferences.grpc.controller.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { Controller } from "@nestjs/common";
|
||||
import { GrpcMethod } from "@nestjs/microservices";
|
||||
import { PreferencesService } from "../preferences/preferences.service.js";
|
||||
import { updatePreferencesSchema } from "../preferences/preferences.dto.js";
|
||||
import type { NotificationPreference } from "../notifications/notifications.schema.js";
|
||||
|
||||
/**
|
||||
* PreferencesGrpcController —— gRPC 入口(NotificationPreferenceService 2 RPC)。
|
||||
*
|
||||
* 仲裁依据:
|
||||
* - msg.proto §NotificationPreferenceService(GetPreferences / UpdatePreferences)
|
||||
* - proto-loader 默认 keepCase=false,字段名 camelCase
|
||||
*/
|
||||
|
||||
interface GrpcPreference {
|
||||
id: string;
|
||||
userId: string;
|
||||
type: string;
|
||||
channels: string[];
|
||||
frequencyLimit: number;
|
||||
quietHoursStart: string;
|
||||
quietHoursEnd: string;
|
||||
quietHoursTimezone: string;
|
||||
enabled: boolean;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
}
|
||||
|
||||
function opt(val: unknown): string | undefined {
|
||||
if (typeof val === "string" && val.length > 0) return val;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function toGrpcPreference(p: NotificationPreference): GrpcPreference {
|
||||
return {
|
||||
id: p.id,
|
||||
userId: p.userId,
|
||||
type: p.type,
|
||||
channels: p.channels,
|
||||
frequencyLimit: p.frequencyLimit ?? 0,
|
||||
quietHoursStart: p.quietHoursStart ?? "",
|
||||
quietHoursEnd: p.quietHoursEnd ?? "",
|
||||
quietHoursTimezone: p.quietHoursTimezone ?? "",
|
||||
enabled: p.enabled,
|
||||
createdAt: p.createdAt instanceof Date ? p.createdAt.getTime() : 0,
|
||||
updatedAt: p.updatedAt instanceof Date ? p.updatedAt.getTime() : 0,
|
||||
};
|
||||
}
|
||||
|
||||
@Controller()
|
||||
export class PreferencesGrpcController {
|
||||
constructor(private readonly service: PreferencesService) {}
|
||||
|
||||
@GrpcMethod("NotificationPreferenceService", "GetPreferences")
|
||||
async getPreferences(
|
||||
data: Record<string, unknown>,
|
||||
): Promise<{ preferences: GrpcPreference[] }> {
|
||||
const prefs = await this.service.getByUserId(String(data.userId ?? ""));
|
||||
return { preferences: prefs.map(toGrpcPreference) };
|
||||
}
|
||||
|
||||
@GrpcMethod("NotificationPreferenceService", "UpdatePreferences")
|
||||
async updatePreferences(
|
||||
data: Record<string, unknown>,
|
||||
): Promise<Record<string, never>> {
|
||||
const rawPrefs = Array.isArray(data.preferences) ? data.preferences : [];
|
||||
|
||||
const dto = updatePreferencesSchema.parse({
|
||||
userId: data.userId,
|
||||
preferences: rawPrefs.map((p: Record<string, unknown>) => ({
|
||||
type: p.type,
|
||||
channels: Array.isArray(p.channels) ? p.channels : [],
|
||||
frequencyLimit: p.frequencyLimit ? Number(p.frequencyLimit) : undefined,
|
||||
quietHoursStart: opt(p.quietHoursStart),
|
||||
quietHoursEnd: opt(p.quietHoursEnd),
|
||||
quietHoursTimezone: opt(p.quietHoursTimezone),
|
||||
enabled: p.enabled ?? true,
|
||||
})),
|
||||
});
|
||||
|
||||
await this.service.update(dto);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user