Commit Graph

84 Commits

Author SHA1 Message Date
4aab0bcbf2 提案以及归档
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m39s
2026-04-18 09:10:29 +08:00
5d9be1d7e4 fix: 修正轮询配置多匹配逻辑,支持同卡匹配多个配置并按 priority 合并 interval
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m27s
核心变更:
- MatchConfig 改为 MatchConfigs,返回所有匹配配置
- MergedTaskIntervals 按 task type 合并各配置,选取最高优先级(非 nil 且最小 priority 值)
- hasAnyEnabledInterval 过滤所有 interval 均为 NULL 的配置
- calcInitialDelay 重构为纯函数,接收 interval 参数
- 移除 getEnabledTaskTypes 和 getIntervalByTaskType(被 MergedTaskIntervals 替代)
- scheduler.go 新增心跳 key + 顶层 panic recovery + Init 完成守卫
- initializer.go 批量失败日志升级为 Error,逐条检查 Pipeline 命令错误
- 数据迁移:禁用 id=29 的轮询配置(所有 interval 均为 NULL)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 14:27:47 +08:00
5065d925ad fix: 修正套餐激活和时间字段nullable问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m33s
核心变更:
1. Model层时间字段改为*time.Time并设为nullable
   - PackageUsage.ActivatedAt/ExpiresAt
   - PersonalCustomerDevice/ICCID/Phone.LastUsedAt/VerifiedAt

2. 数据库迁移:
   - activated_at/expires_at列移除NOT NULL约束
   - 清洗零值记录(status=0且activated_at<'2000-01-01')

3. 新增ActivateSpecificPackage方法:精准激活指定套餐,
   修复HandlePackageQueueActivation从"查找过期包"改为直接激活payload指定套餐

4. 新增孤儿套餐恢复扫描:Worker启动或每次套餐检查时,
   自动发现并恢复无status=1主套餐的孤儿载体

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 11:14:39 +08:00
8bf1282378 归档: add-polling-card-status-with-verbose-log,同步主规范
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m24s
change 目录归档至 openspec/changes/archive/2026-04-15-add-polling-card-status-with-verbose-log/
新建主规范 openspec/specs/polling-card-status-task/spec.md(6个需求)
追加 verbose log 需求至 openspec/specs/polling-task-handlers/spec.md(4个新需求)
protect handler 规范更新字段名:network_status → network_status_at_check + action_taken

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 12:23:05 +08:00
4a1e44f9e1 提案
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
2026-04-15 11:17:23 +08:00
d9de704d73 归档
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 49s
2026-04-14 12:14:29 +08:00
7308afe801 归档
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m18s
2026-04-13 15:03:02 +08:00
7e613a0d2b 归档: fix-status-convention-comments
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 12:21:02 +08:00
677d6239ce fix: 统一佣金状态常量并修复佣金明细关联查询
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m33s
- 删除 model/commission.go 中与 constants 包冲突的旧常量(值=1/2)
- 所有服务层改用 constants.CommissionStatusReleased(值=3)写入和查询
- 数据库迁移:status 1→3(已发放),2→4(已失效)
- 修复佣金明细列表接口,通过 JOIN 关联返回 order_no、iccid、virtual_no、order_created_at
- 新增 seller_shop_id / seller_shop_name 销售来源字段
- 统计接口过滤条件从精确匹配改为排除无效(NOT IN 4,99)
- 更新 OpenAPI 文档及 commission-record-query spec
2026-04-11 10:42:37 +08:00
5496cb58aa feat: 订单创建时快照买家手机号/昵称和套餐类型
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
新增字段:
- tb_order: buyer_phone, buyer_nickname(个人客户下单时快照)
- tb_order_item: package_type(套餐类型快照)

后台订单列表支持按 buyer_phone 精确过滤查询。

