Files
wenzi/docs/archive/2026-03-04-cleanup/OPTIMIZATION_PLAN_2026-01-21.md
Your Name 0eed01e9eb docs: 完善项目文档并清理过时文件
新增文档:
- API_INTEGRATION_GUIDE.md: API集成指南(快速开始、SDK示例、常见场景)
- DEPLOYMENT_GUIDE.md: 部署指南(环境要求、生产部署、Docker部署)
- CONFIGURATION_GUIDE.md: 配置指南(环境配置、数据库、Redis、安全)
- DEVELOPMENT_GUIDE.md: 开发指南(环境搭建、项目结构、开发规范)

文档更新:
- api.md: 补充8个缺失的API端点(分享跟踪、回调、用户奖励)

文档清理:
- 归档18个过时文档到 docs/archive/2026-03-04-cleanup/
- 删除3个调试文档(ralph-loop-*)

代码清理:
- 删除4个.bak备份文件
- 删除1个.disabled测试文件

文档结构优化:
- 从~40个文档精简到12个核心文档
- 建立清晰的文档导航体系
- 完善文档间的交叉引用
2026-03-04 10:41:38 +08:00

24 KiB
Raw Permalink Blame History

🦟 蚊子项目 - 系统性修复方案

方案日期: 2026-01-21
基于评审: CODE_REVIEW_REPORT.md, ARCHITECTURE_ASSESSMENT.md, ARCHITECTURE_OPTIMIZATION_REPORT.md, PRODUCT_REVIEW_2026-01-21.md
修复方法: Superpowers Skills框架
目标: 2026-01-21审查报告中的所有P0/P1级问题


📊 修复目标总览

问题严重程度分布

级别 数量 影响 预计工期
🔴 P0级 10 阻碍上线 3-4周
🟡 P1级 8 影响体验 2-3周
🟢 P2级 5 优化提升 1-2周

修复策略

基于Superpowers技能框架采用以下系统性修复策略

  1. 🎯 目标驱动: 优先解决阻碍上线的P0级问题
  2. 🔧 技术重构: 修复技术债务和架构问题
  3. 🏗️ 功能完善: 补齐缺失的核心功能
  4. 🛡️ 安全加固: 解决安全漏洞和风控问题
  5. 📱 前端补充: 开发完整的前端界面
  6. 🔍 测试验证: 完整的测试覆盖
  7. 📊 运维完善: 生产级运维能力
  8. 📚 文档齐全: 完整的技术文档

🎯 第一阶段P0级核心问题修复3周

🔴 P0-001: 优惠券发放系统实现

问题描述: 优惠券验证功能未实现,核心价值无法兑现

修复方案:

// 新增优惠券服务
@Service
public class CouponService {
    
    private final CouponBatchRepository couponBatchRepository;
    private final CouponDistributionRepository couponDistributionRepository;
    
    @Transactional
    public CouponDistribution distributeCoupon(Long activityId, String couponBatchId, Long userId) {
        // 1. 验证优惠券批次有效性
        CouponBatch batch = validateCouponBatch(couponBatchId);
        
        // 2. 检查发放规则
        validateDistributionRules(activityId, batch, userId);
        
        // 3. 随机选择优惠券
        Coupon coupon = selectRandomCoupon(batch);
        
        // 4. 创建发放记录
        CouponDistribution distribution = new CouponDistribution();
        distribution.setActivityId(activityId);
        distribution.setCouponBatchId(couponBatchId);
        distribution.setCouponId(coupon.getId());
        distribution.setUserId(userId);
        distribution.setStatus(AVAILABLE);
        distribution.setDistributedAt(OffsetDateTime.now());
        
        return couponDistributionRepository.save(distribution);
    }
    
    private CouponBatch validateCouponBatch(String couponBatchId) {
        return couponBatchRepository.findByIdAndActive(couponBatchId)
            .orElseThrow(() -> new InvalidCouponBatchException("优惠券批次不存在或已失效"));
    }
    
    private void validateDistributionRules(Long activityId, CouponBatch batch, Long userId) {
        // 验证用户是否已领取
        if (couponDistributionRepository.existsByActivityAndUser(activityId, userId)) {
            throw new CouponAlreadyReceivedException("用户已领取过优惠券");
        }
        
        // 验证批次剩余数量
        long distributedCount = couponDistributionRepository.countByBatchId(batch.getId());
        if (distributedCount >= batch.getTotalCount()) {
            throw new CouponBatchExhaustedException("优惠券批次已发完");
        }
    }
}

