85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
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 {};
|
||
}
|
||
}
|