OpenSpec: order-buyer-snapshot
2026-04-10 17:12:56 +08:00
afc6d7fc76 docs: 归档 excel-import-refactor,同步更新主 specs
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 50s
- 将变更目录移至 archive/2026-04-09-excel-import-refactor
- device-import spec:更新为固定列位置读取(IMEI 调整至第5列),新增 MaxSimSlots 范围校验说明
- iot-card-import-task spec:更新为固定列位置读取,新增"导入批次支持卡业务类型"需求

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 17:37:44 +08:00
ff7e749bf2 归档 2026-04-09 14:53:48 +08:00
6dfc5c0301 feat: 资产解析接口新增实名时间字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m5s
- AssetResolveResponse 新增 real_name_at 字段:card 类型取 first_realname_at,device 类型取绑定卡中最小的实名时间
- BoundCardInfo 新增 real_name_at 字段:各卡自己的 first_realname_at
- RefreshCardDataFromGateway 手动刷新路径补写实名时间:检测到 0→1 变化时同步写入 first_realname_at
- 同步更新 asset-resolve 规格文档

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 12:12:28 +08:00
e9df1e7ded feat: IoT卡新增绑定设备虚拟号快照字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m28s
- tb_iot_card 新增 device_virtual_no 字段,存储绑定设备的虚拟号快照
- 列表/详情接口响应新增 device_virtual_no 字段
- 列表接口 is_standalone 改为可选参数(不传返回全部卡)
- 移除列表接口 virtual_no 查询参数
- 绑卡/解绑时同步更新 device_virtual_no 快照
- 设备导入时批量写入 device_virtual_no 快照
- 归档 feat-iot-card-device-virtual-no 变更提案

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 10:50:46 +08:00
80c6f6c756 feat: 资产标识符标准化、资产历史订单查询及导入虚拟号强制验证
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m21s
主要变更:
- 新增 AssetIdentifier 模型及 Store,统一管理资产标识符(ICCID/IMEI/SN 等)
- 新增迁移:asset_identifier 表、order 表新增 asset_identifier 字段、iot_card.virtual_no NOT NULL 约束
- 资产 Handler/Service/Route 全面重构,支持标识符路由查询与解析
- 新增资产历史订单查询接口,支持跨设备/卡/钱包维度的订单聚合
- 设备与物联卡导入任务强制校验虚拟号,缺失时直接拒绝
- Excel 工具函数优化,前端导入指引文档同步更新
- 归档三个 OpenSpec 提案:asset-identifier-standardization、asset-historical-orders、import-mandatory-virtual-no
- 更新 OpenAPI 文档及相关 DTO

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-07 17:39:36 +08:00
434a8b0349 feat: 轮询系统重构(分片队列 + 停复机统一 + Handler 拆分)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m46s
【核心变更】

1. 停复机逻辑统一(StopResumeService)
   - 新增 EvaluateAndAct 统一入口,封装三条件停复机判断
   - 停机条件:无套餐(no_package) / 流量耗尽(traffic_exhausted) / 未实名(not_realname)
   - 复机条件:stop_reason 合规 + 有套餐且未耗尽 + 已实名或行业卡
   - 修复设备套餐 Bug:hasValidPackage 按 device_id 查套餐,而非仅 iot_card_id
   - 设备维度停复机加幂等锁(Redis SetNX,TTL 30s),防止多卡并发重复调 Gateway

2. Redis 分片队列(PollingQueueManager)
   - 新建 queue_manager.go,封装所有轮询 Redis 操作
   - 16 分片 Sorted Set,Key 格式:polling:shard:{shardID}:queue:{taskType}
   - Lua 脚本原子出队(ZRANGEBYSCORE + 分批 ZREM),消除竞态窗口
   - 新增背压检测:队列深度超 50 万时 Scheduler 跳过该分片
   - RemoveFromAllQueues 覆盖 4 种任务类型(含 protect)

3. Handler 拆分(polling_handler.go 1360行 → 5个专注文件)
   - polling_base.go:共享基类(并发控制/卡缓存/重入队)
   - polling_realname_handler.go:实名采集,实名 0→1 时立即触发复机
   - polling_carddata_handler.go:流量采集,保留跨月边界检测逻辑
   - polling_package_handler.go:套餐采集,委托 EvaluateAndAct 决策
   - polling_protect_handler.go:保护期一致性检查,保护期内强制修正

4. 配置管理(PollingConfigManager)
   - 新建 config_manager.go,从 scheduler.go 提取配置职责
   - 内存缓存 + 5 分钟定时刷新,刷新失败保留原缓存
   - 修复 getCardCondition:停机卡返回 suspended,不再错配 activated 配置

