gouki
|
6efb048b0b
|
test: 新增 sync_service 核心同步流程测试(正常入库/去重/异常容错)
|
2026-10-14 12:48:14 +00:00 |
|
gouki
|
e6bbfdfdc7
|
fix(deploy): 解除更新链路死锁——失败标记改为冷却窗口而非永久拒绝
FAILED_STATE 语义原为「永久拒绝该远端提交」,但闸门失败可能源于环境问题
而非代码问题(venv 缺 pytest、systemd PATH 缺 nvm)。此时修复手段是修环境,
远端 hash 并未变化,于是形成自锁:
旧脚本写入标记 → 修好环境后的新脚本因 hash 未变被跳过 → 标记永不失效
cc1 实测已因此冻结:dd192bac 被拦(纯文档提交),随后 e9cc95c 修 update.sh
的提交本身也被同一个错误判定写入标记,每分钟只打印「跳过重复部署」,
只能人工 ssh 删除标记才能恢复。
改为带时间戳的冷却窗口(DEPLOY_COOLDOWN,默认 6h):
- 标记内容由裸 hash 变为 "<commit> <epoch> <单行原因>"
- 到期自动重试,兼得防抖(不反复抖动/告警轰炸)与自愈(修完环境自动恢复)
- 识别旧格式(无时间戳)即清理并放行,不让旧死锁残留
- 日志输出真实失败原因与「立即重试」命令,不再一律宣称「健康检查失败」
此前同批修复的另外两处(随 e9cc95c 一并上线):
- 测试闸门区分「pytest 未安装」与「测试失败」,前者跳过而非拦截
- JS 闸门 node 探测增加 ~/.nvm/versions/node/*/bin 回退
验证:bash -n 通过;冷却逻辑 10 项分支测试全通过;pytest 334 passed
|
2026-10-14 12:17:29 +00:00 |
|
gouki
|
e9cc95c509
|
fix(deploy): 测试闸门区分 pytest 缺失与测试失败,node 探测补 nvm 回退
cc1 的 venv 只装 requirements.txt、未装 pytest,闸门把
'No module named pytest' 当成测试失败,拦截了正常的文档提交 dd192ba
并写入 FAILED_STATE,导致更新链路自此永久冻结在 87e144e。
- pytest 不可用时降级为跳过,与 JS 闸门缺 node 的处理保持一致,
闸门只对真正的测试失败生效
- node 探测增加 ~/.nvm/versions/node/*/bin/node 回退:systemd PATH
不含 nvm,此前每轮都打印「未找到 node」而静默跳过 JS 闸门
|
2026-10-14 12:09:07 +00:00 |
|
gouki
|
dd192bac20
|
docs(rules): 云厂商适配层补充 AI 余额同步要求
新增 AI 适配器时须在对应 adapter 实现余额查询方法,
sync_ai_balances.py 通过 sync_all_ai_balances() 自动遍历同步。
|
2026-10-14 08:32:09 +00:00 |
|
gouki
|
0d28c155e8
|
docs(rules): 云厂商适配层补充 AI 适配器同步要求
新增 AI 适配器时须同步在 seed.py PRESET_PROVIDERS 添加平台记录,
前端 AI 平台选择器从数据库 Provider 动态渲染,无硬编码列表。
|
2026-10-14 08:31:43 +00:00 |
|
gouki
|
87e144e022
|
feat(deploy): update.sh 健康闸门增加核心 API 探测,失败触发回滚
在 wait_health commit 追平通过后、清除 FAILED_STATE 之前,新增
check_core_apis 函数探测 4 个核心端点(/api/assets、/api/accounts、
/api/providers、/api/stats/overview),复用 deploy.sh 的端点列表与
判定标准(curl -w %{http_code},非 200 视为验收失败)。
API 探测失败时走现有完整回滚路径:git reset --hard $LOCAL +
systemctl restart + 二次 wait_health + 写 FAILED_STATE + 告警。
告警消息新增「失败原因」字段区分健康检查与 API 探测失败。
|
2026-10-14 08:31:10 +00:00 |
|
gouki
|
b0b91e4956
|
docs(rules): 云厂商适配层清单同步至 registry.py,指定其为唯一事实源
补全 AWS / Linode / NameSilo / AI 适配器组(DeepSeek / Moonshot / OpenAI / MiniMax),
声明以 app/adapters/registry.py 的 @register 注册项为唯一事实源,防止文档再次漂移。
|
2026-10-14 08:31:05 +00:00 |
|
gouki
|
158679be3c
|
feat(deploy): update.sh 增加部署后健康闸门与自动回滚
restart 后轮询 /health 直到 commit 追平新 HEAD 且 status=ok,参数对齐
deploy-verification.md(间隔 15s / 单次 10s / 总超时 120s,可用 DEPLOY_HEALTH_* 覆盖)。
超时或 status≠ok 时 git reset --hard 回滚到 reset 前记录的 HEAD 并再次 restart,
经 .env 已配置渠道(Telegram/邮件)告警,并以 exit 1 结束让 systemd 记录失败。
- 期望哈希用 git rev-parse --short HEAD,与 app.main._read_git_commit 口径一致,避免长度不符误回滚
- 失败提交记入 .git/vps-manager-deploy-failed,阻止 timer 每分钟重复部署同一坏版本(抖动+告警轰炸)
- fetch_health 无 curl 时回退 Python urllib,避免取数工具缺失导致误判超时回滚好版本
- timer 触发方式与 sync_units 单元同步逻辑保持不变
|
2026-10-12 21:45:52 +00:00 |
|
gouki
|
7eccb87c6d
|
fix(deps): 封顶 sqlmodel<0.0.45 避免全新安装拉到不兼容版本
sqlmodel 0.0.45 起 UTCDateTime 强制要求带时区 datetime,与本项目 naive-UTC 存储设计(app/core/timeutils.py)冲突,全新 venv 首个写库即 ValueError(测试红;生产 setup.sh 全新部署同样会崩)。二分定位断点:0.0.44 绿、0.0.45 红。封顶后干净 venv 全量 334 passed。对现有 .venv(0.0.39)为 no-op。
|
2026-10-12 21:41:30 +00:00 |
|
gouki
|
6edafc9345
|
chore(ide): 将 .qoder 指令层纳入版本控制
工作区根 own/vps 不是 git 仓库,.qoder/rules 与 .qoder/agents 长期无版本化、无异地备份。
现将两类手写指令资产实体迁入本仓库 .qoder/ 下,工作区根原路径改为相对符号链接指回仓库,
IDE 加载路径与规则 glob(vps-manager/**/*.py)保持不变。
.gitignore 仅跟踪 .qoder/rules 与 .qoder/agents,repowiki、better-harness 报告等可重生成产物不入库。
|
2026-10-12 21:39:54 +00:00 |
|
gouki
|
dd79d24b2b
|
fix(run.sh): venv 初始化追加安装 requirements-dev.txt
本地/手动启动入口 run.sh 在创建 .venv 时一并装 pytest,使 .qoder/rules 里的 .venv/bin/python -m pytest 开箱即用、测试环境可复现。生产由 systemd 直接拉起 uvicorn,setup.sh/update.sh 仍只装 requirements.txt,dev 依赖不会带上线。
|
2026-10-12 21:31:25 +00:00 |
|
gouki
|
ca2b49952a
|
test: 补齐 asset_service CRUD 与 API 装配层 fail-closed 测试
- tests/test_asset_service.py:以模块名直接调用 asset_service,覆盖 create/get/
update/delete 正常路径与失败分支(缺详情 400、账号悬空 400、不存在 404)、
删除的详情+子表联动清理与 metrics 清理失败容错、VPS 凭证加密入库、list 筛选/
搜索/排序白名单兜底、get_expiring 到期口径
- tests/test_api_assembly.py:首次用 TestClient 挂载 app.main:app,以 RFC5737 公网
来源验证 API_KEY/AGENT_KEY 未配置或错误时 401(fail-closed)、正确时放行
(/api/assets 201、/api/agent/report 进入业务校验 404)
- 复用 conftest sys.path 约定与 tmp_path+create_engine 临时库;依赖覆盖到临时库、
不触发 lifespan,免凭证、免网络
334 passed(新增 25)
|
2026-10-12 21:31:22 +00:00 |
|
gouki
|
46faadbcae
|
feat(multicloud): 补齐上线前的多云管理缺口(适配器/动作层/DNS/定时同步)
评估发现项目只有台账能力,缺失真正的多云管理链路。本次按缺口逐项补齐:
适配层
- 新增 aws / linode / namesilo 适配器,registry 登记;阿里云、腾讯云补
list_domains 与 get_account 余额
- NormalizedVPS 补 expiry_date + charge_type:此前云端同步进来的 VPS 拿不到
到期日,永远进不了续费提醒——而续费提醒正是这套台账存在的理由
- base.py 统一云端错误可读化(http_error_message / cloud_error_text):各厂商
把原因放的位置都不同(Linode errors[].reason、Cloudflare errors[].message、
腾讯 Response.Error.Message、AWS XML),此前直接 str(e) 会把 httpx 的多行文本
连同 MDN 链接弹给用户
动作层与 DNS
- 新增 /api/actions:实例启停/重启/续费,写操作全部二次确认 + 审计
- 新增 Cloudflare DNS 记录的增删改查
定时同步
- scripts/sync_all_assets.py + /api/sync/assets + vps-sync-assets.timer(08:30)
- 08:30 而非随机时刻:必须早于 09:00 的续费检查,否则提醒读到上一天的旧到期日
- sync_all_assets 修正计数:每一项子同步都失败时不再计为「成功」,否则凭证过期
会显示「成功 1」,用户以为数据拉到了、实际一条没有
数据一致性
- AssetRead 输出 external_id(只出不进):前端「云操作」「DNS」按钮靠它渲染,
缺了则所有按钮永远出不来
- import_assets 落库 external_id:导出带了去重键而导入丢弃,会让迁移后首次同步
把所有云端资产当新增再建一份
- _align_preset_providers 取代 _backfill_provider_services:库里声明但注册表未
实现的 sdk_type 清空(声明支持却不支持,比明说不支持更糟),services 只增量
补标签不覆盖,用户自建平台不动
前端如实展示
- cost 为 0 统一显示「未填」而非「0 USD」:0 既可能是没填、也可能是云端不返回
价格,而汇总处又把 0 当「无费用」排除,两处口径不一致
- 总览「本年支出」增加 year_cost_missing,把合计的覆盖缺口说出来
- DNS 弹窗补 MX/SRV 优先级与备注;列表请求失败时 provider 用资产自带 slug 兜底,
否则 Cloudflare 代理勾选框永远不出现
测试:257 -> 309 passed
|
2026-10-12 00:43:37 +00:00 |
|
gouki
|
192d448a28
|
docs: 补充 vultr 适配器功能说明注释
|
2026-09-27 23:14:42 +00:00 |
|
gouki
|
c2696132fb
|
docs: 补充版本号文件说明到 main.py 模块注释
|
2026-09-27 23:00:00 +00:00 |
|
gouki
|
f09c0f6e4b
|
fix(review): 处理全量审查剩余项(M4-M8/M11/M12 + 21 条 low)
后端
- asset_service: delete_asset 先清 subdomains/site_certs 子表(SQLite 不强制
FK 且 assets.id 无 AUTOINCREMENT,删最大 id 后新建会复用 rowid 导致孤儿误挂);
metrics.db 清理改 best-effort,不再让已成功的删除返回 500
- provider_service: slug 唯一约束竞态补 IntegrityError 兜底(与 account_service 一致)
- account_service/sync_service: raise HTTPException 补 from e,保留原始异常链
- sync_service: 删死代码 _load_config;新增 BalanceUnsupported,平台无余额接口时
计入 skipped 而不是静默当作失败;到期日写库前归一
- ai: 删掉 OpenAI 早已下线的 billing 余额接口实现,能力探测如实报「不支持」
- adapters/base: _overridden 改走 MRO,中间层基类实现的能力不再被误判为未实现
- core/timeutils: 删死代码 utcnow_iso(注释声称 Z 后缀,实际输出 +00:00)
- main: lifespan 退出时 await 被 cancel 的清理任务,避免 pending task 被销毁
- ssl_service: 写 site_certs/subdomains 前校验 asset_id 存在,杜绝悬空引用;
到期阈值贯穿 _judge_status/_apply_probe/check_one/check_all_site_certs
- routers/credentials、accounts: 明文密码 GET 补 Cache-Control: no-store
- routers/stats: /stats/expiring 的 Query 描述与实际语义对齐(不设下界,含已过期)
Agent
- collector: 解析 sshd_config 的 Include(含 sshd_config.d/*.conf,按 sshd 语义
「首次出现的值生效」),未显式配置的关键字按编译默认值判定,消除假 pass;
防火墙检测改用 iptables -S 统计 -A 规则行并读 INPUT 策略(-L -n 恒有链头输出)
- reporter: 4xx(除 429)不再重试直接退出,429 优先按 Retry-After 退避
安全与部署
- core/security: require_agent_key 改为对外 fail-closed——tailnet/本机放行,
外部来源未配 AGENT_KEY 时一律 401(此前全放行,而服务默认监听 0.0.0.0,
公网上任何人可伪造监控指标与安全检查结果)
- main: 启动时把「未配 API_KEY/AGENT_KEY 则外部来源不可用」打进日志
- run.sh: HOST/PORT 可用环境变量覆盖,并说明默认 0.0.0.0 的权衡
- deploy/setup.sh: 新装时自动生成随机 API_KEY/AGENT_KEY 并提示同步到各 VPS;
注册 vps-cert-check.timer
- deploy/vps-cert-check.{service,timer}: 新增每日 09:30 的站点证书到期探测
(此前 check_site_certs.py 没有任何 unit,证书提醒不会自动跑)
- deploy/update.sh: sync_units 对 timer 用 enable --now(新增 timer 只 restart
不会建开机自启软链),主服务 unit 变更后额外 restart;pip 安装失败不再被吞
- scripts/check_site_certs.py: threshold 参数真正生效并打印
- scripts/make_migration_bundle.py: 缺 assets.db 直接 abort;umask 077 + chmod 600
(包内含 .env 的 MASTER_KEY 与 escrow,不能默认 644 落在 /tmp)
- scripts/restore_migration_bundle.py: 校验之外补必备文件预检,缺文件在触碰
目标机状态之前就 abort
前端
- store: 拆分列表口径 assets 与统计口径 allAssets(无筛选时同源,不重复请求);
删除已无消费者的 expiring/loadExpiring(每次 loadAll 白发一个请求)
- dashboard/monitor/providers/subscriptions/modals: 统计与计数改用 allAssets,
资产页的筛选(含统计卡片点击跳转带的筛选)不再让其他视图的数字缩水
- modals: 账号同步后补 loadOverview;settings: 导入后改 loadAll
- api: countdownText 支持 unit/empty 选项,monitor/domains 各自的实现改为委托,
assets/domains/subscriptions 的到期列不再直出「(-3天)」
- servers: cpu/mem/disk 百分比统一判空,采样缺项不再渲染「null%」
- assets: 同步 AI 余额的结果提示区分 skipped(平台无余额接口)与 failed
- modals: 修正凭据库头注释——2FA 动态码是选填 + 可事后补验,与实现一致
测试
- 新增 tests/test_agent_collector.py(8 条)、tests/test_security.py(11 条)
- 全量 113 passed;改动 JS 均通过 node --check,deploy 脚本通过 bash -n
- 浏览器实测:筛选态下总览/监控中心/平台页/付费资产的统计仍为全量口径,
到期文案与 null 百分比渲染正确,console 零报错
|
2026-09-23 10:15:52 +00:00 |
|
gouki
|
61372f7ceb
|
fix(review): 修复全量审查发现的域名到期日链路、AI 资产挂靠迁移与 2FA 取码缺陷
92 文件全量代码审查后的高危/中危修复,每条都带回归测试,并在未修复的 HEAD 上
反向确认过「测试确实会失败」。
- H1 域名同步整批失败:NormalizedDomain.expiry_date 契约声明为字符串,Cloudflare
适配器把 Registrar 的 ISO 时间戳截成 "YYYY-MM-DD" 直接赋给 Date 列,写库抛
TypeError;而 _sync_domains 的 commit 在循环外,一个域名就让整批全量回滚
(Cloudflare 域名实际从未同步成功)。现统一契约:base.py 新增 parse_iso_date,
适配器产出 date,_sync_domains 写库前再归一一次以兼容仍返回字符串的适配器
- M9 Vultr / DigitalOcean 的域名到期日此前完全没映射,这两家域名永远进不了续费提醒
- M1 同步失败变 500:能力分支写库失败后未回滚,Session 停在 pending-rollback,
随后更新 last_synced_at 的 commit 抛 PendingRollbackError,真实错误被 500 掩盖
- H2 AI 资产挂靠迁移静默零命中:迁移 SQL 用枚举值 'ai_agent' 匹配 Enum 列,而
SQLAlchemy Enum 存的是成员名 'AI_AGENT',该分支从未生效(6 个 AI 资产的
account_id 全为 NULL)。改用成员名并加日志留痕;账号命名沿用步骤 1 的
「{slug}-默认」约定,避免建出与既有账号语义重复、且没有凭证的空账号
(dry-run 实测:deepseek 资产复用已有且有凭证的 deepseek-默认)
- H3 2FA 动态码不刷新:otpState 全局常驻、收起只清 timer 不删条目,「不存在才拉」
的守卫导致再次展开显示上一次的旧码且倒计时冻结在 0。改为每次展开都重取;
stopOtp 同时清空旧码(避免重展开瞬间闪过已失效的码),并加请求代号,防止
「请求在途时收起」后返回的响应又重启轮询
- M10 账号弹窗关闭不清理:外层用 v-if 关闭并不卸载组件,onUnmounted 不触发,
OTP 轮询定时器与明文密码驻留后台。关闭时显式调 closePwd
- M2 提醒发不出去:Telegram 用 parse_mode=HTML,资产名含 < > & 时整条消息被 400
拒收;纯文本提醒不需要任何标签,去掉 parse_mode,并把拒收正文带回便于排查
- M3 负数天文案:cbb32ea 已修好提醒消息正文,本次补齐仍在直出负数的两处
(check_renewals.py 输出、设置页预览),后端抽出 renewal_service.day_text 统一,
前端走 Fmt.countdownText
验证:pytest 94 passed(新增 tests/test_domain_expiry.py、tests/test_notification.py);
本地起服务对 H2 迁移做真实 dry-run(6 个 AI 资产挂到 4 个账号、无重复账号、幂等、
非 AI 资产零影响,迁移前已备份);浏览器端以 otpState 状态断言验证 H3/M10,
设置页续费预览确认已过期项显示「已过期 N 天」。
|
2026-09-22 22:26:42 +00:00 |
|
gouki
|
7045843db8
|
feat(ui): 总览/监控中心顶部统计卡片支持点击筛选
- 总览页「总资产」「本年支出」「异常状态」卡片点击跳转资产页并带上对应筛选
(全部/付费资产TAB/异常状态组合筛选);「30天内到期」及「另有N项已过期」
子文案点击跳转监控中心并带上到期区间子筛选
- 监控中心顶部统计卡片(30天/7天/已过期/有到期日)支持点击筛选下方列表,
再点一次取消;SSL 证书卡片(正常/即将到期/已过期或失败)同理
- 资产页状态筛选新增「异常(已停止/已过期)」组合选项:后端 status 只认单值,
该组合作为前端本地筛选哨兵值处理,不发给 API;切到专有视图 TAB 时自动清空
- 顺带修复监控中心统计卡片数字不随类别 TAB 变化的问题(原先 stats 未按 TAB
过滤,与列表数据口径不一致)
|
2026-09-20 12:53:48 +00:00 |
|
gouki
|
cbb32ea3b0
|
fix(expiry): 已过期资产不再从到期统计中消失,总览页改为到期日历
get_expiring/get_overview 去掉 expiry_date>=today 下界(仅排除已注销)并新增 overdue_count;renewal_service 续费提醒纳入已过期、文案区分已过期N天/今天到期/N天后;dashboard 用到期日历逐条显示具体到期日与倒计时;api.js 新增 Fmt.countdownText 统一文案。
|
2026-09-18 08:41:21 +00:00 |
|
gouki
|
c5982a5706
|
feat(2fa): 动态码改为可选校验,未验证条目支持就地补验
痛点:secret 多为历史留存,录入那一刻手上常常没有能出码的验证器,
原先「绑定必须 secret + 当前 6 位码校验通过」直接把用户挡在门外。
改为「能验则验,没验就标」,抄错风险由角标持续提醒 + 后置补验兜住。
- 后端:新增 otp_verified_at 记账;code 可选(填了必须通过,错码 400
且不覆盖已绑 secret);POST /{id}/otp/verify 补验转正;更换 secret
一律重置为未验证;_migrate_assets_db 幂等补列并回填旧数据,避免升级
后全量误报未验证
- 前端:列表区分「2FA 已验证/未验证」徽章,展开区未验证提醒条 + 就地
补验输入;账号查看密码弹窗增加未验证提示;移除 CredentialModal.save()
里的必填预校验(这是留空保存连请求都不发出的根因)
- 测试:pytest 74 绿(新增契约反转 + 6 个补验用例 + 迁移回填用例);
Playwright 端到端 13/13(留空保存 → 未验证角标 → 错码 400 保持未验证
→ 正码补验转正 → 移动端 375px 无横向溢出 → 无 JS 运行时报错)
- 文档:goal-spec §1/§2/§4/§5/§6/§7/§9 同步新决策,替换旧的必填校验约定
|
2026-09-18 08:40:09 +00:00 |
|
gouki
|
49c4dc9af5
|
feat(vault): 授权来源候选扩至 37 项并支持手填自动记入
问题:凭据表单的「授权来源」只有 6 项 datalist 建议,缺国内常见的支付宝/淘宝/
微博等三方登录,且移动端 iOS Safari 对 datalist 支持不稳,导致没法填。
- api.js: OAUTH_PROVIDERS(6) → OAUTH_PRESETS(37,按国内/国际/开发者分组,
key 为入库值、label 为展示名);新增 oauthLabel/oauthDetail 展示中文名,
normalizeOauth 把中文输入归一化成英文 slug,避免同一来源存成多种写法
- modals.js: 授权来源改为「输入框 + 分组芯片」选择器,随输入过滤(中英文均可
搜)、可一键清空、误填项可划掉;无匹配时提示将按原样保存
- store.js: 手填的非预设值记入 localStorage 候选,并在拉取凭据列表后与服务端
值对账,换设备也能看到以前填过的来源;被划掉的记入 ignore 不再冒回
- credential_service.py: 凭据库搜索纳入 oauth_provider
|
2026-09-10 09:27:52 +00:00 |
|
gouki
|
cc8c91ddd9
|
feat(migration): 换宿主平台迁移能力(打包/恢复脚本 + runbook)
make_migration_bundle:sqlite backup API 在线快照(无需停服)打包 data/(两库+escrow+backups)与 .env,含逐文件 sha256 清单与版本/commit 元信息。restore_migration_bundle:sha256 逐文件校验(篡改即拒绝)、目标机原状态留 pre-restore 备份、兼容旧版 Python 的 tar 解包路径校验,并打印 serve/agent/CORS/源机下线等手工步骤。docs/migration-runbook.md:迁移面清单、可选预处理(agent 去 IP 化)、七步迁移、十项验收、回滚与灾难恢复。本地隔离演练验证:密码解密一致、2FA 出码可用、escrow+RESTORE_KEY 可解回 MASTER_KEY、篡改包被拦截。
|
2026-09-05 23:20:45 +00:00 |
|
gouki
|
6865bb7914
|
fix(backup): 备份链路纳入 master_key.escrow(覆盖式单份+S3)
escrow 是 MASTER_KEY 遗失恢复链的一环:整机丢失时仅有库备份+离线 RESTORE_KEY 仍无法恢复,缺的正是托管档。随 assets 周期备份,固定文件名覆盖(多版本无意义),未建立托管时 skip。
|
2026-09-05 23:10:46 +00:00 |
|
gouki
|
d711ad5827
|
feat(vault): 凭据库(密码+2FA 动态码)与 MASTER_KEY 密钥托管
credentials 表为登录凭据唯一事实源(站点×登录方式,含 oauth/2FA);账号密码读写重定向凭据层并幂等迁移历史数据;TOTP 按 RFC6238 零依赖自实现,绑定需当前动态码校验;Key Escrow 防 MASTER_KEY 遗失;前端新增凭据库视图与账号 2FA 联动。64 pytest + 16 浏览器端到端验证通过。
|
2026-09-05 15:54:41 +00:00 |
|
gouki
|
2fbb658126
|
fix(security): funnel公网流量强制校验API_KEY双保险(Tailscale-Funnel-Request头,不可伪造)
|
2026-08-15 22:24:47 +00:00 |
|
gouki
|
8fea6c2288
|
fix(security): Tailscale内网(100.64/10)免API_KEY+外部强制校验;修复账号重复提交400(提交锁+唯一约束兜底)
|
2026-08-15 22:19:51 +00:00 |
|
gouki
|
b4705331c0
|
fix(account): 支持跨平台同名账号——(platform,name)联合唯一+Asset.account_id外键重构
|
2026-08-11 07:27:01 +00:00 |
|
gouki
|
bc1b804931
|
feat(account): 账号登录密码支持查看明文——新增GET /accounts/{id}/password解密接口+前端🔑查看弹窗(8s自动关闭/一键复制)
|
2026-08-10 14:51:52 +00:00 |
|
gouki
|
09a7b7aa42
|
test(deploy): timer注释标记,验证sync_units单元自动同步链路
|
2026-08-09 23:41:52 +00:00 |
|
gouki
|
88e7050cf0
|
fix(deploy): 版本比对统一用短哈希,修复永不匹配的bug
|
2026-08-09 23:08:39 +00:00 |
|
gouki
|
8dbccdb238
|
chore: 版本升至0.3.7(零SSH自动化部署:单元自动同步+1分钟更新+一键deploy.sh)
|
2026-08-09 22:45:45 +00:00 |
|
gouki
|
750a986821
|
fix(deploy): update.sh改用reset --hard同步远端,本地误改不再阻塞自动部署
|
2026-08-09 21:53:05 +00:00 |
|
gouki
|
e6323c5e46
|
fix(deploy): 恢复update.sh可执行位(755)
|
2026-08-09 21:28:55 +00:00 |
|
gouki
|
270ffc81f9
|
fix(deploy): 恢复update.sh可执行位;ExecStart改bash调用不再依赖可执行位
|
2026-08-09 21:18:27 +00:00 |
|
gouki
|
32a4e0da36
|
fix(deploy): 变量引用加花括号,避免多字节字符粘连导致unbound variable
|
2026-08-09 20:40:34 +00:00 |
|
gouki
|
e4a8cc68b4
|
feat(deploy): 零SSH自动化部署——update.sh自动同步systemd单元/更新timer缩至1分钟/新增deploy.sh一键部署验证脚本
|
2026-08-09 20:27:02 +00:00 |
|
gouki
|
dc2134cf5a
|
refactor: 凭证下沉账号层——平台不再持有API凭证;账号支持登录凭证+API配置,SDK测试/同步改为账号维度,同步产出自动挂账号;含存量数据自动迁移
|
2026-08-09 16:50:45 +00:00 |
|
gouki
|
cf18cadb6b
|
fix(ui): 账号编辑表单提升z-index至60,修复被账号查看弹窗(z-50)遮挡
|
2026-08-09 00:29:49 +00:00 |
|
gouki
|
ee5a4c81cf
|
feat: 平台卡片「关联N个资产」点击跳转资产页并按平台筛选(后端/api/assets新增provider参数,资产页可清除筛选标签)
|
2026-08-09 00:13:16 +00:00 |
|
gouki
|
74f9688ba1
|
fix(cache): 入口HTML加no-cache,杜绝启发式缓存持有旧?v=版本号导致部署后看到旧版
|
2026-08-08 23:42:40 +00:00 |
|
gouki
|
6829b211ac
|
feat(ui): 平台页默认隐藏未使用平台(无资产/账号/API配置),可一键展开全部,偏好持久化
|
2026-08-08 23:36:13 +00:00 |
|
gouki
|
fcb3153c50
|
refactor(ui): 账号改为平台→账号→资产三层交互(平台卡片入口+展开看名下资产,移除平铺账号区)
|
2026-08-08 22:16:14 +00:00 |
|
gouki
|
1c93ac00eb
|
feat(ui): 账号列表以说明为主标题(适配代管场景),账号标识为副;弹窗表单说明字段前置
|
2026-08-08 22:00:30 +00:00 |
|
gouki
|
a33a2b71de
|
feat: 版本号管理机制(VERSION文件+git哈希,部署/启动/UI/health均展示) + 平台账号管理(accounts表CRUD,资产所属账号候选联动,重命名同步引用)
|
2026-08-08 20:07:03 +00:00 |
|
gouki
|
4883837dda
|
fix: 阿里云/腾讯云list_vps补分页(超100台实例不再漏同步)
|
2026-08-05 22:55:41 +00:00 |
|
gouki
|
4dba505d82
|
fix+perf: SQLite连接busy_timeout修复并发锁/静态版本号缓存/删除资产批量清理/安全检查最新记录子查询修正/AI余额与SSL探测并发化/密钥常量时间比较
|
2026-08-05 22:49:01 +00:00 |
|
gouki
|
4f855ba0da
|
chore: .gitignore 忽略 .env.local(防止 S3 密钥误提交)
|
2026-08-05 12:41:17 +00:00 |
|
gouki
|
1b7d4823c3
|
feat: 综合平台services多服务支持+SW网络优先缓存修复+适配层/定时任务完善
|
2026-08-05 11:57:17 +00:00 |
|
gouki
|
7f1268f508
|
feat: 数据库备份支持S3兼容对象存储(SigV4纯标准库实现,无配置时兼容原本地备份)
|
2026-08-05 11:57:17 +00:00 |
|
gouki
|
f1cdcf716c
|
feat: 数据导出/导入(资产迁移/备份,支撑部署到其他服务器)
|
2026-08-03 00:12:38 +00:00 |
|