diff --git a/.devcontainer/external/.env.example b/.devcontainer/external/.env.example index aad0550..45e322d 100644 --- a/.devcontainer/external/.env.example +++ b/.devcontainer/external/.env.example @@ -11,3 +11,12 @@ K12STUDY_REGISTRY_HOST=192.168.0.23 K12STUDY_REGISTRY_PORT=8848 K12STUDY_REGISTRY_GRPC_PORT=9848 K12STUDY_REGISTRY_RAFT_PORT=9849 +K12STUDY_GRAPH_HOST=192.168.0.23 +K12STUDY_GRAPH_PORT=9669 +K12STUDY_GRAPH_USER=root +K12STUDY_GRAPH_PASSWORD=nebula +K12STUDY_VECTOR_HOST=192.168.0.23 +K12STUDY_VECTOR_PORT=19530 +K12STUDY_VECTOR_HTTP_PORT=9091 +K12STUDY_ATTU_HOST=192.168.0.23 +K12STUDY_ATTU_PORT=3000 diff --git a/.devcontainer/external/devcontainer.json b/.devcontainer/external/devcontainer.json index b57984e..4a0dd3c 100644 --- a/.devcontainer/external/devcontainer.json +++ b/.devcontainer/external/devcontainer.json @@ -27,5 +27,9 @@ "SPRING_PROFILES_ACTIVE": "dev", "K12STUDY_DEV_MODE": "external" }, - "postCreateCommand": "cd /workspaces/K12study/frontend && pnpm install" + + "remoteUser": "codespace", + "updateRemoteUserUID": true, + + "postCreateCommand": "sudo chown -R codespace:codespace /pnpm-store /workspaces/K12study/frontend/node_modules" } diff --git a/.devcontainer/external/docker-compose.yml b/.devcontainer/external/docker-compose.yml index 305bba1..bc9e068 100644 --- a/.devcontainer/external/docker-compose.yml +++ b/.devcontainer/external/docker-compose.yml @@ -3,9 +3,17 @@ services: image: mcr.microsoft.com/devcontainers/universal:2 volumes: - ../../:/workspaces/K12study:cached + - frontend-node-modules:/workspaces/K12study/frontend/node_modules + - pnpm-store:/pnpm-store working_dir: /workspaces/K12study command: sleep infinity + user: 1000:1000 # 👈 强制权限,最关键 environment: + NPM_CONFIG_USER: 1000 + PNPM_HOME: /pnpm-store + PNPM_STORE_DIR: /pnpm-store + + # 你原来的所有环境变量... K12STUDY_DB_HOST: ${K12STUDY_DB_HOST:-host.docker.internal} K12STUDY_DB_PORT: ${K12STUDY_DB_PORT:-5432} K12STUDY_DB_NAME: ${K12STUDY_DB_NAME:-k12study} @@ -25,6 +33,12 @@ services: K12STUDY_VECTOR_HOST: ${K12STUDY_VECTOR_HOST:-host.docker.internal} K12STUDY_VECTOR_PORT: ${K12STUDY_VECTOR_PORT:-19530} K12STUDY_VECTOR_HTTP_PORT: ${K12STUDY_VECTOR_HTTP_PORT:-9091} + K12STUDY_ATTU_HOST: ${K12STUDY_ATTU_HOST:-host.docker.internal} + K12STUDY_ATTU_PORT: ${K12STUDY_ATTU_PORT:-3000} PYTHONUNBUFFERED: "1" extra_hosts: - "host.docker.internal:host-gateway" + +volumes: + frontend-node-modules: + pnpm-store: \ No newline at end of file diff --git a/.devcontainer/internal/devcontainer.json b/.devcontainer/internal/devcontainer.json index 61dad36..c8202ee 100644 --- a/.devcontainer/internal/devcontainer.json +++ b/.devcontainer/internal/devcontainer.json @@ -39,5 +39,5 @@ "SPRING_PROFILES_ACTIVE": "dev", "K12STUDY_DEV_MODE": "internal" }, - "postCreateCommand": "cd /workspaces/K12study/frontend && pnpm install" + "postCreateCommand": "sudo chown -R codespace:codespace /pnpm-store /workspaces/K12study/frontend/node_modules && cd /workspaces/K12study/frontend && pnpm install" } diff --git a/.devcontainer/internal/docker-compose.yml b/.devcontainer/internal/docker-compose.yml index 8de14a7..e0574f6 100644 --- a/.devcontainer/internal/docker-compose.yml +++ b/.devcontainer/internal/docker-compose.yml @@ -3,6 +3,8 @@ services: image: mcr.microsoft.com/devcontainers/universal:2 volumes: - ../../:/workspaces/K12study:cached + - frontend-node-modules:/workspaces/K12study/frontend/node_modules + - pnpm-store:/pnpm-store working_dir: /workspaces/K12study command: sleep infinity environment: @@ -26,6 +28,7 @@ services: K12STUDY_VECTOR_PORT: 19530 K12STUDY_VECTOR_HTTP_PORT: 9091 PYTHONUNBUFFERED: "1" + PNPM_STORE_DIR: /pnpm-store depends_on: - postgres - redis @@ -151,6 +154,8 @@ services: - milvus-dev-data:/var/lib/milvus volumes: + frontend-node-modules: + pnpm-store: postgres-dev-data: redis-dev-data: nacos-dev-logs: diff --git a/.gitignore b/.gitignore index 8bf09b0..35813cd 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,8 @@ referenceCode .DS_Store .tmp-run/ .gitnexus - +.pnpm-store +**/runtime **/target/ **/node_modules/ diff --git a/docker/dev-common/docker-compose.public-services.yml b/docker/dev-common/docker-compose.public-services.yml index d6890cb..7c30888 100644 --- a/docker/dev-common/docker-compose.public-services.yml +++ b/docker/dev-common/docker-compose.public-services.yml @@ -44,15 +44,24 @@ services: restart: unless-stopped environment: MODE: standalone - NACOS_AUTH_ENABLE: "false" - NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN:-azEyc3R1ZHktbmFjb3MtZGV2LXRva2VuLTIwMjY=} + # --- 鉴权配置 --- + NACOS_AUTH_ENABLE: "true" + NACOS_AUTH_SYSTEM_TYPE: nacos + NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=} NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY:-serverIdentity} NACOS_AUTH_IDENTITY_VALUE: ${NACOS_AUTH_IDENTITY_VALUE:-security} + NACOS_AUTH_CACHE_ENABLE: "true" + NACOS_AUTH_ADMIN_ENABLE: "true" + NACOS_AUTH_CONSOLE_ENABLE: "true" + # Nacos 2.4+ / 3.x 不再提供默认管理员密码(不再是 nacos)。 + # 首次开启鉴权后需初始化管理员密码,例如调用: + # POST /nacos/v1/auth/users/admin with form-data: password=nacos TZ: ${TZ:-Asia/Shanghai} JVM_XMS: 256m JVM_XMX: 512m JVM_XMN: 128m ports: + - "${K12STUDY_REGISTRY_CONSOLE_PORT:-9080}:8080" - "${K12STUDY_REGISTRY_PORT:-8848}:8848" - "${K12STUDY_REGISTRY_GRPC_PORT:-9848}:9848" - "${K12STUDY_REGISTRY_RAFT_PORT:-9849}:9849" @@ -111,52 +120,15 @@ services: - "${K12STUDY_GRAPH_PORT:-9669}:9669" networks: - k12study-dev-net - milvus-etcd: - image: quay.io/coreos/etcd:v3.5.5 - container_name: k12study-dev-milvus-etcd - restart: unless-stopped - environment: - ETCD_AUTO_COMPACTION_MODE: revision - ETCD_AUTO_COMPACTION_RETENTION: "1000" - ETCD_QUOTA_BACKEND_BYTES: "4294967296" - ETCD_SNAPSHOT_COUNT: "50000" - command: etcd -advertise-client-urls=http://milvus-etcd:2379 -listen-client-urls=http://0.0.0.0:2379 --data-dir=/etcd - volumes: - - ${K12STUDY_RUN_DIR:-./runtime}/milvus/etcd:/etcd - networks: - - k12study-dev-net - milvus-minio: - image: minio/minio:RELEASE.2024-11-07T00-52-20Z - container_name: k12study-dev-milvus-minio - restart: unless-stopped - environment: - MINIO_ACCESS_KEY: ${K12STUDY_MINIO_ACCESS_KEY:-minioadmin} - MINIO_SECRET_KEY: ${K12STUDY_MINIO_SECRET_KEY:-minioadmin} - command: minio server /data + nebula-studio: + image: vesoft/nebula-graph-studio:latest ports: - - "${K12STUDY_MINIO_PORT:-9000}:9000" - volumes: - - ${K12STUDY_RUN_DIR:-./runtime}/milvus/minio:/data - networks: - - k12study-dev-net - milvus: - image: milvusdb/milvus:v2.4.8 - container_name: k12study-dev-milvus - restart: unless-stopped - command: ["milvus", "run", "standalone"] + - "7001:7001" + environment: + - NGINX_PORT=7001 + - LANG=en-US depends_on: - - milvus-etcd - - milvus-minio - environment: - ETCD_ENDPOINTS: milvus-etcd:2379 - MINIO_ADDRESS: milvus-minio:9000 - ports: - - "${K12STUDY_VECTOR_PORT:-19530}:19530" - - "${K12STUDY_VECTOR_HTTP_PORT:-9091}:9091" - volumes: - - ${K12STUDY_RUN_DIR:-./runtime}/milvus/data:/var/lib/milvus - networks: - - k12study-dev-net + - nebula-graphd networks: k12study-dev-net: diff --git a/docs/architecture.md b/docs/architecture.md index 2808dbc..279198d 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -25,7 +25,7 @@ - 完成核心业务域数据模型定版,确保接口与代码开发有稳定数据契约。 - 关键任务 - 梳理多租户基础域(tenant/dept/user/role/menu)。 - - 梳理课程域、题目与批改域、成就与推荐域、AI 知识域的数据关系。 + - 梳理课程域、题目与批改域、成就域、AI 知识域的数据关系。 - 定义 SQL 执行顺序、索引策略、跨 schema 依赖约束。 - 验收产物 - `docs/architecture/er-diagram.md` diff --git a/docs/architecture/api-design.md b/docs/architecture/api-design.md index d2c7eb9..2158573 100644 --- a/docs/architecture/api-design.md +++ b/docs/architecture/api-design.md @@ -62,14 +62,7 @@ - `GET /api/achievement/users/{userId}/records` - `GET /api/achievement/users/{userId}/progress` - `POST /api/achievement/events/trigger` - -### 3.4 推荐域(recommendation) -- `POST /api/recommendation/tasks` -- `GET /api/recommendation/tasks/{taskId}/items` -- `POST /api/recommendation/items/{itemId}/feedback` -- `GET /api/recommendation/effects/daily` - -### 3.5 AI 知识域(ai) +### 3.4 AI 知识域(ai) - `POST /api/ai/knowledge/files` - `POST /api/ai/knowledge/files/{fileId}/sync` - `GET /api/ai/knowledge/sync-tasks/{taskId}` @@ -78,5 +71,5 @@ ## 4. API 阶段交付映射 - M3:`auth + upms + file/message 基础扩展` -- M5:`course + question + achievement + recommendation + ai` +- M5:`course + question + achievement + ai` - M6:前后端按冻结 API 完成联调,不新增破坏性变更。 diff --git a/docs/architecture/er-diagram.md b/docs/architecture/er-diagram.md index 2e774bc..5f67406 100644 --- a/docs/architecture/er-diagram.md +++ b/docs/architecture/er-diagram.md @@ -3,7 +3,7 @@ - 基础域:租户、组织、用户、角色、菜单、文件。 - 课程域:课程、章节、学习节点、知识点、学习进度。 - 习题与批改域:题库、试卷、作业、提交、批改、错题与复习。 -- 成就与推荐域:成就定义、用户成就、推荐任务、反馈、学习闭环。 +- 成就域:成就定义、用户成就与学习激励闭环。 - AI 知识域:知识文件、同步任务、图谱实体/关系。 ## 2. 核心关系图(基础域 + 教学主链路) @@ -34,8 +34,6 @@ erDiagram USER_ACHIEVEMENT }o--|| ACHIEVEMENT : awarded USER_ACHIEVEMENT }o--|| SYS_USER : owner - RECOMMENDATION_TASK ||--o{ RECOMMENDATION_ITEM : produces - RECOMMENDATION_ITEM ||--o{ RECOMMENDATION_FEEDBACK : receives ``` ## 3. AI 知识域关系图 @@ -72,6 +70,6 @@ erDiagram - `init/pg/ai/10_create_ai_tables.sql` ## 6. 设计建议 -- 保持跨域依赖单向:`course/question/achievement/recommendation` 通过 `upms` 提供的主体信息关联。 +- 保持跨域依赖单向:`course/question/achievement` 通过 `upms` 提供的主体信息关联。 - 涉及 AI 知识检索的数据优先走异步同步表,避免在线写链路阻塞。 - 复杂业务报表优先通过事实表/汇总表落地,避免线上实时多表大 join。 diff --git a/docs/architecture/logical-view.md b/docs/architecture/logical-view.md index 63fd51d..774f95d 100644 --- a/docs/architecture/logical-view.md +++ b/docs/architecture/logical-view.md @@ -11,7 +11,7 @@ - `ai-client`(Java 侧 AI 适配) - `python-ai`(AI 处理服务) - 业务域层(规划中) - - `course`、`question`、`achievement`、`recommendation` + - `course`、`question`、`achievement` - 数据与基础设施层 - PostgreSQL(多 schema) - Redis(缓存、会话、热点) @@ -30,21 +30,18 @@ graph TD GW --> COURSE[Course Service] GW --> QUESTION[Question Service] GW --> ACHIEVE[Achievement Service] - GW --> REC[Recommendation Service] AUTH --> PG[(PostgreSQL)] UPMS --> PG COURSE --> PG QUESTION --> PG ACHIEVE --> PG - REC --> PG AUTH --> REDIS[(Redis)] UPMS --> REDIS COURSE --> REDIS QUESTION --> REDIS ACHIEVE --> REDIS - REC --> REDIS QUESTION --> AICLIENT[AI Client] AICLIENT --> PYAI[Python AI] @@ -63,7 +60,7 @@ graph TD - 教师发作业:题库/试卷/作业配置 -> 投放班级。 - 学生提交:答题内容 + 文件(可选)。 - 批改流程:自动批改 + 人工复核 -> 成绩汇总 -> 错题沉淀。 -- 复习与推荐:复习计划 -> 推荐内容 -> 用户反馈 -> 闭环效果。 +- 复习闭环:复习计划 -> 复习执行 -> 效果回写。 - 成就激励:事件触发 -> 规则命中 -> 成就发放/进度更新。 ### 3.3 AI 知识链路 diff --git a/docs/plan/modules/gateway.md b/docs/plan/modules/gateway.md index af5c092..d9465c0 100644 --- a/docs/plan/modules/gateway.md +++ b/docs/plan/modules/gateway.md @@ -1,7 +1,7 @@ # 问题陈述 将 `gateway` 从“仅转发 auth/upms 的静态网关”升级为全域统一接入层,负责鉴权透传、租户隔离防线、端侧能力边界控制(尤其小程序学生端)。 ## 当前状态(已确认) -* 架构定义中网关应承接 auth/upms/course/question/achievement/recommendation 多域入口。参考 `docs/architecture/logical-view.md (24-41)`。 +* 架构定义中网关应承接 auth/upms/course/question/achievement/ai 多域入口。参考 `docs/architecture/logical-view.md (24-41)`。 * 现有网关路由仅配置 `auth` 与 `upms` 两条,且目标地址硬编码 localhost。参考 `backend/gateway/src/main/resources/application.yml (1-30)`。 * `JwtRelayFilter` 仅做 token 校验并透传 `X-User-Id/X-Username/X-Display-Name/X-Tenant-Id/X-Dept-Id`。参考 `backend/gateway/src/main/java/com/k12study/gateway/filter/JwtRelayFilter.java (1-79)`、`backend/common/common-core/src/main/java/com/k12study/common/core/constants/SecurityConstants.java (1-13)`。 * API 设计要求对外统一 `/api/*`,且后续需扩展到 course/question/ai。参考 `docs/architecture/api-design.md (1-82)`。 diff --git a/docs/plan/modules/question.md b/docs/plan/modules/question.md index a7f374d..2c3e255 100644 --- a/docs/plan/modules/question.md +++ b/docs/plan/modules/question.md @@ -1,11 +1,11 @@ # 问题陈述 -将 `question` 拆分为可演进的习题/作业/批改核心域,并在同一计划中处理错题复习、费曼讲解、推荐闭环与小程序学生端作业可见规则。 +将 `question` 拆分为可演进的习题/作业/批改核心域,并在同一计划中处理错题复习、费曼讲解与小程序学生端作业可见规则。 ## 当前状态(已确认) * 架构与 API 已定义 `question` 为核心业务域,覆盖题库、作业、提交、批改、复习。参考 `docs/architecture/api-design.md (42-61)`、`docs/architecture/logical-view.md (58-66)`。 * 当前后端尚无 `question` 服务代码,能力主要体现在 `init/pg/question` 表结构。参考 `backend/pom.xml (11-20)`、`init/pg/question/10_create_question_tables.sql (1-1272)`。 -* SQL 已覆盖题库/作业/批改/错题/复习/讲解评估,并把推荐与画像并入 `question.rc_*`。参考 `init/pg/question/10_create_question_tables.sql (1041-1272)`。 +* SQL 已覆盖题库/作业/批改/错题/复习/讲解评估;当前阶段 `question` 不承载 recommendation 相关能力。参考 `init/pg/question/10_create_question_tables.sql (1-1272)`。 * 复习策略已有租户级默认种子(E1-E6)。参考 `init/pg/question/20_init_question_seed.sql (8-56)`。 -* 功能清单对错题、变式题、费曼评估、复习提醒、推荐闭环都有明确诉求。参考 `docs/AI智能学习系统功能清单.md (11-24)`、`docs/AI智能学习系统功能清单.md (91-108)`。 +* 功能清单对错题、变式题、费曼评估、复习提醒都有明确诉求。参考 `docs/AI智能学习系统功能清单.md (11-24)`。 ## 模块拆分与设计细节 ### 1) 子模块边界 * `question-bank`:题库、题目、题目知识点关联。 @@ -13,7 +13,6 @@ * `question-grading`:批改任务、答案评分、错因标签、知识点分析。 * `question-review`:错题沉淀、艾宾浩斯计划与执行。 * `question-explanation`:费曼讲解提交、评估与维度评分。 -* `question-recommendation-bridge`:保留 `rc_*` 闭环数据(中期可再独立 recommendation 服务)。 ### 2) 小程序学生端规则 * 小程序仅面向学生,`assignment` 查询必须限制为“学生所在班级 + 已发布 + 节点类型为课堂练习/课后作业”。 * 对应教师创建课程中的课件节点,不在学生端作业列表和详情返回。 @@ -22,17 +21,16 @@ * 强化 `hw_assignment_target.target_ref_id` 的对象完整性(按 `target_type` 校验 class_id/student_id 存在且同租户)。 * 补充“变式题生成任务”数据结构(任务、来源错题、生成题、命中策略),连接功能清单中的举一反三链路。 * `gd_answer_grade` 继续作为统一批改结果主表,避免客观/主观分表回退。 -* 推荐闭环暂存于 `question` 时,需定义清晰子包边界,避免与习题核心耦合扩散。 ### 4) 租户隔离策略 -* 所有 `hw_* / gd_* / rc_*` 读写统一按 `tenant_id` 强过滤。 -* 跨表关联(submission->student、assignment->class、recommendation->user)均执行租户一致性断言。 +* 所有 `hw_* / gd_*` 读写统一按 `tenant_id` 强过滤。 +* 跨表关联(submission->student、assignment->class)均执行租户一致性断言。 * 对 AI 生成、图检索、向量检索调用记录 tenant 维度与来源对象,便于追溯越权风险。 ## 问题点与风险 -* `question` 当前“超大域”承载习题+复习+讲解+推荐,若不先做包级拆分,后续维护成本会快速上升。 +* `question` 当前域内职责仍较重(习题+复习+讲解),若不先做包级拆分,后续维护成本会快速上升。 * 目前无运行时代码,尽管 SQL 完整,但缺业务规则执行层,容易出现“表有字段、行为缺失”。 * `target_ref_id` 弱关联容易引发错投放与越权读取。 * 功能清单的变式题追踪链路在现有表中仍缺专门任务模型。 ## 需确认的设计决策 -* 推荐相关 `rc_*` 是短期保留在 `question`,还是本阶段即拆到 `recommendation` 独立服务。 +* 当前阶段 recommendation 不纳入 `question`,`question` 仅交付习题/作业/批改/复习/讲解相关接口。 * 变式题生成首期是否强依赖 AI 服务,或先以规则模板生成保障可交付。 * 费曼评估通过阈值与回流规则(与系统文档口径)是否纳入一期强约束。