5. 渐进式初始化(CardInitializer)
   - 新建 initializer.go,分批加载(每批 10 万),批次间 sleep 500ms
   - 过滤 enable_polling=false 的卡,初始化完成前 Scheduler 不出队

6. 卡生命周期服务(PollingLifecycleService)
   - 新建 lifecycle_service.go,替代已删除的 callbacks.go 和 api_callback.go
   - OnCardCreated/OnCardEnabled/OnCardStatusChanged 入队前检查 enable_polling

7. Scheduler 精简(1000+行 → 227行)
   - 保留纯调度循环:scheduleLoop + processShardSchedule + enqueueBatch
   - 保留每 10 秒触发套餐过期检测和流量重置
   - 移除所有 DB 操作、配置加载、卡初始化逻辑

8. 轮询管控 API(enable_polling)
   - 新增 PUT /api/admin/assets/:id/polling-status 接口
   - 支持对设备/卡维度开关轮询,关闭后从所有分片队列移除

9. 数据库迁移
   - 000103:tb_device 新增 enable_polling 字段(boolean, NOT NULL, DEFAULT true)
   - 000104:新增 suspended 轮询配置,为 activated 配置补全 protect_check_interval

【文件统计】
- 新增:19 个文件(handler × 5、polling 组件 × 4、迁移 × 3 等)
- 修改:20 个文件(bootstrap 注入、store 接口、monitoring 适配分片等)
- 删除:3 个文件(polling_handler.go、callbacks.go、api_callback.go)

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-07 12:27:04 +08:00
8980e6d999 fix: 补全三处轮询覆盖缺口
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m11s
问题一:protect 轮询任务从未被调度器初始化入队
PollingConfig 新增 protect_check_interval 字段(NULL=不参与),
调度器 initCardsBatch/initCardPolling/requeueCard 补全 protect 队列
初始化逻辑,IotCard 新增 last_protect_check_at 记录上次检查时间。
迁移文件:000102_add_polling_protect_fields

问题二:设备套餐流量耗尽时绑定卡未被停机
UsageService.checkAndTriggerSuspension 新增 carrier_type=device 分支,
通过 DeviceSimBindingStore.ListByDeviceID 查询绑定卡,对每张卡异步
触发 CheckAndStopCard,同步注入 Bootstrap 依赖。

问题三:主套餐过期后不立即停机,依赖下次轮询兜底
PackageActivationHandler.processExpiredPackage 在 updateCarrierSuspended
Status 后,若载体无后续生效套餐,立即异步调用 CheckAndStopCard(iot_card
类型直接触发,device 类型遍历绑定卡),消除停机延迟窗口。

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-02 14:36:24 +08:00
8b5cd50576 chore: 归档 fix-stop-resume-lifecycle-engine 变更提案
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-31 18:12:44 +08:00
f339fb1987 fix: 资产钱包自动创建机制 — 修复C端购买时钱包不存在报错
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
- client_order: 新增 getOrCreateWallet 兜底,钱包不存在时自动创建
- device_import: 设备导入事务内同步创建设备钱包
- iot_card_import: IoT卡批量导入后批量创建卡钱包
- queue/handler: 传递 AssetWalletStore 给两个导入 handler
- migration 000098: 为存量IoT卡和设备补建资产钱包
2026-03-30 11:37:41 +08:00
cebcada950 refactor: 流量系统重构 — 增量累加算法 + 日粒度缓冲 + 旧详单清理
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m16s
核心改造:
- 增量算法:流量计算从覆盖式改为增量累加(gateway - lastReading),支持上游运营商重置检测
- 日流量缓冲:insertDataUsageRecord 改为 Redis INCRBYFLOAT,每日凌晨落盘到 tb_card_daily_usage
- 运营商:新增 data_reset_day 字段(联通=27,其余=1)
- IoT卡:新增 last_gateway_reading_mb 字段存储上次网关读数
- 查询层:新建 TrafficQueryService 合并 Redis(今日)+ DB(历史)数据源
- 清理:删除 DataUsageRecord model/store,移除 polling_handler 旧引用

迁移:000094-000097(carrier字段、iot_card字段、数据初始化、日流量表)
2026-03-30 09:59:30 +08:00
b9733c4913 fix: 修正零售价架构错误 + 清理旧微信配置 + 归档提案 + 前端接口文档
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m12s
1. 修正 retail_price 架构:
   - 删除 batch-pricing 接口的 pricing_target 字段和 retail_price 分支
     (上级只能改下级成本价,不能改零售价)
   - 新增 PATCH /api/admin/packages/:id/retail-price 接口
     (代理自己改自己的零售价,校验 retail_price >= cost_price)