实现文件:

  • src/main/java/com/mosquito/project/service/CouponService.java
  • src/main/java/com/mosquito/project/controller/CouponController.java
  • src/main/java/com/mosquito/project/domain/Coupon.java
  • src/main/java/com/mosquito/project/domain/CouponBatch.java
  • src/main/java/com/mosquito/project/domain/CouponDistribution.java
  • src/main/resources/db/migration/V22__Add_coupon_tables.sql

🔴 P0-002: 真实数据统计聚合

问题描述: 使用随机数模拟统计数据,所有决策数据造假

修复方案:

@Service
public class RealTimeStatsService {
    
    private final UserInviteRepository userInviteRepository;
    private final LinkClickRepository linkClickRepository;
    private final UserRepository userRepository;
    private final ActivityRepository activityRepository;
    
    @Scheduled(fixedRate = 60000) // 每分钟更新
    @Transactional(readOnly = true)
    public void aggregateRealTimeStats() {
        List<Activity> activeActivities = activityRepository.findByStatus("ACTIVE");
        
        for (Activity activity : activeActivities) {
            LocalDate today = LocalDate.now();
            
            // 真实统计聚合
            ActivityStats stats = ActivityStats.builder()
                .activityId(activity.getId())
                .statDate(today)
                .totalInvites(countTotalInvites(activity.getId(), today))
                .uniqueInviters(countUniqueInviters(activity.getId(), today))
                .totalClicks(countLinkClicks(activity.getId(), today))
                .uniqueClickers(countUniqueClickers(activity.getId(), today))
                .newUsers(countNewUsers(activity.getId(), today))
                .conversions(countConversions(activity.getId(), today))
                .conversionRate(calculateConversionRate(activity.getId(), today))
                .build();
            
            // 持久化统计数据
            dailyStatsRepository.upsert(stats);
        }
    }
    
    private Long countTotalInvites(Long activityId, LocalDate date) {
        return userInviteRepository.countByActivityIdAndDate(activityId, date);
    }
    
    private Long countUniqueInviters(Long activityId, LocalDate date) {
        return userInviteRepository.countDistinctInviterByActivityIdAndDate(activityId, date);
    }
    
    private Long countLinkClicks(Long activityId, LocalDate date) {
        return linkClickRepository.countByActivityIdAndDate(activityId, date);
    }
    
    private Long countNewUsers(Long activityId, LocalDate date) {
        return userRepository.countByActivityAndDate(activityId, date);
    }
}

实现文件:

  • src/main/java/com/mosquito/project/service/RealTimeStatsService.java
  • src/main/java/com/mosquito/project/domain/ActivityStats.java
  • src/main/java/com/mosquito/project/service/StatisticsAggregationJob.java (重构)

🔴 P0-003: 多级奖励规则持久化

问题描述: 多级奖励规则仅存在于内存,未持久化到数据库

修复方案:

@Service
@Transactional
public class MultiLevelRewardService {
    
    private final ActivityRepository activityRepository;
    private final MultiLevelRewardRuleRepository ruleRepository;
    private final RewardCalculationEngine calculationEngine;
    
    public void saveMultiLevelRewardRules(Long activityId, List<MultiLevelRewardRule> rules) {
        // 验证活动存在
        Activity activity = activityRepository.findById(activityId)
            .orElseThrow(() -> new ActivityNotFoundException("活动不存在"));
        
        // 删除旧规则
        ruleRepository.deleteByActivityId(activityId);
        
        // 保存新规则
        for (MultiLevelRewardRule rule : rules) {
            rule.setActivityId(activityId);
            rule.setCreatedAt(OffsetDateTime.now());
            rule.setUpdatedAt(OffsetDateTime.now());
            
            // 验证规则逻辑
            validateRule(rule);
            
            ruleRepository.save(rule);
        }
        
        // 更新活动实体的多级奖励规则关联
        activity.setMultiLevelRewardRules(rules);
        activityRepository.save(activity);
    }
    
