feat: initialize parent-bff service with full core features

add complete parent-bff implementation including:
- GraphQL endpoint with depth/cost validation
- ChildGuard越权校验 with redis cache and singleflight
- parallel orchestration with partial failure fallback
- three-level cache fallback strategy (Redis + LRU + downstream)
- Kafka consumer for cache invalidation and notification push
- opossum circuit breaker for downstream services
- Prometheus metrics and SLO alerts
- Helm chart for k8s deployment with multi-environment configs
- Grafana dashboard for observability
- complete unit and integration tests
This commit is contained in:
SpecialX
2026-07-10 18:49:06 +08:00
parent a7d8f92227
commit 2229309a1e
88 changed files with 11221 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
import { describe, it, expect } from "vitest";
import {
UpdateNotificationPreferencesSchema,
NotificationChannelSchema,
NotificationEventTypesInputSchema,
} from "../../src/parent/dto/parent-inputs.dto.js";
describe("NotificationChannelSchema", () => {
it("接受有效渠道", () => {
expect(NotificationChannelSchema.parse("APP")).toBe("APP");
expect(NotificationChannelSchema.parse("SMS")).toBe("SMS");
expect(NotificationChannelSchema.parse("EMAIL")).toBe("EMAIL");
expect(NotificationChannelSchema.parse("WECHAT")).toBe("WECHAT");
});
it("拒绝无效渠道", () => {
expect(() => NotificationChannelSchema.parse("PUSH")).toThrow();
expect(() => NotificationChannelSchema.parse("")).toThrow();
});
});
describe("NotificationEventTypesInputSchema", () => {
it("接受所有可选布尔字段", () => {
const result = NotificationEventTypesInputSchema.parse({
gradeReleased: true,
homeworkGraded: false,
examPublished: true,
attendanceAlert: false,
schoolAnnouncement: true,
});
expect(result.gradeReleased).toBe(true);
expect(result.homeworkGraded).toBe(false);
});
it("允许部分字段(未传为 undefined", () => {
const result = NotificationEventTypesInputSchema.parse({
gradeReleased: true,
});
expect(result.gradeReleased).toBe(true);
expect(result.homeworkGraded).toBeUndefined();
});
it("接受空对象", () => {
const result = NotificationEventTypesInputSchema.parse({});
expect(result.gradeReleased).toBeUndefined();
});
it("拒绝非布尔值", () => {
expect(() =>
NotificationEventTypesInputSchema.parse({ gradeReleased: "yes" }),
).toThrow();
});
});
describe("UpdateNotificationPreferencesSchema", () => {
it("接受完整有效输入", () => {
const input = {
channels: ["APP", "WECHAT"],
eventTypes: {
gradeReleased: true,
homeworkGraded: false,
},
};
const result = UpdateNotificationPreferencesSchema.parse(input);
expect(result.channels).toEqual(["APP", "WECHAT"]);
expect(result.eventTypes.gradeReleased).toBe(true);
});
it("拒绝空 channels 数组", () => {
expect(() =>
UpdateNotificationPreferencesSchema.parse({
channels: [],
eventTypes: {},
}),
).toThrow();
});
it("拒绝无效 channel 值", () => {
expect(() =>
UpdateNotificationPreferencesSchema.parse({
channels: ["INVALID"],
eventTypes: {},
}),
).toThrow();
});
it("拒绝缺少 channels", () => {
expect(() =>
UpdateNotificationPreferencesSchema.parse({
eventTypes: {},
}),
).toThrow();
});
it("拒绝缺少 eventTypes", () => {
expect(() =>
UpdateNotificationPreferencesSchema.parse({
channels: ["APP"],
}),
).toThrow();
});
it("接受单个 channel", () => {
const result = UpdateNotificationPreferencesSchema.parse({
channels: ["APP"],
eventTypes: {},
});
expect(result.channels).toEqual(["APP"]);
});
});