2. 清理旧微信 YAML 配置(已全部迁移到数据库 tb_wechat_config):
   - 删除 config.yaml 中 wechat.official_account 配置节
   - 删除 NewOfficialAccountApp() 旧工厂函数
   - 清理 personal_customer service 中的死代码(旧登录/绑定微信方法)
   - 清理 docker-compose.prod.yml 中旧微信环境变量和证书挂载注释

3. 归档四个已完成提案到 openspec/changes/archive/

4. 新增前端接口变更说明文档(docs/前端接口变更说明.md)

5. 修正归档提案和 specs 中关于 pricing_target 的错误描述
2026-03-19 17:39:43 +08:00
817d0d6e04 更新openspec
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 46s
2026-03-17 14:22:01 +08:00
f3297f0529 docs: 归档 asset-wallet-interface OpenSpec 提案,更新卡钱包 spec
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-16 23:30:48 +08:00
b9c3875c08 feat: 新增数据库迁移,重命名 device_no 为 virtual_no,新增 iot_card.virtual_no 和 package.virtual_ratio 字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m3s
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-14 18:27:28 +08:00
b5147d1acb 设备的部分改造
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m34s
2026-03-10 10:34:08 +08:00
b52cb9a078 fix: 修复梯度佣金档位字段缺失,补全授权接口响应字段及强充有效状态
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m27s
- OneTimeCommissionTierDTO 补充 operator 字段映射
- GrantCommissionTierItem 补充 dimension/stat_scope 字段(从全局配置合并)
- 系列授权列表/详情补充强充锁定状态和强充金额的有效值计算
- 同步 OpenSpec 主规范并归档变更文档
2026-03-05 11:23:28 +08:00
e0cb4498e6 docs: 归档 refactor-agent-series-grant 变更文档
将已完成的变更(proposal、design、tasks、delta specs)归档至 openspec/changes/archive/2026-03-04-refactor-agent-series-grant/。变更内容:合并系列分配和套餐分配为系列授权(Grant)、新增梯度佣金模式、新增代理层强充层级规则。50/50 任务全部完成。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-04 11:37:33 +08:00
61155952a7 feat: 新增代理分配套餐上架状态(shelf_status)功能
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m56s
- 新增数据库迁移:为 shop_package_allocation 表添加 shelf_status 字段
- 更新模型/DTO:ShopPackageAllocation 增加 ShelfStatus 字段及相关枚举
- 更新套餐分配 Service:支持上架/下架状态管理逻辑
- 更新套餐 Store/Service:根据 shelf_status 过滤可售套餐
- 更新购买验证 Service:引入上架状态校验逻辑
- 归档 OpenSpec 变更:2026-03-02-agent-allocation-shelf-status
- 同步更新主规范文档:allocation-shelf-status、package-management、purchase-validation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 15:38:54 +08:00
e661b59bb9 feat: 实现订单超时自动取消功能,支持钱包余额解冻和 Asynq Scheduler 统一调度
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m58s
- 新增 expires_at 字段和复合索引,待支付订单 30 分钟超时自动取消
- 实现 cancelOrder/unfreezeWalletForCancel 钱包余额解冻逻辑
- 创建 Asynq 定时任务(order_expire/alert_check/data_cleanup)
- 将原有 time.Ticker 轮询迁移至 Asynq Scheduler 统一调度
- 同步 delta specs 到 main specs 并归档变更
2026-02-28 17:16:15 +08:00
5bb0ff0ddf fix: 修复代理钱包订单创建逻辑,拆分后台/H5端下单方法并归档变更
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m54s
- 拆分订单创建为 CreateAdminOrder(后台一步支付)和 CreateH5Order(H5 两步支付)
- 新增 CreateAdminOrderRequest DTO,后台仅允许 wallet/offline 支付方式
- 同步 delta specs 到主规格(order-payment 更新 + admin-order-creation 新增)
- 归档 fix-agent-wallet-order-creation 变更
- 新增 implement-order-expiration 变更提案
2026-02-28 16:31:31 +08:00
8ed3d9da93 feat: 实现代理钱包订单创建和订单角色追踪功能
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m0s
新增功能:
- 代理在后台使用 wallet 支付时,订单直接完成(扣款 + 激活套餐)
- 支持代理自购和代理代购场景
- 新增订单角色追踪字段(operator_id、operator_type、actual_paid_amount、purchase_role)
- 订单查询支持 OR 逻辑(buyer_id 或 operator_id)
- 钱包流水记录交易子类型和关联店铺
- 佣金逻辑调整:代理代购不产生佣金