    public Reward calculateMultiLevelReward(Activity activity, Long userId) {
        // 获取用户邀请统计
        UserInviteStats userStats = getUserInviteStats(activity.getId(), userId);
        
        // 获取活动的多级奖励规则
        List<MultiLevelRewardRule> rules = ruleRepository.findByActivityIdOrderByLevel(activity.getId());
        
        return calculationEngine.calculate(activity, userStats, rules);
    }
    
    private void validateRule(MultiLevelRewardRule rule) {
        // 验证衰减系数范围
        if (rule.getDecayCoefficient().compareTo(BigDecimal.ZERO) < 0 || 
            rule.getDecayCoefficient().compareTo(BigDecimal.ONE) > 0) {
            throw new InvalidRewardRuleException("衰减系数必须在0-1之间");
        }
        
        // 验证阈值
        if (rule.getThreshold() <= 0) {
            throw new InvalidRewardRuleException("阈值必须大于0");
        }
    }
}

实现文件:

  • src/main/java/com/mosquito/project/service/MultiLevelRewardService.java
  • src/main/java/com/mosquito/project/service/RewardCalculationEngine.java
  • src/main/resources/db/migration/V23__Fix_multi_level_reward_persistence.sql

🔴 P0-004: 短链接追踪逻辑完善

问题描述: 短链接跳转未记录追踪,传播路径黑盒

修复方案:

@Controller
public class EnhancedShortLinkController {
    
    private final ShareTrackingService shareTrackingService;
    private final InvitationChainService invitationChainService;
    private final RealTimeStatsService realTimeStatsService;
    
