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:
244
packages/shared-ts/contracts/graphql/parent-bff.graphql
Normal file
244
packages/shared-ts/contracts/graphql/parent-bff.graphql
Normal file
@@ -0,0 +1,244 @@
|
||||
# parent-bff GraphQL Schema(SDL 契约,对齐 02-architecture-design.md §4.2)
|
||||
#
|
||||
# 本文件是 parent-bff GraphQL 端点的契约唯一源(single source of truth)。
|
||||
# - 前端 parent-portal 引用本文件生成 TypeScript 类型
|
||||
# - 后端 parent-bff 引用本文件加载为 GraphQLSchema
|
||||
# - CI 强制检测 breaking change(与 main 分支对比)
|
||||
#
|
||||
# 仲裁依据:
|
||||
# - U3:GraphQL P2 立即引入(parent-bff P4 直接用 GraphQL,不走 REST 过渡)
|
||||
# - C1:错误码前缀 BFF_PARENT_
|
||||
# - U4:BFF 豁免 @RequirePermission,仅校验 x-user-id + ChildGuard
|
||||
# - 02 §9 #5:depth ≤ 7 / cost ≤ 1000
|
||||
|
||||
scalar DateTime
|
||||
|
||||
# ============ Types ============
|
||||
|
||||
type Parent {
|
||||
id: ID!
|
||||
email: String!
|
||||
name: String!
|
||||
avatar: String
|
||||
roles: [String!]!
|
||||
dataScope: DataScope!
|
||||
}
|
||||
|
||||
enum DataScope {
|
||||
SELF
|
||||
CHILDREN
|
||||
CLASS
|
||||
GRADE
|
||||
SCHOOL
|
||||
DISTRICT
|
||||
ALL
|
||||
}
|
||||
|
||||
type ViewportItem {
|
||||
key: String!
|
||||
label: String!
|
||||
route: String!
|
||||
icon: String
|
||||
sortOrder: String!
|
||||
requiredPermission: String
|
||||
}
|
||||
|
||||
type Child {
|
||||
id: ID!
|
||||
name: String!
|
||||
grade: String!
|
||||
class: ClassInfo!
|
||||
lastGrade: Grade
|
||||
grades(page: Int = 1, pageSize: Int = 20, subject: String): GradePage!
|
||||
homework: [Homework!]!
|
||||
exams: [Exam!]!
|
||||
analytics: ChildAnalytics!
|
||||
}
|
||||
|
||||
type ClassInfo {
|
||||
id: ID!
|
||||
name: String!
|
||||
gradeId: String!
|
||||
}
|
||||
|
||||
type Grade {
|
||||
id: ID!
|
||||
examId: ID!
|
||||
examTitle: String!
|
||||
subject: String!
|
||||
score: Float!
|
||||
rank: Int
|
||||
gradedAt: DateTime!
|
||||
}
|
||||
|
||||
type GradePage {
|
||||
items: [Grade!]!
|
||||
pagination: Pagination!
|
||||
}
|
||||
|
||||
type Pagination {
|
||||
page: Int!
|
||||
pageSize: Int!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type Homework {
|
||||
id: ID!
|
||||
title: String!
|
||||
classId: ID!
|
||||
dueDate: DateTime!
|
||||
status: HomeworkStatus!
|
||||
submittedAt: DateTime
|
||||
}
|
||||
|
||||
enum HomeworkStatus {
|
||||
NOT_SUBMITTED
|
||||
SUBMITTED
|
||||
GRADED
|
||||
OVERDUE
|
||||
}
|
||||
|
||||
type Exam {
|
||||
id: ID!
|
||||
title: String!
|
||||
classId: ID!
|
||||
status: ExamStatus!
|
||||
examDate: DateTime!
|
||||
publishedAt: DateTime
|
||||
}
|
||||
|
||||
enum ExamStatus {
|
||||
DRAFT
|
||||
PUBLISHED
|
||||
IN_PROGRESS
|
||||
GRADING
|
||||
SCORED
|
||||
ARCHIVED
|
||||
}
|
||||
|
||||
type ChildAnalytics {
|
||||
childId: ID!
|
||||
weakness: [WeaknessTopic!]!
|
||||
trend: [TrendPoint!]!
|
||||
classRank: Int
|
||||
classAverage: Float
|
||||
}
|
||||
|
||||
type WeaknessTopic {
|
||||
knowledgePointId: ID!
|
||||
name: String!
|
||||
subject: String!
|
||||
masteryRate: Float!
|
||||
}
|
||||
|
||||
type TrendPoint {
|
||||
date: DateTime!
|
||||
score: Float!
|
||||
subject: String
|
||||
}
|
||||
|
||||
type Notification {
|
||||
id: ID!
|
||||
type: NotificationType!
|
||||
title: String!
|
||||
content: String!
|
||||
read: Boolean!
|
||||
childId: ID
|
||||
createdAt: DateTime!
|
||||
}
|
||||
|
||||
enum NotificationType {
|
||||
SYSTEM
|
||||
EXAM
|
||||
HOMEWORK
|
||||
GRADE
|
||||
ATTENDANCE
|
||||
ANNOUNCEMENT
|
||||
}
|
||||
|
||||
type NotificationPreferences {
|
||||
channels: [NotificationChannel!]!
|
||||
eventTypes: NotificationEventTypes!
|
||||
}
|
||||
|
||||
enum NotificationChannel {
|
||||
APP
|
||||
SMS
|
||||
EMAIL
|
||||
WECHAT
|
||||
}
|
||||
|
||||
type NotificationEventTypes {
|
||||
gradeReleased: Boolean!
|
||||
homeworkGraded: Boolean!
|
||||
examPublished: Boolean!
|
||||
attendanceAlert: Boolean!
|
||||
schoolAnnouncement: Boolean!
|
||||
}
|
||||
|
||||
type DashboardData {
|
||||
parent: Parent
|
||||
children: [Child!]!
|
||||
viewports: [ViewportItem!]!
|
||||
unreadNotifications: Int!
|
||||
degraded: Boolean!
|
||||
}
|
||||
|
||||
# ============ Query ============
|
||||
|
||||
type Query {
|
||||
dashboard: DashboardData!
|
||||
viewports: [ViewportItem!]!
|
||||
me: Parent!
|
||||
children: [Child!]!
|
||||
child(childId: ID!): Child
|
||||
childGrades(
|
||||
childId: ID!
|
||||
page: Int = 1
|
||||
pageSize: Int = 20
|
||||
subject: String
|
||||
): GradePage!
|
||||
childHomework(childId: ID!): [Homework!]!
|
||||
childExams(childId: ID!): [Exam!]!
|
||||
childAnalytics(childId: ID!, dateRange: DateRangeInput): ChildAnalytics!
|
||||
notifications(
|
||||
unreadOnly: Boolean
|
||||
page: Int = 1
|
||||
pageSize: Int = 20
|
||||
): [Notification!]!
|
||||
notificationPreferences: NotificationPreferences!
|
||||
}
|
||||
|
||||
input DateRangeInput {
|
||||
start: DateTime!
|
||||
end: DateTime!
|
||||
}
|
||||
|
||||
# ============ Mutation ============
|
||||
|
||||
type Mutation {
|
||||
selectChild(childId: ID!): SelectChildResult!
|
||||
markNotificationRead(notificationId: ID!): Notification!
|
||||
updateNotificationPreferences(
|
||||
input: UpdateNotificationPreferencesInput!
|
||||
): NotificationPreferences!
|
||||
}
|
||||
|
||||
type SelectChildResult {
|
||||
childId: ID!
|
||||
selectedAt: DateTime!
|
||||
audited: Boolean!
|
||||
}
|
||||
|
||||
input UpdateNotificationPreferencesInput {
|
||||
channels: [NotificationChannel!]!
|
||||
eventTypes: NotificationEventTypesInput!
|
||||
}
|
||||
|
||||
input NotificationEventTypesInput {
|
||||
gradeReleased: Boolean
|
||||
homeworkGraded: Boolean
|
||||
examPublished: Boolean
|
||||
attendanceAlert: Boolean
|
||||
schoolAnnouncement: Boolean
|
||||
}
|
||||
Reference in New Issue
Block a user