数据库变更:
- 订单表新增 4 个字段和 2 个索引
- 钱包流水表新增 2 个字段
- 包含迁移脚本和回滚脚本

文档:
- 功能总结文档
- 部署指南
- OpenAPI 文档更新
- Specs 同步(新增 agent-order-role-tracking capability)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 14:11:42 +08:00
03a0960c4d refactor: 数据权限过滤从 GORM Callback 改为 Store 层显式调用
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m2s
- 移除 RegisterDataPermissionCallback 和 SkipDataPermission 机制
- 在 Auth 中间件预计算 SubordinateShopIDs 并注入 Context
- 新增 ApplyShopFilter/ApplyEnterpriseFilter/ApplyOwnerShopFilter 等 Helper 函数
- 所有 Store 层查询方法显式调用数据权限过滤函数
- 权限检查函数 CanManageShop/CanManageEnterprise 改为从 Context 获取数据

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 16:38:52 +08:00
18daeae65a feat: 钱包系统分离 - 代理钱包与卡钱包完全隔离
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m17s
## 变更概述
将统一钱包系统拆分为代理钱包和卡钱包两个独立系统,实现数据表和代码层面的完全隔离。

## 数据库变更
- 新增 6 张表:tb_agent_wallet、tb_agent_wallet_transaction、tb_agent_recharge_record、tb_card_wallet、tb_card_wallet_transaction、tb_card_recharge_record
- 删除 3 张旧表:tb_wallet、tb_wallet_transaction、tb_recharge_record
- 代理钱包:按 (shop_id, wallet_type) 唯一标识,支持主钱包和分佣钱包
- 卡钱包:按 (resource_type, resource_id) 唯一标识,支持物联网卡和设备

## 代码变更
- Model 层:新增 AgentWallet、AgentWalletTransaction、AgentRechargeRecord、CardWallet、CardWalletTransaction、CardRechargeRecord 模型
- Store 层:新增 6 个独立 Store,支持事务、乐观锁、Redis 缓存
- Service 层:重构 commission_calculation、commission_withdrawal、order、recharge 等 8 个服务
- Bootstrap 层:更新 Store 和 Service 依赖注入
- 常量层:按钱包类型重新组织常量和 Redis Key 生成函数

## 技术特性
- 乐观锁:使用 version 字段防止并发冲突
- 多租户:支持 shop_id_tag 和 enterprise_id_tag 过滤
- 事务管理:所有余额变动使用事务保证 ACID
- 缓存策略:Cache-Aside 模式,余额变动后删除缓存

## 业务影响
- 代理钱包和卡钱包业务完全隔离,互不影响
- 为独立监控、优化、扩展打下基础
- 提升代理钱包的稳定性和独立性

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-25 09:51:00 +08:00
c665f32976 feat: 套餐系统升级 - Worker 重构、流量重置、文档与规范更新
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m54s
- 重构 Worker 启动流程,引入 bootstrap 模块统一管理依赖注入
- 实现套餐流量重置服务(日/月/年周期重置)
- 新增套餐激活排队、加油包绑定、囤货待实名激活逻辑
- 新增订单创建幂等性防重(Redis 业务键 + 分布式锁)
- 更新 AGENTS.md/CLAUDE.md:新增注释规范、幂等性规范,移除测试要求
- 添加套餐系统升级完整文档(API文档、使用指南、功能总结、运维指南)
- 归档 OpenSpec package-system-upgrade 变更,同步 specs 到主目录
- 新增 queue types 抽象和 Redis 常量定义
2026-02-12 14:24:15 +08:00
804145332b chore: 归档轮询系统实现变更 (polling-system-implementation)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 44s
已完成千万级卡规模轮询系统的完整实现和集成测试验证,将变更归档到 openspec/changes/archive/2026-02-10-polling-system-implementation/

