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

@@ -477,6 +477,25 @@
| 优雅关闭 | HTTP server → Redis → gRPC clients → TracerBFF 无 DB/Kafka关闭顺序简化 |
| ParentSession 值对象 | parentId/roles/dataScope:CHILDREN/requestedChildId/traceId每次请求重建不跨请求004 §12.1 无状态约束) |
| 通知偏好配置 | NotificationPreference渠道开关 channels[] + 频率限制 frequency_limit + 静默时段 quiet_hoursP4 通过 msg 服务管理 |
| P5 msg gRPC 客户端 | MsgClient interface + MockMsgClient + GrpcMsgClientNotificationPreferences RPC 未定义时回退默认偏好(避免下游未实现阻塞 BFF |
| P5 push-gateway HTTP 客户端 | PushHttpClient interface + MockPushHttpClient + HttpPushHttpClientfetch + 3s timeout + AbortController |
| P5 通知偏好过滤 | EVENT_TYPE_MAP 映射事件→通知类型,拉取偏好后检查偏好开关 + channels 交集,跳过关闭偏好的家长推送 |
| P5 Kafka consumer 多 handler | 同一 topic 可注册多个 handlerpush + cache-invalidationhandlers 改为 `Map<string, EventHandler[]>` 支持多 handler |
| P5 Kafka 幂等 + DLQ | event_id Redis SETNX 去重24h TTL+ MAX_RETRIES=3 指数退避 + DLQ `edu.parent-bff.dlq` |
| P5 缓存失效 handler | edu.teaching.grade.recorded→grades+dashboard 失效edu.notification.read/recalled→notifications 失效 |
| P6 opossum 熔断器 | per-service 单例 + 事件监听open/close/halfOpen→circuitStateGauge+ withCircuitBreaker 包装 callWithMetrics开启抛 503 |
| P6 熔断器配置 | timeout 5s / errorThresholdPercentage 50% / resetTimeout 30s / volumeThreshold 10 |
| P6 Helm chart 结构 | Chart.yaml + values.yaml + values-{dev,staging,prod}.yaml + templates/_helpers.tpl + deployment + service + hpa + configmap |
| P6 podAntiAffinity | preferredDuringSchedulingIgnoredDuringExecution + weight 100 + topologyKey kubernetes.io/hostname |
| P6 HPA 多环境 | dev: 1 replica HPA disabledstaging: 2 replicas HPA 2-5prod: 3 replicas HPA 3-10 + CPU 70%/memory 80% |
| P6 SLO 告警规则 | parent-bff-slo 组 9 条告警P95>200ms / 错误率>0.1% / 可用性<99.9% / 熔断器open / 下游错误率>5% / 缓存命中率<50% / Kafka停滞 / push失败率>5% / ChildGuard突增 |
| P6 Grafana 面板 | 11 面板P95延迟/错误率/可用性/熔断器/缓存命中率/ChildGuard/下游QPS/下游P95/Kafka消费/push推送/GraphQL QPS |
| ESM 模式 import 后缀 | 相对 import 用 `.js` 后缀NodeNext 构建产物test 文件 import 源码也用 `.js` 后缀 |
| vitest coverage 配置 | coverage 配置在 `test` 内部vitest v2 API不在根层级exclude 排除基础设施文件gRPC clients/DataLoader/GraphQL 框架/Redis/Kafka|
| 测试覆盖率排除策略 | 基础设施/框架代码gRPC client 实现/DataLoader 工厂/GraphQL 框架设置/Redis client/Kafka consumer需 E2E 测试覆盖,单元/集成测试排除 |
| Kafka consumer Buffer 类型 | kafkajs `message.value` 类型为 `Buffer | null`,传参需 `?? undefined` 转换为 `Buffer | undefined` |
| Mock 客户端 markAsRead 类型 | `MOCK_NOTIFICATIONS[parentId]` 可能 undefined需 `if (!list) continue``list[idx]` 可能 undefined需 `const target = list[idx]; if (target)` 守卫 |
| msg.client callWithMetrics | callWithMetrics 签名是 `(client, method, request, serviceName)`,不是 `("msg", "X", () => fn)` |
### 2.15 student-portal学生端微前端 RemoteP3