    @GetMapping("/r/{code}")
    public ResponseEntity<Void> redirect(@PathVariable String code, HttpServletRequest request) {
        try {
            // 1. 查找短链接
            ShortLinkEntity link = shortLinkService.findByCode(code)
                .orElseThrow(() -> new ShortLinkNotFoundException("短链接不存在"));
            
            // 2. 记录点击追踪
            recordClickTracking(link, request);
            
            // 3. 更新邀请关系(如果适用)
            updateInvitationRelation(link);
            
            // 4. 触发奖励计算(异步)
            triggerRewardCalculation(link);
            
            // 5. 记录实时统计
            updateRealTimeStats(link);
            
            // 6. 执行重定向
            return createRedirectResponse(link);
            
        } catch (Exception e) {
            log.error("Error processing short link redirect: code={}, error={}", code, e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    private void recordClickTracking(ShortLinkEntity link, HttpServletRequest request) {
        LinkClickEntity click = new LinkClickEntity();
        click.setCode(link.getCode());
        click.setActivityId(link.getActivityId());
        click.setInviterUserId(link.getInviterUserId());
        click.setIp(getClientIp(request));
        click.setUserAgent(request.getHeader("User-Agent"));
        click.setReferer(request.getHeader("Referer"));
        click.setClickedAt(OffsetDateTime.now());
        
        linkClickRepository.save(click);
    }
    
    private void updateInvitationRelation(ShortLinkEntity link) {
        // 从链接中解析邀请信息
        InvitationInfo invitationInfo = parseInvitationInfo(link.getParams());
        
        if (invitationInfo != null) {
            invitationChainService.recordInvitation(
                invitationInfo.getActivityId(),
                invitationInfo.getInviterId(),
                invitationInfo.getInviteeId(),
                link.getCode()
            );
        }
    }
    
    private void triggerRewardCalculation(ShortLinkEntity link) {
        // 异步触发奖励计算,避免阻塞重定向
        CompletableFuture.runAsync(() -> {
            try {
                rewardService.processRewardFromClick(link);
            } catch (Exception e) {
                log.error("Failed to process reward from click: {}", e.getMessage(), e);
            }
        });
    }
    
    private void updateRealTimeStats(ShortLinkEntity link) {
        // 更新点击统计
        realTimeStatsService.incrementClickStats(link.getActivityId());
    }
    
    private ResponseEntity<Void> createRedirectResponse(ShortLinkEntity link) {
        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.LOCATION, link.getOriginalUrl());
        return new ResponseEntity<>(headers, HttpStatus.FOUND);
    }
}

实现文件:

  • src/main/java/com/mosquito/project/controller/EnhancedShortLinkController.java
  • src/main/java/com/mosquito/project/service/InvitationChainService.java
  • src/main/java/com/mosquito/project/domain/LinkClickEntity.java (增强)

🔴 P0-005: 成本追踪模块开发

问题描述: 缺少成本追踪模块无法计算CAC/ROI

修复方案:

@Service
public class CostTrackingService {
    
    private final ActivityBudgetRepository budgetRepository;
    private final CostLogRepository costLogRepository;
    private final ROICalculationService roiService;
    
    @Transactional
    public ActivityBudget createActivityBudget(Long activityId, BigDecimal totalBudget, String currency) {
        ActivityBudget budget = new ActivityBudget();
        budget.setActivityId(activityId);
        budget.setTotalBudget(totalBudget);
        budget.setSpentAmount(BigDecimal.ZERO);
        budget.setRemainingBudget(totalBudget);
        budget.setCurrency(currency);
        budget.setCreatedAt(OffsetDateTime.now());
        
        return budgetRepository.save(budget);
    }
    
    @Transactional
    public void recordCost(Long activityId, CostType costType, BigDecimal amount, String description) {
        // 1. 查询预算
        ActivityBudget budget = budgetRepository.findByActivityId(activityId)
            .orElseThrow(() -> new BudgetNotFoundException("活动预算不存在"));
        
        // 2. 检查预算是否足够
        if (budget.getRemainingBudget().compareTo(amount) < 0) {
            throw new InsufficientBudgetException("预算不足");
        }
        
        // 3. 记录成本日志
        CostLog costLog = new CostLog();
        costLog.setActivityId(activityId);
        costLog.setCostType(costType);
        costLog.setAmount(amount);
        costLog.setDescription(description);
        costLog.setCreatedAt(OffsetDateTime.now());
        
        costLogRepository.save(costLog);
        
        // 4. 更新预算
        BigDecimal newSpentAmount = budget.getSpentAmount().add(amount);
        BigDecimal newRemainingAmount = budget.getRemainingBudget().subtract(amount);
        
        budget.setSpentAmount(newSpentAmount);
        budget.setRemainingAmount(newRemainingAmount);
        budget.setUpdatedAt(OffsetDateTime.now());
        
        budgetRepository.save(budget);
        
        // 5. 预算告警检查
        checkBudgetAlert(budget);
    }
    
    public ROIMetrics calculateROI(Long activityId) {
        return roiService.calculateROI(activityId);
    }
    
    private void checkBudgetAlert(ActivityBudget budget) {
        // 预算使用率超过80%时告警
        BigDecimal usageRate = budget.getSpentAmount()
            .divide(budget.getTotalBudget(), 2, RoundingMode.HALF_UP);
        
        if (usageRate.compareTo(new BigDecimal("0.8")) >= 0) {
            alertService.sendBudgetAlert(budget);
        }
    }
}

实现文件:

  • src/main/java/com/mosquito/project/service/CostTrackingService.java
  • src/main/java/com/mosquito/project/service/ROICalculationService.java
  • src/main/java/com/mosquito/project/domain/ActivityBudget.java
  • src/main/java/com/mosquito/project/domain/CostLog.java
  • src/main/resources/db/migration/V24__Add_cost_tracking_tables.sql

🔴 P0-006: 防刷单机制完善

问题描述: 防刷单机制严重不足,成本失控风险

修复方案:

@Service
public class AntiFraudService {
    
    private final DeviceFingerprintService deviceFingerprintService;
    private final BehaviorAnalysisService behaviorAnalysisService;
    private final RuleEngineService ruleEngineService;
    private final BlacklistService blacklistService;
    
    @Transactional
    public FraudCheckResult checkFraud(Long activityId, Long userId, HttpServletRequest request, String action) {
        // 1. 设备指纹检查
        DeviceFingerprint fingerprint = deviceFingerprintService.getFingerprint(request);
        
        // 2. 行为模式分析
        BehaviorPattern behavior = behaviorAnalysisService.analyzeBehavior(activityId, userId, action);
        
        // 3. 规则引擎检测
        RuleEngineResult ruleResult = ruleEngineService.evaluateRules(
            activityId, userId, fingerprint, behavior, action);
        
        // 4. 黑名单检查
        boolean isBlacklisted = blacklistService.isBlacklisted(userId, fingerprint);
        
        // 5. 综合风险评估
        FraudRisk risk = calculateRisk(ruleResult, fingerprint, behavior, isBlacklisted);
        
        // 6. 记录检测结果
        recordFraudCheck(activityId, userId, fingerprint, risk, action);
        
        // 7. 根据风险等级采取行动
        return takeActionBasedOnRisk(risk);
    }
    
    private FraudRisk calculateRisk(RuleEngineResult ruleResult, 
                                     DeviceFingerprint fingerprint, 
                                     BehaviorPattern behavior, 
                                     boolean isBlacklisted) {
        int riskScore = 0;
        List<String> riskFactors = new ArrayList<>();
        
        // 规则引擎风险评分
        if (ruleResult.isHighRisk()) {
            riskScore += 50;
            riskFactors.add("规则引擎高风险");
        }
        
        // 设备指纹异常
        if (fingerprint.isSuspicious()) {
            riskScore += 30;
            riskFactors.add("设备指纹异常");
        }
        
        // 行为模式异常
        if (behavior.isAbnormal()) {
            riskScore += 40;
            riskFactors.add("行为模式异常");
        }
        
        // 黑名单检查
        if (isBlacklisted) {
            riskScore += 100;
            riskFactors.add("黑名单用户");
        }
        
        return new FraudRisk(riskScore, riskFactors);
    }
    
    private FraudCheckResult takeActionBasedOnRisk(FraudRisk risk) {
        if (risk.getScore() >= 80) {
            // 高风险:拒绝并标记
            return FraudCheckResult.rejected("高风险行为检测到");
        } else if (risk.getScore() >= 60) {
            // 中风险:需要人工审核
            return FraudCheckResult.requiresManualReview("需要人工审核");
        } else if (risk.getScore() >= 40) {
            // 低风险:增加验证
            return FraudCheckResult.requiresAdditionalValidation("需要额外验证");
        } else {
            // 正常:允许通过
            return FraudCheckResult.approved("通过风控检查");
        }
    }
}

实现文件:

  • src/main/java/com/mosquito/project/service/AntiFraudService.java
  • src/main/java/com/mosquito/project/service/DeviceFingerprintService.java
  • src/main/java/com/mosquito/project/service/BehaviorAnalysisService.java
  • src/main/java/com/mosquito/project/service/RuleEngineService.java

🔴 P0-007: 管理后台开发

问题描述: 管理后台完全缺失,管理员无法使用系统

修复方案:

// 管理后台技术栈
// 框架: Vue 3 + TypeScript + Element Plus
// 状态管理: Pinia
// 路由: Vue Router 4
// 构建: Vite

// 核心功能模块
1. 活动管理 (CRUD + 状态管理)
2. 用户管理 (查询 + 权限管理)
3. 数据可视化 (实时看板 + 报表)
4. 系统配置 (参数设置 + 规则管理)
5. 客户支持 (查询工具 + 诊断)
6. 安全监控 (风控 + 审计日志)

实现文件:

  • frontend/admin/ (完整管理后台项目)
    • src/views/Dashboard.vue
    • src/views/ActivityManagement.vue
    • src/views/UserManagement.vue
    • src/views/DataAnalytics.vue
    • src/views/SystemConfig.vue
    • src/views/SecurityMonitoring.vue

🔴 P0-008: 用户端H5开发

问题描述: 用户端H5完全缺失用户无法分享

修复方案:

// 用户端H5技术栈
// 框架: Vue 3 + TypeScript + Vant 4
// 状态管理: Pinia
// 构建: Vite
// 移动端优化: 响应式设计 + PWA

// 核心页面
1. 邀请页面 (活动介绍 + 分享入口)
2. 分享页面 (生成海报 + 复制链接)
3. 个人中心 (邀请记录 + 奖励查看)
4. 排行榜 (实时排名 + 数据展示)
5. 活动列表 (浏览活动 + 参与历史)

实现文件:

  • frontend/h5/ (完整用户端H5项目)
    • src/views/InvitePage.vue
    • src/views/SharePage.vue
    • src/views/ProfilePage.vue
    • src/views/LeaderboardPage.vue
    • src/views/ActivityListPage.vue

🎯 第二阶段P1级影响体验问题修复2-3周

🟡 P1-001: 活动状态机实现

🟡 P1-002: 客户支持工具开发

🟡 P1-003: 业务监控指标实现

🟡 P1-004: API设计一致性

🟡 P1-006: 限流熔断完善

🟡 P1-007: 健康检查增强

🟡 P1-008: 海报渲染降级对接


🎯 第三阶段P2级长期优化问题1-2周

🟢 P2-001: 客户查询后台

🟢 P2-002: 高级风控规则引擎

🟢 P2-003: 客户自助分析工具

🟢 P2-004: 多租户隔离

🟢 P2-005: 移动端原生应用


📈 预期修复成果

修复前后对比

评估维度 修复前 修复后 提升
功能完整性 55% 100% +82%
安全性 60% 95% +58%
用户体验 30% 90% +200%
运维能力 40% 85% +113%
生产就绪 45% 95% +111%

核心价值主张验证

价值主张 修复前状态 修复后状态 验证结果
降低CAC 50% 无法计算 精确计算实际降低45% 基本达成
K因子>1 无法计算 精确计算实际达到1.2 超额达成
自动激励 无法实现 完整实现自动化率100% 完全达成
数据驱动 假数据 真实数据,实时更新 完全达成

📋 交付清单

第一阶段交付物

后端修复 (8个核心服务)

  • CouponService.java - 优惠券发放系统
  • RealTimeStatsService.java - 真实数据统计
  • MultiLevelRewardService.java - 多级奖励持久化
  • EnhancedShortLinkController.java - 完善追踪逻辑
  • CostTrackingService.java - 成本追踪模块
  • AntiFraudService.java - 防刷单机制
  • 管理后台API接口增强
  • 数据库迁移脚本 (V22-V24)

前端开发 (2个完整项目)

  • 管理后台 (Vue 3 + TypeScript)
  • 用户端H5 (Vue 3 + TypeScript)

第二阶段交付物

架构优化 (5个关键模块)

  • 活动状态机实现
  • 业务监控指标体系
  • API一致性重构
  • 性能优化实现
  • 安全加固完善

运维支持 (4个核心系统)

  • 完整监控方案
  • 自动化部署流程
  • 客户支持工具
  • 备份恢复机制

🚀 实施计划

时间安排

Week 1-2: P0核心问题修复

  • Day 1-3: 优惠券系统 + 真实数据统计
  • Day 4-6: 多级奖励持久化 + 短链接追踪
  • Day 7-8: 成本追踪 + 防刷单机制

Week 3: 管理后台开发

  • Day 1-5: 管理后台核心功能
  • Day 6-7: 数据可视化 + 系统配置

Week 4: 用户端H5开发

  • Day 1-5: H5核心页面开发
  • Day 6-7: 优化完善 + 测试

Week 5-6: P1级问题修复

  • Week 5: 状态机 + 监控指标
  • Week 6: API一致性 + 性能优化

Week 7: 集成测试和部署

  • Day 1-3: 集成测试
  • Day 4-5: 性能测试
  • Day 6-7: 生产部署

资源配置

开发团队 (6人)

  • 后端开发: 2人 (P0问题修复)
  • 前端开发: 2人 (管理后台 + H5)
  • 测试工程师: 1人 (测试用例 + 自动化)
  • DevOps工程师: 1人 (运维自动化)

质量保证

  • Code Review: 所有代码必须通过审查
  • 单元测试: 覆盖率要求 90%+
  • 集成测试: 核心功能100%覆盖
  • 安全测试: 第三方安全扫描

成功标准

功能完整性验证

  • 所有P0级问题修复完成
  • 核心功能100%可用
  • 管理后台功能完整
  • 用户端H5功能完整

质量标准验证

  • 单元测试覆盖率 ≥ 90%
  • 集成测试覆盖率 ≥ 85%
  • 性能测试达标 (响应时间 < 200ms)
  • 安全测试无高危漏洞

运维能力验证

  • 一键部署成功
  • 监控告警正常
  • 日志聚合完善
  • 备份恢复可用

系统性修复方案完成时间: 2026-01-21
使用技能: Superpowers Skills Framework
预期效果: 蚊子项目从"不建议上线"提升至"强烈推荐上线"