主要成果:
- 三大轮询任务:实名检查、卡流量检查、套餐流量检查
- 快速启动(<10秒)和渐进式初始化
- 完整运营工具:配置管理、并发控制、监控面板、告警系统、数据清理、手动触发
- 任务完成度:215/216(99.5%)
- 所有 24 个新增接口已生成 OpenAPI 文档

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 10:28:47 +08:00
b11edde720 fix: 注册佣金计算任务 Handler 到队列处理器
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m19s
佣金计算任务 (commission:calculate) 的 Handler 已实现但未在队列处理器中注册,
导致支付成功后入队的佣金计算任务永远不会被消费执行。

变更内容:
- 在 pkg/queue/handler.go 中添加 registerCommissionCalculationHandler() 方法
- 创建所有需要的 Store 和 Service 依赖
- 在 RegisterHandlers() 中调用注册方法

修复后,订单支付成功将正确触发佣金计算和发放。

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 16:08:03 +08:00
b18ecfeb55 refactor: 一次性佣金配置从套餐级别提升到系列级别
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m29s
主要变更:
- 新增 tb_shop_series_allocation 表,存储系列级别的一次性佣金配置
- ShopPackageAllocation 移除 one_time_commission_amount 字段
- PackageSeries 新增 enable_one_time_commission 字段控制是否启用一次性佣金
- 新增 /api/admin/shop-series-allocations CRUD 接口
- 佣金计算逻辑改为从 ShopSeriesAllocation 获取一次性佣金金额
- 删除废弃的 ShopSeriesOneTimeCommissionTier 模型
- OpenAPI Tag '系列分配' 和 '单套餐分配' 合并为 '套餐分配'

迁移脚本:
- 000042: 重构佣金套餐模型
- 000043: 简化佣金分配
- 000044: 一次性佣金分配重构
- 000045: PackageSeries 添加 enable_one_time_commission 字段

测试:
- 新增验收测试 (shop_series_allocation, commission_calculation)
- 新增流程测试 (one_time_commission_chain)
- 删除过时的单元测试(已被验收测试覆盖)
2026-02-04 14:28:44 +08:00
5a90caa619 feat(shop-role): 实现店铺角色继承功能和权限检查优化
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m39s
- 新增店铺角色管理 API 和数据模型
- 实现角色继承和权限检查逻辑
- 添加流程测试框架和集成测试
- 更新权限服务和账号管理逻辑
- 添加数据库迁移脚本
- 归档 OpenSpec 变更文档

Ultraworked with Sisyphus
2026-02-03 10:06:13 +08:00
80f560df33 refactor(account): 统一账号管理API、完善权限检查和操作审计
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m17s
- 合并 customer_account 和 shop_account 路由到统一的 account 接口
- 新增统一认证接口 (auth handler)
- 实现越权防护中间件和权限检查工具函数
- 新增操作审计日志模型和服务
- 更新数据库迁移 (版本 39: account_operation_log 表)
- 补充集成测试覆盖权限检查和审计日志场景
2026-02-02 17:23:20 +08:00
76b539e867 chore: 归档 OpenSpec 变更 refactor-series-binding-to-series-id
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m22s
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-02 12:21:00 +08:00
a30b3036bb feat(iot-card-import): 为导入任务接口添加平台用户权限控制
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m10s
- 在 Import/List/GetByID 接口添加用户类型校验
- 仅超级管理员和平台用户可访问
- 同步更新 OpenAPI 路由描述
- 补充集成测试覆盖权限拒绝场景
2026-02-02 10:25:03 +08:00
d81bd242a4 fix(force-recharge): 补充强充配置缺失的接口和数据库字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m19s
- 订单管理:增加 payment_method 字段支持,合并代购订单逻辑
- 套餐系列分配:增加强充配置字段(enable_force_recharge、force_recharge_amount、force_recharge_trigger_type)
- 数据库迁移:添加 force_recharge_trigger_type 字段
- 测试:更新订单服务测试用例
- OpenSpec:归档 fix-force-recharge-missing-interfaces 变更
2026-01-31 15:34:32 +08:00
d309951493 feat(import): 用 Excel 格式替换 CSV 导入
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m33s
- 删除 CSV 解析代码,新增 Excel 解析器 (excelize)

