Просмотр исходного кода

chore: 日志增强与生产库对账记录

- JwtInterceptor: token 解析失败日志带 token 预览(前30字符)
- CommissionService/UserService: 用户不存在场景补充 warn 日志
- DatabaseInitializer: 生产库对账候选风险记录(注释)
- AGENTS.md: 环境区分说明(测试库 vs 生产库)
- cfc-web: 版本号 1.0.1300 + CHANGELOG 更新
Xiaogang Liao 2 месяцев назад
Родитель
Сommit
69e2286a35

+ 9 - 2
AGENTS.md

@@ -311,11 +311,18 @@ curl -X POST http://localhost:9082/api/migration/run
 
 ## 数据库
 
-- 地址:`192.168.16.251:3306/zxyj`(账号 `zxyj / zxyj@123`)
-- 只读源库:`bianwoyou.mysql.rds.aliyuncs.com:3305/sfms`(`SfmsDataSourceConfig` 配置)
+> ⚠️ **环境区分(重要)**:`192.168.16.251:3306` 是**测试库**,**不是生产库**。任何针对它的 DDL 迁移、调试、数据改动都只能用于测试验证,不能代表生产环境实际状态。生产数据库连接信息(主机/库名/账号)不在此处,需向运维确认后再填写到下方,禁止把测试库当成生产库来判断线上问题。
+
+- **测试库**:`192.168.16.251:3306/zxyj`(账号 `zxyj / zxyj@123`)—— 仅用于测试/开发验证
+- **只读源库**:`bianwoyou.mysql.rds.aliyuncs.com:3305/sfms`(`SfmsDataSourceConfig` 配置)
+- **生产库**:待补充(向运维确认后填入;所有线上判断必须基于生产库,而非上面的测试库)
 - 建表定义:`cfc-backend/src/main/resources/schema.sql`(完整快照)
 - 迁移入口:`cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java`
 
+> **一线原则**:判断"生产缺列 / Unknown column"等线上问题时,必须以**生产库**为准;测试库(192.168.16.251)的库表结构不代表生产,schema.sql 也只是同步镜像,最终以生产确认结果为准。
+
+> ⚠️ **`children` 表标注冲突**:schema.sql 将 `children` 标为"已废除/并入 family_members",但 `Child` 实体、`ChildMapper`、多个 Service(`AccountCleanupService`、`TaskStatsService`、`GrowthTaskService` 等)仍**活跃使用**,且生产库存在真实的 `children` 表。生产 `children` 表缺 `phone`/`id_card` 两列(`AccountCleanupService.exportUserData` 全字段 SELECT 会报 `Unknown column 'phone'`),用户已决定**不迁移,保持现状**。处理 `children` 相关需求时勿据此表已废弃而误删实体/迁移,也不要重复加 `phone`/`id_card` 迁移。
+
 ## 核心框架约定
 
 - **接口**: 统一 `@PostMapping`,禁止 `@GetMapping/@PutMapping/@DeleteMapping`

+ 1 - 1
cfc-backend/AGENTS.md

@@ -221,7 +221,7 @@ cd cfc-langgraph && pip install -r requirements.txt && uvicorn src.app:app --por
 
 ## NOTES
 
-- 数据库:MySQL 8.0,地址 `192.168.16.251:3306/cfc`
+- 数据库:MySQL 8.0,**测试库**地址 `192.168.16.251:3306`(库名可能为 `zxyj`,参见根 AGENTS.md;该地址只是测试环境,**不是生产库**,生产连接信息需向运维确认)
 - 后端端口:9082,JWT 密钥在 `application.yml`
 - 街道数据:使用静态种子数据,街道匹配有回退机制
 - API冲突已修复:检查所有Controller确保无重复路径映射

+ 12 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -10345,5 +10345,17 @@ public class DatabaseInitializer implements CommandLineRunner {
         // 迁移294: articles 表加 sort_order 列(精选文章推荐排序,越小越靠前)
         ensureColumn("articles", "sort_order", "INT NOT NULL DEFAULT 0 COMMENT '推荐排序值(越小越靠前)'");
         log.info("已添加 articles.sort_order 列(迁移294)");
+
+        // ===== 生产库对账候选风险记录(已核对生产库,2026-09,按用户决定不迁移/暂不动,仅记录)=====
+        // 注:以下为 entity 期望但生产库未对齐.项目,用户已决定保持现状或记为候选,勿重复迁移。
+        // 1. children 表缺 phone、id_card(Child 实体+ChildMapper 仍活跃,AccountCleanupService
+        //    exportUserData 全字段 SELECT 会报 Unknown column 'phone')。schema.sql 已将 children 标为
+        //    已废除/并入 family_members,用户决定不迁移。
+        // 2. user_trigger_rules:生产表仅剩 user_id(PK,auto_increment)/action_config/last_triggered_at,
+        //    实体期望 id/trigger_type/trigger_action/status/created_at 共 8 列,表 0 行且不在 schema.sql。
+        //    UserSegmentationService.getTriggerRules 会查 status,命中时会报 Unknown column 'status'。候选。
+        // 3. promotion_tier.rate_percent:生产用旧模型(tier/team_size_1st/2nd/3rd/total_*),实体期望新模型,
+        //    表 0 行。PromotionTier 服务广泛使用。候选。
+        // 4. promotion_tier_config:实体已废弃,改用 cf_rate_tier(迁移279),保持现状。
     }
 }

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/config/JwtInterceptor.java

@@ -185,7 +185,8 @@ public class JwtInterceptor implements HandlerInterceptor {
             // 避免前端带残留 token 时被静默降级为匿名,导致需登录接口返回
             // "请先登录"(code=500) 而前端仍认为已登录。前端收到 401 后
             // 会清理本地登录态并引导重新登录。
-            log.warn("Token解析失败, 拒绝请求: path={}, error={}", path, e.getMessage());
+            String tokenPreview = token != null ? token.substring(0, Math.min(30, token.length())) + "..." : "null";
+            log.warn("Token解析失败, 拒绝请求: path={}, error={}, token={}", path, e.getMessage(), tokenPreview);
             writeUnauthorized(response);
             return false;
         }

+ 2 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/CommissionService.java

@@ -95,8 +95,10 @@ public class CommissionService {
     // ==================== 邀请码相关 ====================
 
     public String getOrCreateReferralCode(Long userId) {
+        log.info("getOrCreateReferralCode: userId={}", userId);
         User user = userMapper.selectById(userId);
         if (user == null) {
+            log.warn("用户不存在: userId={}", userId);
             throw new RuntimeException("用户不存在");
         }
         if (user.getReferralCode() != null) {

+ 2 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/UserService.java

@@ -1416,8 +1416,10 @@ FamilyMember child = familyMemberMapper.selectById(memberId);
      * 为用户创建新家庭
      */
     public Long createFamilyForUser(Long userId, String familyName) {
+        log.info("createFamilyForUser: userId={}, familyName={}", userId, familyName);
         User user = userMapper.selectById(userId);
         if (user == null) {
+            log.warn("用户不存在: userId={}, familyName={}", userId, familyName);
             throw new RuntimeException("用户不存在");
         }
         // 创建新家庭