SpecialX
9cedf0c437
feat(portal-shell): v2.0 P0 shadcn standardization + security + streaming + error handling
...
- shadcn/ui 标准化:废弃纸感令牌,统一 bg-background/text-foreground 等
- Tailwind v4 + @theme inline,移除 tailwind.config.js
- React 19 use() + Suspense 流式渲染,首屏骨架秒出
- 三级错误边界:Route → Section → Widget 层层兜底
- 错误上报:useErrorReport → sendBeacon → /api/log mock 端点
- 三层安全边界:L1 角色门禁 / L2 权限点门禁 / L3 数据范围
- 权限位图 base36 压缩:67 权限点 → ~14 字符,JWT 体积减少 ≥ 99%
- notify 统一 Toast 封装,禁止业务直接 import sonner
- PluginBoundary 替代 PluginLoader(错误边界 + Suspense + Skeleton 三件套)
验证:typecheck 0 错误 / lint 0 错误 / build 6 路由生成成功
2026-07-17 16:10:05 +08:00
SpecialX
1b5781bf42
fix: add missing @RequirePermission decorators
...
Adds @RequirePermission to 19 TS GraphQL resolvers across 5
subgraphs (iam, config-service, core-edu, content, msg) per
audit report §6.1. Maps: iam user/role -> IAM_USER_READ;
config-service 5 queries -> CONFIG_USER; core-edu classInfo ->
CLASS_READ, exam -> EXAM_READ, grade -> GRADE_READ, homework
-> HOMEWORK_READ, datascope visibleGrades/visibleExams ->
GRADE_READ/EXAM_READ; content chapter/knowledgePoint/question/
textbook -> CONTENT_*_READ; msg notifications ->
MSG_NOTIFICATION_READ, template -> MSG_NOTIFICATION_MANAGE.
Federation resolveReference left unguarded. Python subgraphs
(data-ana, ai) deferred to follow-up infrastructure work.
2026-07-17 13:26:58 +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
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
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
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
7dd5c44406
feat(core-edu): admin/dashboard/leave-requests 模块 + gRPC + 状态机测试 + nextstep 文档
2026-07-14 15:56:10 +08:00
SpecialX
61d824924a
fix: 修复集成测试中发现的全部 bug — 15 服务端到端验证通过
...
修复涵盖 6 大类问题:
1. api-gateway
- 路径前缀剥离 /api 而非 /api/v1,保留下游 /v1/ controller 前缀
- JWKS URL 默认值修复
- publicPaths 白名单对齐 /v1/iam/*
2. iam
- iam.module.ts exports 补充 PermissionCacheService 和 IamRepository
- main.ts resolveProtoPath() 多路径探测 proto 文件
3. core-edu
- app.module.ts AuthMiddleware 全局注册
4. BFF 层 GraphQL 端点(teacher-bff / parent-bff / student-bff)
- teacher-bff: mock dataScope OWN→SELF 对齐 GraphQL enum;WHATWG Request header .get() 提取
- parent-bff: handleNodeRequestAndResponse 不存在 → 直接 yoga(req,res);WHATWG Request header .get() 提取
- student-bff: auth.resolver 移除 ActionState 信封返回扁平对象;WHATWG Request header .get() 提取
5. ai
- Kafka 事务降级 + 10s 超时
- gRPC 拦截器降级
- dev mode 禁用事务模式
6. 前端 + 共享包
- teacher-portal: MF 插件条件实例化 + transpilePackages + extensionAlias
- ui-components: error-boundary.tsx 添加 use client
- ui-tokens: tailwind-theme.css 移除 @layer base
- shared-ts: 导出从源码改为 dist 编译产物;OutboxModule global:true
7. infra
- .gitignore 补充 keys/ *.pem *.key secrets/ 排除规则
- infra/init-sql/02-all-services-schema.sql 36 张表 DDL
验证结果:
- TS typecheck: 19 个 workspace 项目全部通过
- Go vet + Ruff: 通过
- 15 服务全部启动成功
- 3 个 BFF GraphQL 端点 + 4 个前端页面全部 200
- Gateway → iam → core-edu 端到端链路验证通过
AI identity: trae-main(集成测试修复会话)
2026-07-11 01:41:46 +08:00
SpecialX
58c0ba1bd9
feat(core-edu): 完整实现 core-edu 教学核心服务
...
包含 classes/exams/homework/grades/attendance/scheduling 域、outbox、iam-consumer、redis 配置等完整实现
2026-07-10 19:08:56 +08:00
SpecialX
0a71b02e04
fix: code compliance audit and fix across all services
...
CI / quality-ts (push) Failing after 48s
CI / quality-go (push) Failing after 4s
CI / quality-proto (push) Failing after 2s
CI / deploy (push) Has been skipped
NestJS (6 services): implement @RequirePermission decorator with
SetMetadata+Reflector, register APP_GUARD globally, fix as assertions
to type guards, add explicit return types, fix import type for express,
fix /metrics implicit any, replace native Error with ApplicationError,
remove typeorm remnants, register LifecycleService.
teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward
real userId to downstream, log downstream failures, migrate health
controller to shared/health.
Go (2 services): interface to any, doc comments, CORS dev whitelist,
JWT secret fail-fast, push-gateway internal API auth, metrics and
readyz endpoints, remove dead code.
Python (2 services): lifespan return type, dev_mode to bool, data-ana
APIRouter, ai POST body model, ClickHouse async wrapping.
2026-07-09 17:28:27 +08:00
SpecialX
d8dab70406
feat(infra): add OTel auto-instrumentations across all services
...
CI / quality-proto (push) Failing after 2s
CI / deploy (push) Has been skipped
CI / quality-ts (push) Failing after 1m11s
CI / quality-go (push) Failing after 5s
NestJS 6 services use getNodeAutoInstrumentations().
Python 2 services use FastAPIInstrumentor. Go 2 services use otelgin.
2026-07-09 13:25:46 +08:00
SpecialX
566060fade
feat(infra): p6 hardening - observability and deploy compose
...
- 5 NestJS services add /metrics endpoint via app.getHttpAdapter()
- prometheus.yml scales to 8 services with rule_files and alertmanager
- monitoring compose replaces blackbox with Loki+Promtail
- Grafana datasource adds Loki
- docker-compose.deploy.yml scales to 11 services
- deploy.env.example completes Neo4j/ES/ClickHouse/LLM vars
- teacher-bff adds health.controller
- CI removes continue-on-error on lint step
- teacher-portal lint script changed to eslint src
2026-07-09 10:21:06 +08:00
SpecialX
4533da6484
feat(core-edu): 修复服务启动并打通考试作业成绩端到端链路
...
database.ts 导出 db 常量替代 getDb()
env.ts JWT_SECRET 改 optional 并新增 DEV_MODE
kafka.ts connectKafka 加 try/catch 不阻塞启动
main.ts 去全局前缀 connectKafka 改非阻塞
app.module 移除未用模块加 HealthModule
controller 路由去前缀去 UseGuards 从 x-user-id 读身份
service datetime ISO 字符串转 Date 修复 drizzle 错误
修正相对 import 路径
health/lifecycle 改用 Drizzle 原生查询
新增 core-edu-init.sql 初始化 4 张表
端到端验证: exams/homework/grades 全部 201/200
Outbox 事件正确写入 core_edu_outbox 表
2026-07-09 08:02:22 +08:00
SpecialX
e9ea34fe53
feat(p6): production hardening with circuit breaker, backup, monitoring and chaos engineering
...
CI Go / test (push) Has been cancelled
CI Python / test (push) Has been cancelled
CI TypeScript / test (push) Has been cancelled
CI Proto / lint (push) Failing after 8m7s
P6 生产硬化阶段交付物(46 文件):
## 1. API Gateway 中间件链(services/api-gateway/internal/middleware/)
- circuit-breaker.go: gobreaker v2 熔断器(5s 窗口/50% 错误率/30s OPEN→HALF_OPEN)
- ratelimit.go: 令牌桶限流(sync.Map + cleanup goroutine,默认 100rps/20 burst)
- cors.go: CORS 中间件(CORS_ORIGINS 环境变量)
- recovery.go: panic 恢复 + uuid request_id
- security.go: 安全头 + 请求体 10MB 限制
- requestid.go: 请求 ID 注入
- health/health.go: /healthz + /readyz 健康检查
- main.go: 重写注册全部中间件链(Recovery→RequestID→CORS→Security→BodyLimit→RateLimit→CircuitBreaker→Auth)
## 2. 基础设施硬化(infra/)
- backup/backup-mysql.sh: MySQL 全量备份(mysqldump+gzip,按服务独立)
- backup/restore-mysql.sh: 恢复脚本
- backup/backup-cron.sh: cron 调度入口(5 服务批量备份)
- alertmanager/alertmanager.yml: 告警路由(webhook + 邮件示例)
- prometheus/rules.yml: 8 条告警规则(服务可用性/性能/资源 3 组)
- grafana/dashboards/microservices-overview.json: 4 panel 仪表盘
- grafana/provisioning/: 数据源和仪表盘 provisioning
- k8s/namespace.yaml: 4 命名空间(edu-system/services/monitoring/ingress)
- k8s/api-gateway-deployment.yaml: Deployment + Service 骨架
- chaos/experiments.yaml: 3 个 Litmus 混沌实验(pod-kill/network-latency/disk-fill)
- docker-compose.monitoring.yml: 监控栈 profile
- security/secrets.example.env: 8 项密钥占位符
- security/waf-rules.conf: ModSecurity WAF 规则骨架
## 3. 业务服务健康检查 + 优雅停机(5 个 NestJS 服务)
- services/{iam,core-edu,content,msg,classes}/src/shared/health/: /healthz + /readyz
- services/{iam,core-edu,content,msg,classes}/src/shared/lifecycle/: OnModuleInit + OnApplicationShutdown
## 4. Python 服务健康检查
- services/{ai,data-ana}/src/health/health.py: FastAPI APIRouter
## 5. 运维文档
- docs/architecture/runbooks/p6-hardening.md: P6 总览 Runbook(9 章节)
- docs/architecture/runbooks/incident-response.md: 事件响应手册(5 章节)
- docs/architecture/004-p6-addendum.md: 004 架构补记 P6 章节
- docs/troubleshooting/known-issues-p6-addendum.md: 15 条 P6 场景→技术映射
## 验收信号
- RPO ≤ 15min(MySQL 备份 + binlog PITR)
- RTO ≤ 30min(K8s 滚动更新 + DNS 切换)
- P99 ≤ 500ms(熔断 + 限流 + 缓存)
- 熔断器错误率 > 50% 触发 OPEN
- 限流 100rps/20 burst
- 备份保留 7 天
- 混沌实验每月 1 次
2026-07-08 02:16:58 +08:00
SpecialX
23246ade6d
feat(p3): core teaching service with Outbox + Kafka event bus
...
P3 阶段交付物:
- services/core-edu: 教学核心服务(DDD 限界上下文:exams/grades/homework/classes)
- exams: 考试 CRUD + 事务内写 exam + outbox
- grades: 成绩 CRUD
- homework: 作业 CRUD
- classes.module: 复用 P1 classes 模块(聚合到 core-edu 服务)
- Outbox 模式实现:
- outbox.schema.ts: core_edu_outbox 表(id/aggregate_id/event_type/payload/status/retry_count)
- outbox.repository.ts: 支持事务参数 tx,确保业务+事件原子性
- outbox.publisher.ts: Kafka idempotent producer + transactionalId,TOPIC_MAP 路由 9 种事件,MAX_RETRY=5
- config/kafka.ts: idempotent producer + transactionalId 配置
- main.ts: 启动顺序 initTracer → connectKafka → outboxPublisher.start → app.listen
- packages/shared-proto/proto/core_edu.proto: ExamService/HomeworkService/GradeService 契约
- packages/shared-proto/proto/events.proto: ClassEvent/ExamEvent/HomeworkEvent/GradeEvent 领域事件契约
2026-07-08 01:38:07 +08:00