SpecialX
ce5aeec955
refactor(ai): stateless workflow store with redis-only mode
...
- remove in-memory fallback (ADR-028: ai must be stateless)
- Redis is the only state store, shared across instances
- Redis unavailable raises RedisError instead of degrading to memory
- key prefix workflow -> ai:workflow (spec 4.3)
- TTL 24h -> 1h (spec 4.3: long-lived state managed by Temporal)
Implements M6 of v2.1 migration plan.
2026-07-15 02:22:28 +08:00
SpecialX
1423a0b8eb
feat(core-edu): dataspcope @requires with scopetoken resolution
...
- new DataScopeResolver extends iam UserDataScope via @extends
- visibleGrades @requires(studentScopeToken) + visibleExams @requires(classScopeToken)
- resolve ScopeToken via Redis sMembers to actual ID list (ADR-041)
- add findByStudentIds/findByClassIds/findAll to repositories
- ALL token = full visibility (admin), skip WHERE IN filter
Implements M4 of v2.1 migration plan.
2026-07-15 02:20:15 +08:00
SpecialX
1a5fa78fa6
feat(config-service): split config-service from iam for plugin/layout config
...
- new NestJS service on port 3011/gRPC 50059 (ADR-026)
- owns 6 config_ tables (plugin/role-mapping/role-layout/layout-tpl/user-override/outbox)
- GraphQL Federation 2 subgraph with DataLoader + RouterAuthGuard
- gRPC ConfigService + admin REST CRUD + user REST API
- three-layer merge: registry.defaultProps + roleMapping.widget_props + userOverride.props
- Redis cache with 5min TTL
- registered in apollo-router supergraph + docker-compose + port-allocation
Implements M3 of v2.1 migration plan.
2026-07-15 02:13:03 +08:00
SpecialX
163bff6666
feat(infra): apollo router deployment and supergraph composition
...
M2: Apollo Router replaces BFF manual aggregation (ADR-037)
- Dockerfile: self-contained with rover + router, auto-compose on startup
- router.yaml: CORS, Router-Authorization header injection, traffic shaping
- supergraph.yaml: 6 subgraphs (iam/core-edu/content/msg/ai/data-ana)
- docker-compose: apollo-router on port 3000, depends on all subgraphs
- ROUTER_AUTH_SECRET added to secrets.example.env
- port-allocation.md: apollo-router registered on port 3000
2026-07-15 01:32:14 +08:00
SpecialX
6af1aa0d82
feat(push-gateway,msg): redis pubsub backplane for real-time notifications
...
M7: ADR-040 Redis Pub/Sub as state routing backplane
- push-gateway: remove Kafka consumer, add SSE endpoint
- SSE: subscribe to Redis user:{userId}:notify on connect
- msg: publish notifications to Redis Pub/Sub instead of HTTP push
- docker-compose: remove Kafka env from push-gateway
2026-07-15 01:28:55 +08:00
SpecialX
a75527be80
feat(content): eager invalidation and optimistic lock for cqrs
...
M4: ADR-038 Eager Invalidation + ADR-039 Optimistic Lock
- EagerInvalidationService: Redis DEL after MySQL commit
- Cache key conventions for textbook/chapter/kp/question
- Version header check (If-Match/X-Expected-Version) on write endpoints
- 409 Conflict on version mismatch
- All write endpoints return updatedAt timestamp
2026-07-15 01:28:20 +08:00
SpecialX
47a062606f
refactor(shared-ts,iam,core-edu,content,msg): remove outbox polling publisher
...
M8: Debezium CDC now handles outbox table to Kafka (ADR-032)
- Remove OutboxPublisher class from shared-ts
- Remove publisher from iam/core-edu/content/msg lifecycle and modules
- OutboxService retained for transactional outbox table writes
- Debezium monitors binlog and pushes to Kafka automatically
2026-07-15 01:27:45 +08:00
SpecialX
a3f4fd013e
feat(data-ana): python graphql federation subgraph with strawberry
...
- strawberry-graphql[asgi] dependency added
- 13 Federation 2 types: ClassPerformance/StudentWeakness/Dashboards/Mastery/ErrorBook
- 11 Query resolvers delegate to existing analytics/mastery services
- RouterAuthMiddleware validates Router-Authorization header on /graphql
- GraphQL endpoint mounted at /graphql alongside existing REST endpoints
2026-07-15 00:57:02 +08:00
SpecialX
1dcdcf23fd
feat(ai): python graphql federation subgraph with strawberry
...
- strawberry-graphql[asgi] dependency added
- GeneratedReport and LessonPlanStatus @key types with resolve_reference
- RouterAuthMiddleware validates Router-Authorization header on /graphql
- GraphQL endpoint mounted at /graphql in FastAPI app
- WorkflowStateStore injected for lesson plan status resolution
2026-07-15 00:56:37 +08:00
SpecialX
35aa56537d
chore(ai): add proto-generated graphql schema reference
...
Python service needs strawberry-graphql federation implementation
2026-07-15 00:20:21 +08:00
SpecialX
d3b126ed9d
feat(msg): graphql subgraph with dataloader for notification/template
...
- GraphQLModule: Apollo Federation 2 at /graphql
- Notification/NotificationTemplate @key with @ResolveReference
- RouterAuthGuard: validate Router-Authorization header (ADR-036)
- batchFindByIds added to notifications and templates repositories
2026-07-15 00:19:26 +08:00
SpecialX
d59c4e585f
feat(content): graphql subgraph with dataloader for textbook/chapter/kp/question
...
- GraphQLModule: Apollo Federation 2 at /graphql
- Textbook/Chapter/KnowledgePoint/Question @key with @ResolveReference
- RouterAuthGuard: validate Router-Authorization header (ADR-036)
- batchFind methods added to 4 repositories
- Domain modules export repositories for GraphqlModule injection
2026-07-15 00:18:57 +08:00
SpecialX
9ff7a61ee2
feat(core-edu): graphql subgraph with dataloader for exam/homework/grade/class
...
- GraphQLModule: Apollo Federation 2 at /graphql
- Exam/Homework/Grade/ClassInfo @key with @ResolveReference using DataLoader
- RouterAuthGuard: validate Router-Authorization header (ADR-036)
- batchFind methods added to exams/homework/grades/classes repositories
- Domain modules export repositories for GraphqlModule injection
2026-07-15 00:18:30 +08:00
SpecialX
6bed673d9f
feat(iam): graphql subgraph with dataloader and router auth guard
...
- GraphQLModule: Apollo Federation 2 subgraph at /graphql
- UserResolver/RoleResolver: @key with @ResolveReference using DataLoader (ADR-035)
- DataScopeResolver: ScopeToken for visible class/student IDs (ADR-041)
- RouterAuthGuard: validate Router-Authorization header (ADR-036)
- DataLoaderService: REQUEST-scoped userLoader + roleLoader
- IamRepository.batchFindRoles: batch query for DataLoader
- IamService.getVisibleClassIds/getVisibleStudentIds: dataScope calculation
- app.module.ts: register PermissionGuard + RouterAuthGuard as APP_GUARD
2026-07-14 23:48:16 +08:00
SpecialX
5fcb831a18
feat(shared-ts): federation shared utilities for apollo subgraphs
...
- RouterAuthGuard: validate Router-Authorization header (ADR-036)
- DataLoader factory: request-scoped batching (ADR-035)
- ScopeTokenService: Redis-backed scope token (ADR-041)
- GraphqlContext: build context from HTTP headers
- FederationExceptionFilter: HTTP-to-GraphQL error mapping
2026-07-14 23:46:51 +08:00
SpecialX
3c2ea50c7f
feat(infra): proto-to-graphql generator + debezium outbox connector
...
- M0: parse proto to generate Federation 2 subgraph SDL
- M0.5: Debezium Connect monitors 4 outbox tables
- docker-compose: extend Debezium profiles to default+p3+p4+p5+p6
- package.json: add proto:gen-graphql script
2026-07-14 23:45:32 +08:00
SpecialX
f212ba0813
docs(docs): known-issues ai 模块经验更新(9 RPC + 6 权限点 + 2 新经验)
...
gRPC server 8→9 RPC(新增 GenerateReport)
PermissionGuard 5→6 权限点(新增 ai:report:generate)
新增经验:Markdown 章节关键词提取 + main.py 模块级变量顺序
2026-07-14 23:02:01 +08:00
SpecialX
765f7da4c0
feat(msg): v2 ARB-013 topic 命名统一 + 考试事件消费
...
ARB-013 P0 修复:PRODUCER_TOPIC_MAP 从 edu.notification.* 改为 edu.notify.notification.*
kafka.consumer 新增 3 考试实时事件消费(exam.extended/force_submitted/question_reordered)
嵌套 payload 解包支持 + topic-map 扩展
新增 6 测试数据文件(docker-notify + 5 kafka 事件 json)
101 单元测试通过 + Docker 真实环境验证
2026-07-14 23:00:33 +08:00
SpecialX
ad39a3bb0f
feat(iam): v2 用户管理 RPC + F12 httpOnly Cookie
...
admin-portal §2.3 P1 阻塞项补齐:CreateUser/UpdateUser/DeleteUser 3 RPC
iam.repository/service/grpc.controller 实现 3 用户管理方法(含 bcrypt + 审计)
iam.controller 新增 POST /v1/iam/users + DELETE /v1/iam/users/:id(@RequirePermission(IAM_USER_MANAGE))
iam.dto 新增 createUserSchema Zod 校验
F12 httpOnly Cookie:refresh_token 改为 httpOnly+Secure+SameSite=Strict Cookie 下发
extractRefreshToken 优先读 cookie 回退 body + buildRefreshTokenCookie/buildClearCookie
2026-07-14 22:59:28 +08:00
SpecialX
d11441c9a8
feat(core-edu): v2 P3.14 考试实时事件 + pino 修复
...
新增 3 RPC:ExtendExam/ForceSubmitExam/ReorderExamQuestions
新增 3 Kafka 事件:exam.extended/exam.force_submitted/exam.question_reordered
exams.service.ts 新增 3 方法 + Outbox 事务内写入 + TOPIC_MAP 映射
grpc.server.ts 注册 3 handler + grpc-smoke 测试
logger.ts pino 导入修复(import pino → import { pino })
27/27 smoke test 通过
2026-07-14 22:58:38 +08:00
SpecialX
aac26c7c6f
feat(ai): v2 新增 GenerateReport RPC + ReportService
...
第 9 个 RPC GenerateReport(学情报告生成):data-ana 学情数据 → LLM 生成 → 结构化提取
新增 ReportService 业务编排层 + GenerateReportRequest/GeneratedReport 模型
gRPC servicer + HTTP POST /v1/ai/generate/report(权限 ai:report:generate)
proto_gen 重新生成 + 测试覆盖(servicer/service/HTTP/模型/权限 共 26 用例)
402 测试通过,覆盖率 88.5%
2026-07-14 22:57:57 +08:00
SpecialX
843b370b3d
feat(shared-proto): ai/core_edu/iam proto v2 扩展
...
ai.proto: 新增 GenerateReport RPC + GenerateReportRequest/GeneratedReport message
core_edu.proto: 新增 ExtendExam/ForceSubmitExam/ReorderExamQuestions 3 RPC + message
iam.proto: 新增 CreateUser/UpdateUser/DeleteUser 3 RPC + 4 message
2026-07-14 22:57:18 +08:00
SpecialX
7545956202
docs(docs): v2.1 架构 spec 8 项调整
...
- Temporal 严格边界引入(AI 工作流 + Saga,CRUD 短事务禁用)
- CDC+Outbox 结合(Debezium Transaction Log Tailing,废弃轮询)
- DataLoader 强制(@key 解析器请求合并,消除 N+1)
- Router-Authorization 信任凭证(拒绝非 Router 的 GraphQL 请求)
- 外部 GraphQL + 内部 gRPC 边界明确
- Eager Invalidation + 乐观锁版本号回传
- Redis Pub/Sub 推送背板(边缘网关不挂 Kafka)
- ScopeToken 优化大规模 ID 列表传递
2026-07-14 22:55:56 +08:00
SpecialX
62682b9d61
docs(docs): 004 arch.db 二次校验 + 新增 v2 架构重设计 spec
...
004 修正 7 处与代码不符描述:
- proto 统计 / 包名 / core-edu gRPC service 数
- msg RPC 数 / data-ana RPC 数
- student-bff 模块数 / parent-bff 模块数
新增 v2 架构重设计 spec(996 行):
- Apollo Federation BFF 联邦
- DataScope @requires 运行时解析
- iam 拆分 config-service
- content CQRS / ai 无状态化
- SSE 优先 / Temporal 不引入
Spec 自审修复 6 处问题:
- apollo-router 端口冲突 4000→4011
- Kafka topic 命名一致性
- CDC/Outbox 投影器职责分工
- 改动点数字 / 服务数 / 容器数计算
2026-07-14 21:25:37 +08:00
SpecialX
594a4e65fe
fix(arch-scan): 修复 ts-scanner 误识别 Python 服务 + 扩展符号提取
...
- 新增 pyproject.toml 检测,跳过纯 Python 服务(ai/data-ana)和包(shared-py)
- 扩展符号提取:新增 TS_CONST_EXPORT_RE 匹配 camelCase/PascalCase 导出常量
- 新增 TS_TYPE_RE 匹配 export type alias
- 修复后 arch:scan 输出 22 模块 / 4715 符号 / 475 契约
2026-07-14 21:24:22 +08:00
SpecialX
0b858d9069
docs(docs): 新增 0020 Portal Shell 架构文档(C4+4+1+ADR) + 设计 spec v2.1 + 更新 0010/004 指向新架构
2026-07-14 18:34:40 +08:00
SpecialX
9db7fd917e
feat(data-ana): v2 P6 硬化完成 + 6 新 RPC + Prometheus 监控
...
P6 硬化(5 项全部完成):
- CDC 多实例水平扩展: _INSTANCE_ID + get_lag() 真实 lag 计算
- ExamCache Redis 化: key data_ana:exam:{exam_id}, TTL 30 天 + 内存 LRU fallback
- ClickHouse TTL 归档: 5 表均加 TTL(1-3 年),分区级删除
- Prometheus 监控: 18 个指标(CDC/CH/ExamCache/DataScope/gRPC/业务)
- readyz 深度硬化: 4 依赖超时检查(CH 1s/Redis 200ms/iam 2s/CDC lag<1000)
v2 新增 6 个 RPC(analytics.proto 扩展为 18 RPC):
- GetStudentGrowth / GetAssignmentAnalysis / GetMasterySummary
- ListDiagnosticReports(占位,待 ai 服务)/ ListErrorBookItems / GetErrorBookStats
监控与可观测性: lifespan 预热 + gRPC ServerInterceptor + CDC 消费者指标
Docker 本地测试 19 项全部通过(healthz/readyz/metrics + 11 HTTP + 10 gRPC + ruff)
nextstep-v2.md: 上游需求对齐 + 下游要求(iam/core-edu/content/ai/SRE)
2026-07-14 18:07:17 +08:00
SpecialX
78e406b317
feat(content): v2 扩展 Elective/LessonPlan/CoursePlan 三业务域
...
新增 3 个业务域(10 RPC):
- ElectiveService: 选修课列表/学生选课记录/选课/退课(含容量与重复校验)
- LessonPlanService: 教师备课列表/学生备课列表(仅 published)/详情
- CoursePlanService: 学生课程计划列表/详情
- KnowledgeGraphService.GetKnowledgePath: 与 GetLearningPath 同实现
新增 4 张 MySQL 表(elective_courses/selections/lesson_plans/course_plans),含完整索引。
新增 11 个权限点,覆盖 admin/teacher/student/parent 四角色。
proto 由 4 Service/22 RPC 扩展至 7 Service/32 RPC,v1 全部 RPC 保持向后兼容。
修复 logger.ts pino 导入: default import 在 NodeNext ESM 下不可调用,
改用 named import(与 iam/msg/core-edu 对齐)。
Docker 本地测试全部通过(HTTP + gRPC 双协议),健康检查、
Elective/LessonPlan/CoursePlan CRUD、4 个新 gRPC Service 全部验证通过。
nextstep-v2.md 已创建,记录上下游依赖与 6 项联调待办。
2026-07-14 17:54:37 +08:00
SpecialX
abde336876
chore(deps): 更新根 package.json 依赖 + pnpm-lock.yaml 同步
CI / quality-ts (push) Failing after 6s
CI / quality-go (push) Failing after 26s
CI / quality-proto (push) Failing after 6s
CI / deploy (push) Has been skipped
2026-07-14 16:04:48 +08:00
SpecialX
2796d7c88f
feat(infra): api-gateway 环境变量补全 + build context 修复 + docker-compose.test 新增
2026-07-14 16:04:20 +08:00
SpecialX
a70977ad4b
feat(api-gateway): admin 路由组 + BFF 路径重写 + announcements 路由 + Dockerfile 修复 + nextstep v2 文档
2026-07-14 16:03:38 +08:00
SpecialX
9fd7c018c2
feat(push-gateway): config 扩展 + kafka consumer + ws handler + nextstep 文档
2026-07-14 16:03:17 +08:00
SpecialX
5a88c8b45d
feat(parent-bff): graphql schema 扩展 + extended-resolvers + grpc factory + nextstep 文档
2026-07-14 16:02:49 +08:00
SpecialX
422b55f901
feat(student-bff): extended queries/mutations resolvers + Dockerfile + nextstep 文档
2026-07-14 16:01:20 +08:00
SpecialX
895a060491
feat(teacher-bff): admin 命名空间 + 5 个 gRPC client + health probes + merge-resolvers + nextstep 文档
2026-07-14 16:00:46 +08:00
SpecialX
7b790f1276
feat(ai): gRPC clients 扩展 + server interceptors + proto_gen + 测试 + nextstep 文档
2026-07-14 15:59:41 +08:00
SpecialX
fb23c5234e
feat(msg): announcements 公告模块 + sendBatch 批量优化 + 权限扩展 + nextstep 文档
2026-07-14 15:57:41 +08:00
SpecialX
7dd5c44406
feat(core-edu): admin/dashboard/leave-requests 模块 + gRPC + 状态机测试 + nextstep 文档
2026-07-14 15:56:10 +08:00
SpecialX
d260df864c
feat(iam): 角色权限管理 + 权限缓存 + 指标 + 鉴权中间件增强 + nextstep 文档
2026-07-14 15:55:39 +08:00
SpecialX
e9d3030f2f
feat(shared-ts): 同步 3 个 BFF GraphQL schema + downstream-client/logger/outbox 增强
2026-07-14 15:51:36 +08:00
SpecialX
774af93d76
feat(shared-proto): core_edu proto 扩展 admin/dashboard/leave-requests/grpc 定义
2026-07-14 15:48:20 +08:00
SpecialX
81a539b9ab
chore(deps): 统一依赖管理 - pnpm 11 + node:22 + golang:1.25 + python:3.12 + shared-* 集中化
...
CI / quality-ts (push) Failing after 6s
CI / quality-go (push) Failing after 25s
CI / quality-proto (push) Failing after 6s
CI / deploy (push) Has been skipped
- Node.js 统一到 node:22-alpine,Go 统一到 golang:1.25-alpine,Python 统一到 python:3.12-slim
- pnpm 升级到 11.13.0(corepack),新增 allowBuilds 白名单解决 ERR_PNPM_IGNORED_BUILDS
- 新增 packages/shared-py 集中 Python 共享依赖,shared-ts 补充 graphql-yoga/prom-client
- api-gateway 修复 go.mod 的 shared-go 依赖 + Dockerfile 改用 repo 根作 context
- Python 服务(data-ana/ai)Dockerfile 改用 repo 根作 context + 声明 uv workspace sources
- 16 个服务的 Dockerfile + CI + docker-compose.tools.yml 全部对齐版本矩阵
- known-issues.md 沉淀 9 条 pnpm 11 / uv workspace / Go shared-go 迁移经验
- 验证:4 服务完全成功(api-gateway /healthz 200),其余 install 成功(build 失败为预存 TS 错误)
2026-07-14 12:04:49 +08:00
SpecialX
74077c7083
docs(parent-portal): 恢复 nextstep.md v1 原貌 + 新增 nextstep-v2.md 核查报告
...
v1 保持原样(2026-07-13 初版下游待办)
v2 新增(2026-07-14 核查结果):1 项已完成(pnpm-lock),4 项仍未完成(端点路径/Docker/schema/api-gateway 镜像)
v2 新发现:extended-resolvers.ts 存在但未集成且引用不存在的类型;parent-bff Dockerfile pnpm 版本未固定
2026-07-14 10:14:43 +08:00
SpecialX
0066afc55e
feat(teacher-portal): v2 下游核查 + push-gateway 接入 + 测试扩展至 87 + ui-components 12/12
...
v2 核查结论:
- iam/push-gateway/api-gateway 已就绪
- teacher-bff teacher 域仍是 P2 占位(56/61 operations 不可用)
- 5 个 gRPC target 留空走降级模式 B
- 保留 MSW mock,记录 12 项 teacher-bff 待补工作到 nextstep-v2.md
v2 完成工作:
- push-gateway WebSocket 接入(环境变量 + URL query token + Reconnect 协议)
- 单元测试扩展(usePermission 15 + useAuth 9,总计 87/87 passed)
- ui-components 剩余 3 组件(Chart/Calendar/RichTextEditor,12/12)
- 设计令牌完整迁移(无 hsl/hex 字面量)
- i18n 5/55 页面 + 26 模块 key
- 性能优化(size-limit 9 项 + 5 页面懒加载)
- useAuth 迁移阻塞核查(iam 未实现 Set-Cookie,修正 v1 假设)
文档:新增 nextstep-v2.md;workline.md §5.7 添加 v2 工作记录。
验证:typecheck + lint + 87/87 tests + arch:scan 全部通过。
2026-07-14 08:47:18 +08:00
SpecialX
ae6fe23be6
docs(student-portal): nextstep-v2 二次核查下游服务实现状态
2026-07-14 08:43:45 +08:00
SpecialX
21f2485749
docs(student-portal): nextstep-v2 核查下游服务实现状态+记录42个resolver未装配问题
2026-07-14 08:36:02 +08:00
SpecialX
41179ff0a9
docs(parent-portal): nextstep.md v2 核查下游服务完成情况
...
v2 核查结果:parent-bff pnpm-lock 已添加,但端点路径/schema/Docker 构建/extended-resolvers 集成仍未完成
api-gateway Docker 构建仍失败(golang:1.22-alpine 无法拉取)
parent-portal 自身 Docker 镜像构建成功,容器 healthy,typecheck + lint 零错误
2026-07-14 08:29:25 +08:00
SpecialX
0b42302a64
docs(admin-portal): 新增 nextstep-v2.md 记录下游核查结果
...
v1 声称完成的下游工作经核查实际未完成:
- api-gateway: /api/admin/graphql 路由未注册,go vet 编译失败
- teacher-bff: resolver 已完成但 schema 未同步(命名空间 vs 扁平)
- iam: proto 缺 BatchGetUsers rpc 声明
v2 记录详细核查证据和修复要求
2026-07-14 08:26:27 +08:00
SpecialX
99580fa13a
feat(content): docker 本地测试通过 + P5 ES 集成 + P6+ 审核工作流/可视化/可观测性
...
P5 ES 集成:
- config/elasticsearch.ts: 惰性初始化 + ik_max_word→standard 回退
- shared/sync/es-sync.worker.ts: Kafka 消费 question 事件并索引 ES
- questions search API: ES 优先, MySQL LIKE 降级
- ensureQuestionIndex() 幂等创建, IK 不可用回退 standard
- main.ts: 启动 ensureQuestionIndex + esSyncWorker 生命周期管理
P6+ 审核工作流/可视化/可观测性:
- Question 状态机: draft→pending_review→published→archived
- 非法转换拦截
- 知识图谱可视化 API: Neo4j 优先 + MySQL 降级
- Cypher 返回标量避免 Node 包装对象问题
- 教材版本管理: GET /textbooks/versions + archive
- 5 个 Prometheus 指标 + /readyz Outbox 积压检查
Docker 本地测试 (8 类全通过):
- healthz/readyz (5 依赖 ok)
- REST CRUD (textbook/chapter/kp/question)
- ES 全文检索命中
- 审核工作流状态机 (合法/非法转换)
- Outbox 事件驱动 (8 事件全 published)
- Neo4j 同步 (KnowledgePoint 节点创建)
- 可视化 (nodes/edges 正确)
- Prometheus 指标
docs/nextstep.md: 上游 (MySQL/Neo4j/Kafka/Redis/ES/ai)
+ 下游 (teacher-bff/student-bff/parent-bff/data-ana/api-gateway/ai)
2026-07-14 00:58:50 +08:00
SpecialX
5b06bdbc52
feat(data-ana): docker 本地测试通过 + gRPC 修复 + nextstep 上下游依赖文档
2026-07-13 23:57:48 +08:00