- 更新 IoT 卡和设备导入任务处理器

- 更新 API 路由文档和前端接入指南

- 归档变更到 openspec/changes/archive/

- 同步 delta specs 到 main specs
2026-01-31 14:13:02 +08:00
62708892ec 文档
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m2s
2026-01-31 13:06:30 +08:00
65b4127b84 Merge branch 'emdash/wechat-official-account-payment-integration-30g'
# Conflicts:
#	README.md
#	cmd/api/main.go
#	internal/bootstrap/dependencies.go
#	pkg/config/config.go
#	pkg/config/defaults/config.yaml
2026-01-30 17:32:33 +08:00
bf591095a2 微信相关能力 2026-01-30 17:25:30 +08:00
ffeb0417c0 登录权限返回修改 2026-01-30 17:22:38 +08:00
1cf17e8f14 清理冗余的梯度返佣(TierCommission)配置
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m46s
- 移除 Model 层:删除 ShopSeriesCommissionTier 模型及相关字段
- 更新 DTO:删除 TierCommissionConfig、TierEntry 类型及相关请求/响应字段
- 删除 Store 层:移除 ShopSeriesCommissionTierStore 及相关查询逻辑
- 简化 Service 层:删除梯度返佣处理逻辑,统计查询移除 tier_bonus 字段
- 数据库迁移:创建 000034_remove_tier_commission 移除相关表和字段
- 更新测试:移除梯度返佣相关测试用例,更新集成测试
- OpenAPI 文档:删除梯度返佣相关 schema 和枚举值
- 归档变更:归档 remove-tier-commission-redundancy 到 archive/2026-01-30-
- 同步规范:更新 4 个主 specs,标记废弃功能并添加迁移指引

原因:梯度返佣功能与一次性梯度佣金功能重复,且从未实现实际计算逻辑
迁移:使用一次性佣金的梯度模式 (OneTimeCommissionConfig.type = "tiered") 替代
2026-01-30 14:57:24 +08:00
409a68d60b feat: OpenAPI 契约对齐与框架优化
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m45s
主要变更:
1. OpenAPI 文档契约对齐
   - 统一错误响应字段名为 msg(非 message)
   - 规范 envelope 响应结构(code, msg, data, timestamp)
   - 个人客户路由纳入文档体系(使用 Register 机制)
   - 新增 BuildDocHandlers() 统一管理 handler 构造
   - 确保文档生成的幂等性

2. Service 层错误处理统一
   - 全面替换 fmt.Errorf 为 errors.New/Wrap
   - 统一错误码使用规范
   - Handler 层参数校验不泄露底层细节
   - 新增错误码验证集成测试

3. 代码质量提升
   - 删除未使用的 Task handler 和路由
   - 新增代码规范检查脚本(check-service-errors.sh)
   - 新增注释路径一致性检查(check-comment-paths.sh)
   - 更新 API 文档生成指南

4. OpenSpec 归档
   - 归档 openapi-contract-alignment 变更(63 tasks)
   - 归档 service-error-unify-core 变更
   - 归档 service-error-unify-support 变更
   - 归档 code-cleanup-docs-update 变更
   - 归档 handler-validation-security 变更
   - 同步 delta specs 到主规范文件

影响范围:
- pkg/openapi: 新增 handlers.go,优化 generator.go
- internal/service/*: 48 个 service 文件错误处理统一
- internal/handler/admin: 优化参数校验错误提示
- internal/routes: 个人客户路由改造,删除 task 路由
- scripts: 新增 3 个代码检查脚本
- docs: 更新 OpenAPI 文档(15750+ 行)
- openspec/specs: 同步 3 个主规范文件

破坏性变更:无
向后兼容:是
2026-01-30 11:40:36 +08:00
1290160728 fix: 修复订单支付幂等性问题,防止重复激活套餐
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m22s
- 使用条件更新实现支付状态原子转换(pending -> paid)
- 重复请求返回幂等成功,不再重复激活套餐
- 新增 tb_package_usage 唯一索引(order_id, package_id)
- 新增幂等性和异常状态测试,测试覆盖率 71.7%
- 归档 OpenSpec 变更 fix-order-activation-idempotency
2026-01-29 16:33:53 +08:00