wangwangit
|
df5ee5b241
|
fix: 修复编辑订阅不生成支付记录及测试通知不写入历史的问题
- updateSubscription: 当订阅有金额但缺少 initial 支付记录时自动补建
- testSingleSubscriptionNotification: 传递 env/subId 使通知日志正常写入
- .gitignore: 排除 AI 工具目录和环境变量文件
|
2026-05-27 20:35:18 +08:00 |
|
wangwangit
|
a25c817c8f
|
feat(api): 新增版本号端点 + 分类管理 + 下次提醒时间 API
- GET /api/version 返回当前版本号 (3.0.0)
- GET/POST /api/categories 管理分类列表
- GET /api/subscriptions/:id/next-reminder 返回下次提醒时间
- Issue #168 #170 #171
|
2026-05-26 23:25:34 +08:00 |
|
wangwangit
|
6e1b506c8a
|
polish: 默认时区 Asia/Shanghai + 清理代码与文档中的版本号字眼
时区默认值:
- DEFAULT_CONFIG.TIMEZONE: 'UTC' → 'Asia/Shanghai'
- 配置页时区下拉用 <optgroup> 把中国标准时间钉到"🇨🇳 推荐"分组
- 未知时区 fallback 也改 Asia/Shanghai
去除版本号字眼(45 文件):
- 全部 "维护人:v3 重构 (2026-05)" 文件头注释删除
- 文件描述里的 "(v3 重写)" "(v3 新增)" 等去掉
- @deprecated v2 兼容 → @deprecated 旧版兼容函数
- 注释里的 "v2/v3" 替换为中性表述("早期版本""旧调度器""既有客户端"等)
- src/api/handlers/v3-routes.js → src/api/handlers/extras.js
- tests/api/v3-routes.test.js → tests/api/extras-routes.test.js
- 函数名 handleV3Routes → handleExtraRoutes
- README / MIGRATION / ARCHITECTURE 整体重写:
- README 去掉 "v3 关键改进里程碑" 段,改写为标准产品功能介绍
- MIGRATION 重写为通用"升级指南",用"旧版本"代替 v2
- ARCHITECTURE 模块图与流程描述去掉所有 v3 标签
- package.json description 去掉 v3
- wrangler.toml / wrangler.dev.toml 注释里 v3 去掉
故意保留的(持久化的 KV 数据兼容性标识):
- schema_version 字符串值 'v3'
- migrate:subscriptions_v3 / reminder_rules_v3 / scheduler_logs_v3 step ID
- subscriptions_v2_backup KV key
- 文档对这些标识有显式说明:"是 KV 内部数据兼容性标记,与产品版本号无关"
171 测试全绿;lint 干净;wrangler dry-run 571 KiB / gzip 119 KiB。
|
2026-05-24 20:04:16 +08:00 |
|
wangwangit
|
868263a1c7
|
fix: 货币显示一致性 + 仪表盘读新调度日志(Task 12)
修复 #160:v2 在 4 个文件里重复定义 currencySymbols;JPY 与 CNY 同
符号 ¥ 易混淆。
- 新建 src/core/currency-format.js:CURRENCY_SYMBOLS 单一来源 +
formatAmount(amount, currency) helper,JPY 改前缀为 'JP¥' 区分
- src/services/notify/reminder.js 与 src/api/handlers/subscriptions.js
改用 formatAmount,删除两份重复定义
仪表盘 (#149):
- src/api/handlers/dashboard.js 重写,scheduler_status / status_history
改从 scheduler-logs.repo.getRecent(10) 取
- 兼容老前端字段(lastRunAt / shouldNotifyThisHour 等)做扁平转换
- 时区从 config.TIMEZONE 读取(不再硬编码 UTC)
- 响应增加顶层 timezone 字段
170 测试全绿;wrangler dry-run 560 KiB / gzip 118 KiB。
Refs Task 12 of refactor/v3-product-grade plan.
|
2026-05-24 18:31:05 +08:00 |
|
wangwangit
|
8518045408
|
feat(ui): 通知历史页 + 时区感知配置页(Task 11)
新增 src/views/notifyLogsPage.html:
- /admin/notify-logs 路由(admin.js 登记)
- 顶部筛选:subId / channel / status / 最近 N 小时
- 概览卡片:总记录 / 成功 / 失败 / 最近发送
- 调度执行预览(最近 10 次 sched_log,可折叠)
- 主表格:时间(用户 TZ)/ 订阅名 / 规则 ID / 渠道 / 状态徽章 / 详情展开
- 失败行红底,成功行绿底;详情含 raw 响应与通知正文展开
src/views/configPage.html:
- 通知时段标签从"(UTC)"改为"(按你的时区)",动态显示具体 TZ 名
- 改原灰色提示为黄色"v3 时区语义变更"提示,明确升级行为
- 新增实时预览 div:显示当前用户 TZ 的小时/分钟、是否在通知时段
- TZ select / hours input 的 change/input 事件即时刷新,30s 兜底重算
src/views/{adminPage,dashboardPage,configPage}.html:
顶部导航与移动菜单加 "通知历史" 链接(fa-history 图标)
src/views/pages.js + src/api/admin.js:
注册 notifyLogsPage 模板 + 路由 /admin/notify-logs
170 测试全绿;wrangler dry-run 559 KiB / gzip 117 KiB。
Refs Task 11 of refactor/v3-product-grade plan.
|
2026-05-24 18:28:48 +08:00 |
|
wangwangit
|
3397d34c15
|
feat(ui): 订阅表单加入多提醒规则编辑器(Task 10)
adminPage.html:
- 替换原"提醒提前量"单行输入为"提醒规则"区块
- 顶部按钮:[应用预设(7/3/1/0)] [添加规则]
- 每行:启用复选框、类型(到期前/到期当天/到期后)、数值、单位(天/小时)
- after_expiry 类型展开:每 N 小时重复,直到 [续费/手动确认/不停止]
- 隐藏原 reminderUnit/reminderValue 作为 v2 兜底字段保留
- validateForm 不再强制 reminderValue(已隐藏)
JS 模块(位于 </script> 之前):
- ReminderRulesEditor (setRules / setPresets / getRules / clear)
- 新增订阅 → 自动渲染 4 条预设
- 编辑订阅 → 轮询监听 subscriptionId 字段变化,拉取 /api/.../reminders 渲染
- 全局 fetch 劫持:POST/PUT 订阅时自动附加 reminderRules 到 body
- 编辑模式 (PUT) 完成后调用 PUT /api/subscriptions/:id/reminders 同步替换规则
后端:
- v3-routes.js 新增 PUT /api/subscriptions/:id/reminders 整体替换接口
170 条测试全绿;wrangler dry-run 540 KiB / gzip 113 KiB。
Refs Task 10 of refactor/v3-product-grade plan.
|
2026-05-24 18:24:17 +08:00 |
|
wangwangit
|
b6ab5ed944
|
feat(api): 提醒规则 / 通知日志 / 调度日志新 API + 创建订阅联动
src/api/handlers/v3-routes.js(新):
GET /api/subscriptions/:id/reminders 列表
POST /api/subscriptions/:id/reminders 新增(body 传 preset:true 一键应用预设)
PUT /api/subscriptions/:id/reminders/:ruleId 更新
DELETE /api/subscriptions/:id/reminders/:ruleId 删除
GET /api/notification-logs?subId=&channel=&status=&since=&until=&limit=
GET /api/scheduler-logs?limit=N
挂载点:在 router.js 鉴权之后、subscriptions handler 之前匹配。
按 v2 错误结构返回 { success, message };405/404/400 状态码与 v2 一致。
POST /api/subscriptions 扩展:
- 不传 reminderRules → 自动应用 4 条智能预设(7/3/1/0 天)
- 传入数组 → 按数组替换(每条经 normalizeRule 校验)
- 写入失败不影响订阅本体创建,错误打 console.error
测试 tests/api/v3-routes.test.js 12 条覆盖:
- 4 类 reminder CRUD(含 preset=true / 不存在 → 404)
- notification-logs 过滤 subId / status
- scheduler-logs 列表
- 创建订阅自动写预设 vs 自定义规则
- 鉴权失败路径
总计 170 条测试全绿;lint 干净;wrangler dry-run 484 KiB。
Refs Task 8 of refactor/v3-product-grade plan.
|
2026-05-24 18:16:22 +08:00 |
|
wangwangit
|
b9de410f6f
|
feat(observability): 三类可观测性仓库 + 迁移扩展
新增三个 KV 仓库(v3 通知/调度可观测性数据底座):
1. src/data/reminders.repo.js
- reminder_rules:{subId} 数组,支持 CRUD + 智能预设(4 条:到期前 7/3/1/当天)
- legacyFieldToRule 把 v2 的 reminderUnit/reminderValue 单点提醒
转成 1 条等价 before_expiry 规则
- normalizeRule 修复非法字段,repeatInterval 仅 after_expiry 类型保留
2. src/data/notification-logs.repo.js
- notify_log:{ymdh}:{subId}:{ruleId}:{channel}:{rand}, TTL 30 天
- writeLog / query(subId/channel/status/since/until/limit 过滤)
- 时间倒序,KV.list 拉全后排序
3. src/data/scheduler-logs.repo.js
- sched_log:{isoUtc}, TTL 30 天
- writeLog / getRecent(按时间倒序)
迁移扩展:MIGRATION_STEPS 追加两个 step
- reminder_rules_v3:为现有订阅生成默认提醒规则
- scheduler_logs_v3:v2 的 scheduler_status_history 转换到新表
调试页新增链接:/debug?export=sched_logs&limit=50 直接下载 JSON
测试:
- tests/data/reminders.test.js (13)
- tests/data/notification-logs.test.js (8)
- tests/data/scheduler-logs.test.js (4)
- 共 85 条测试全绿;lint 干净
Refs Task 4 of refactor/v3-product-grade plan.
|
2026-05-24 18:03:01 +08:00 |
|
wangwangit
|
f6bce4b7b3
|
refactor(time): 重写时区核心模块为单一真相源
修复 #91 / #52 / #166 类时区相关问题的根因:旧 getCurrentTimeInTimezone
只返回 new Date(),被调用方误以为是"用户本地时间对象"。
变化点:
- 新增 getNowInTimezone(tz, now?) 返回 {utc, parts, hourString, isoLocal}
强制业务代码显式选择需要 UTC 时刻还是用户 TZ 字段
- 新增 getTimezoneHourString(date, tz) 调度器通知时段判断专用
- 新增 getDaysBetween(from, to, tz) 基于用户 TZ 各自零点的整天数差,
修复"凌晨 0–8 点创建订阅默认日期变前一天"的 #166
- formatLocalDate 替代 formatTimeInTimezone(保留旧名作 alias)
- 旧 API(getCurrentTimeInTimezone / convertUTCToTimezone)保留为兼容
wrapper,加显眼注释说明其语义陷阱
- 全文 JSDoc 标注 + 中文用途说明,启用 // @ts-check
- 40 条单测覆盖:UTC/北京/纽约 DST、跨日界、#166 边界、非法时区兜底
附带:/debug 页新增"时区诊断"区块,直观展示 UTC vs 用户 TZ 当前小时、
通知时段是否命中——这是用户自助排查"为什么没收到通知"的入口
Refs Task 2 of refactor/v3-product-grade plan.
|
2026-05-24 17:53:29 +08:00 |
|
wangwangit
|
e2fc130f99
|
fix: XSS 风险修复
- showToast 改用 textContent 设置消息内容,防止 HTML 注入
- createHoverText 对所有用户输入进行 escapeHtml 转义
- 续订/支付历史/编辑支付模态框中的 subscription.name 和
payment.note 使用 escapeHtml 转义
- debug 页面 adminUsername 转义
- 添加全局 escapeHtml 工具函数
|
2026-05-19 12:06:21 +08:00 |
|
wangwangit
|
d36f8b94fe
|
feat: 登录暴力破解防护 + Cookie Secure 标志
- 基于 IP 的登录失败计数(KV TTL 自动过期)
- 连续 5 次失败后锁定 5 分钟
- 失败时提示剩余尝试次数
- 登录成功后清除失败计数
- 添加 request.json() 的 try-catch 防止解析错误
- Cookie 添加 Secure 标志(login + logout)
|
2026-05-19 11:57:53 +08:00 |
|
wangwangit001
|
5214f76c55
|
fix: preserve zero amount and payment currency
|
2026-04-24 11:14:32 +08:00 |
|
wangwangit001
|
cc97cc97c9
|
feat: add serverchan and pushplus notifiers
|
2026-04-23 12:04:44 +08:00 |
|
wangwangit
|
805a47e417
|
fix(security/ui): do not expose secrets; show configured flags + explicit clear
|
2026-03-05 19:40:47 +08:00 |
|
wangwangit
|
4f4fc5af1f
|
feat(notify): add gotify notifier + config UI
|
2026-03-05 15:29:53 +08:00 |
|
wangwangit
|
a095213162
|
fix(security): mask config secrets, protect /debug, use crypto RNG
|
2026-03-05 15:05:34 +08:00 |
|
wangwangit
|
bd5b5227c4
|
release: v2 modular refactor and docs cleanup
|
2026-02-27 15:29:43 +08:00 |
|