Commit Graph

298 Commits

Author SHA1 Message Date
wangjia 15ef71734d chore: release server-v1.0.64
Deploy Server / release-deploy-server (push) Successful in 55s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
server-v1.0.64
2026-06-20 10:13:49 +08:00
wangjia 36c7ad8b43 chore: release client-v1.0.61
Deploy Client / build-client-web (push) Successful in 38s
Deploy Client / build-windows (push) Successful in 1m52s
Deploy Client / build-macos (push) Successful in 1m55s
Deploy Client / build-android (push) Successful in 1m0s
Deploy Client / build-ios (push) Successful in 2m47s
Deploy Client / release-deploy-client (push) Successful in 1m21s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
client-v1.0.61
2026-06-20 08:56:02 +08:00
wangjia 2b6178892f chore: release client-v1.0.60
Deploy Client / build-client-web (push) Successful in 40s
Deploy Client / build-macos (push) Successful in 2m1s
Deploy Client / build-android (push) Successful in 1m26s
Deploy Client / build-ios (push) Successful in 2m57s
Deploy Client / build-windows (push) Successful in 1m48s
Deploy Client / release-deploy-client (push) Successful in 1m24s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
client-v1.0.60
2026-06-20 07:07:01 +08:00
wangjia 937446214b chore: release server-v1.0.63
Deploy Server / release-deploy-server (push) Successful in 52s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
server-v1.0.63
2026-06-20 07:06:08 +08:00
wangjia a76724b385 feat(client): 录单表单优化 + 可搜索下拉支持新建 + 日期选择器组件
新增 DatePickerField 日期选择器与 date_util;可搜索下拉 SearchableOptionField
支持内联新建选项;入库/出库录单表单、商品页、财务页、app_shell 导航相应调整。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:05:22 +08:00
wangjia e892ab45b2 feat(client): 历史单明细优先读快照列、回退 product 关联
入库/出库明细 fromJson 改为优先取明细行自身的 product_code/name/series/spec
快照列,回退到 product 关联。历史导入单 product_id 为占位、无 product join,
靠快照列正常展示商品信息;App 新建单据仍走 product 关联,行为不变。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:05:13 +08:00
wangjia 90d2c8668b feat(backend): 历史进销存导入器 cmd/import-history + 单据明细快照列
一次性 CLI 导入旧系统 data/ 入库·出库 总表/详情表到当前库,历史只读(绝不
回放 inventories/inventory_logs)。明细忠实直存不做 SKU 归一:order/item 表
新增 creator_id(制单人)与 product_code/product_name/series/spec 快照列
(出库另补 batch_no/production_date),导入行 product_id 指向共享占位商品。
order_no 天然主键 (shop_id,order_no) 幂等去重,可重复跑。

testutil sqlite DDL 同步补列以保持 service 测试通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 07:05:08 +08:00
wangjia 7bbc944ae2 chore: release server-v1.0.62
Deploy Server / release-deploy-server (push) Successful in 51s
服务端安全加固:多维限流(按 IP/按门店)+ 敏感接口独立速率上限抵御 DDoS/刷接口;
登录暴力破解新增按来源 IP 锁定;反代后正确识别真实客户端 IP;
门店 custom_fields 轻量配置(录入默认值)透传保存。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
server-v1.0.62
2026-06-19 20:20:44 +08:00
wangjia 0d967e899a chore: release client-v1.0.59
Deploy Client / build-client-web (push) Successful in 41s
Deploy Client / build-windows (push) Successful in 2m36s
Deploy Client / build-macos (push) Successful in 2m17s
Deploy Client / build-android (push) Successful in 1m36s
Deploy Client / build-ios (push) Successful in 2m46s
Deploy Client / release-deploy-client (push) Successful in 1m24s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
client-v1.0.59
2026-06-19 14:07:16 +08:00
wangjia 0a21ea5b2a chore: release server-v1.0.61
Deploy Server / release-deploy-server (push) Successful in 1m8s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
server-v1.0.61
2026-06-19 14:06:03 +08:00
wangjia 9b6dba4c2b test(backend): 补 redeem_code 单测 + gitignore todo/ 与 gencode 产物
覆盖 NormalizeCode 边界/幂等、GenerateRedeemCode 格式/无歧义字母表
(剔除 0/O/1/I/L)/无碰撞。.gitignore 忽略全局 todo skill 本地数据
与 backend/gencode 构建产物。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-19 14:04:22 +08:00
wangjia 54451f0e52 feat(deploy): gencode 纳入 server 发版产物 + EC2 生码封装
server 流水线编译并发布 jiu-gencode 二进制(回滚路径随 release 资产
自动下载),部署到 /opt/jiu/backend/,对旧版回滚做存在性判断优雅跳过。
新增 deploy/jiu-gencode.sh 封装自动读 production.env,线上生码从此
一条 ssh 即可,无需本地交叉编译 + scp。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-19 14:04:14 +08:00
wangjia 8fc24b5d36 chore(deploy): 移除退役的 ed25519/HMAC license 死配置
兑换券改造后运行时已不读签名相关 env,清理 production.env.template
的 LICENSE_HMAC_SECRET / LICENSE_ED25519_* 三项,并从 render-env.sh
的 SECRET_KEYS 去掉对应密钥(渲染 env 时不再白拉 Bitwarden)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-19 14:04:06 +08:00
wangjia 6ac6b52717 chore: 移除两个废弃 skill(archive-design / design-review)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-19 12:52:30 +08:00
wangjia c72e4171fc chore: release server-v1.0.60
Deploy Server / release-deploy-server (push) Successful in 42s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
server-v1.0.60
2026-06-19 12:15:28 +08:00
wangjia f955391830 docs: license-design 增补 v2 时长兑换券模型说明
顶部新增 v2 节,标注 v1 的 Ed25519 token 方案已废弃,记录兑换券
模型/数据表/Redeem 流程/与 v1 差异;运行时降级 phase 两版共用。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:14:35 +08:00
wangjia f4e5f935e2 feat(client): 授权 Tab 文案改为兑换券语义
激活卡片标题/说明/输入提示/按钮/成功提示对齐时长券:
"兑换激活码"、hint JIUKU-XXXX-XXXX、"时长叠加到当前授权之后"。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:14:35 +08:00
wangjia 23dff69c62 feat(backend): 授权改为时长兑换券体系 + 退役 ed25519/HMAC + 平台生码工具
- 新增 license_codes 码池表 + model.LicenseCode;licenses 加 tier 档位列
- LicenseService.Redeem:单事务 FOR UPDATE 校验码未用 → 时长叠加(可叠加,0=永久)
  → 写 type/tier/max_devices → 绑设备(超限整笔回滚) → 标记已用 → 即时失效 phase 缓存
  路由仍 POST /license/activate,客户端零破坏
- util.GenerateRedeemCode/NormalizeCode:JIUKU-XXXX-XXXX 短码(crypto/rand)
- cmd/gencode:平台批量生成兑换码并落库;删除 cmd/issue、cmd/genkey
- 退役 ed25519 + HMAC:删 util/license_key、GenerateKey、License 全部 config 字段
  及生产启动私钥校验;trial 改直接建行(无需私钥、去 Fatal)
- tier 档位钩子默认 standard,分档消费模式后续设计
- 测试:Redeem 全场景(叠加/过期重置/永久/一码一次/无效/设备上限回滚)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:14:27 +08:00
wangjia 914e2fb533 chore(scripts): 新增授权到期时间测试工具 set-license-expiry.sh
按相对天数设置门店授权 expires_at,快速切换 normal/grace/readonly/locked
四个阶段验证客户端表现。SSH 到线上 jiu_mysql 执行,DB 密码仅在远端从
production.env 读取,不打印/外传。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 09:58:31 +08:00
wangjia 58266a2095 feat(client): 登录页品牌化 + 授权过期续费入口 + 全平台应用图标统一
- 登录页文案与 Logo 改为「岩美酒库」品牌:标题/副标题/页脚 + 内嵌品牌 mark(替换原酒杯渐变方块)
- 授权过期锁定时,登录页给出续费入口:前往官网续费 + 复制客服邮箱
- 应用图标全平台统一为岩美品牌 mark:macOS(16-1024) / Web(favicon+icons+maskable)
  / Android mipmap(48-192) / iOS AppIcon(20-1024,满底无 alpha 过审核)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 09:58:25 +08:00
wangjia ca093c3c22 chore: 移除项目级 Figma MCP 与自带 /todo 命令,TODO 统一走全局 skill
- 删除 .mcp.json(项目级 Figma MCP 注册,改用全局)
- 删除 .claude/commands/todo.md(项目自带 /todo slash command)
- CLAUDE.md「项目 TODO 管理」改写:统一使用全局 todo 工具
  (~/.claude/skills/todo/),数据落到本项目 todo/ 目录

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 09:57:17 +08:00
wangjia ec36b9679a chore: release server-v1.0.59
Deploy Server / release-deploy-server (push) Failing after 23m11s
server-v1.0.59
2026-06-19 07:35:22 +08:00
wangjia 51c81fd943 docs: 会话安全方案文档 + 本地测试脚本
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 07:34:07 +08:00
wangjia 32bd64d676 feat(client): 实时授权状态与会话失效处理
- 心跳读取 /auth/ping 回带的授权概况,直接刷新横幅/状态栏/只读门禁,省去单独轮询 /license/info
- 账号被停用/删除(401 USER_DISABLED)即强制重新登录
- 令牌持久化经串行队列 + 会话代号守卫,杜绝续期写入与登出交叉把失效 token 写回
- 写操作门禁(write_guard)+ 授权文案(license_copy)按 grace/readonly/locked 分阶段降级

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 07:34:07 +08:00
wangjia e41085a878 feat(backend): 会话安全加固 + 授权实时 phase + 首次使用自动试用
会话安全(jti 轮换 / 重用检测 / 改密吊销 / 禁用即时下线 / 清理 / 失败登录落库):
- refresh token 轮换 jti + token-family 重用检测,旧 token 重放即吊销整条会话
- 改密码、停用用户即时吊销其全部活跃会话(revoked_by 审计)
- 中间件 session JOIN user 校验,禁用/删除用户带 token 请求返回 401 USER_DISABLED
- 新增 login_attempts 失败登录落库 + 会话保留期清理 goroutine

授权实时 phase + 心跳回带:
- LicenseGuard 改为按当前 DB 实时计算 phase(30s 每店缓存),续费/过期/被改 ~30s 内对写操作生效,无需重登
- /auth/ping 回带授权概况(ShopInfoView,与 /license/info 同构),客户端一次心跳即刷新横幅/门禁

首次使用自动试用 + code-review 修复:
- 门店首次登录/续期无有效授权时自动签发 30 天 trial(快路径无锁 Count,仅首用走 FOR UPDATE 事务)
- ShopInfo 区分「确无授权」与瞬时 DB 错误,避免误降级
- trial 签发后改为在事务提交后再失效 phase 缓存(修复早于提交的竞态)
- 存量无 sid token 续期纳入显式上限,legacy 会话不再游离于并发配额之外

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 07:34:04 +08:00
wangjia 2d84bda99a chore: release server-v1.0.58
Deploy Server / release-deploy-server (push) Successful in 48s
RefreshTokens 续登路径补发首次试用,修复自动续登老用户授权停留「未激活」。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
server-v1.0.58
2026-06-18 19:14:25 +08:00
wangjia e3c8350d03 chore(deploy): 接入 Ed25519 license 签发密钥到 production.env 渲染
render-env.sh 修正 Bitwarden 条目名为「jiu db password」,SECRET_KEYS
加入 LICENSE_ED25519_PRIVATE_KEY;模板补公钥(明文可提交)与私钥占位。
修复未激活门店因生产缺少签发私钥而无法自动发放试用授权的问题。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-18 08:57:30 +08:00
wangjia a8e29a641a feat(client): 退出登录归入用户名下拉菜单
侧栏底部用户名行改为可点击的 PopupMenuButton,点击弹出账号菜单,
退出登录移入其中;移除原用户名行直接打开门店信息面板的入口。
设备管理保持在侧栏导航不变。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-18 08:57:30 +08:00
wangjia e3e8cf7037 chore: release client-v1.0.58
Deploy Client / build-client-web (push) Successful in 40s
Deploy Client / build-windows (push) Successful in 1m56s
Deploy Client / build-macos (push) Successful in 2m13s
Deploy Client / build-android (push) Successful in 1m35s
Deploy Client / build-ios (push) Successful in 3m0s
Deploy Client / release-deploy-client (push) Successful in 1m19s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
client-v1.0.58
2026-06-18 08:01:50 +08:00
wangjia 435e02278d chore: release server-v1.0.57
Deploy Server / release-deploy-server (push) Successful in 40s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
server-v1.0.57
2026-06-18 08:00:34 +08:00
wangjia 64a64e7c0a feat(backend): 首次登录无有效授权时自动发放 30 天试用
未激活门店(seed/手动建店/老数据,无任何 license 行)此前被当作永久授权,
既不拦截也无提示。现在登录时若门店无有效授权,自动签发 30 天 trial,
之后照常走 grace/readonly/locked 降级链。须在 issueTokens 之前发放,
使 JWT 的 lic_exp 带上新到期日。幂等(已有有效授权不重发),签发失败
仅记日志不阻断登录。复用注册路径的发放逻辑(抽出 issueTrialLicense)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
2026-06-18 07:59:44 +08:00
wangjia 2ac1cbfb24 ci(devops): compile-windows 兼容裸 v 前缀版本号,修 pubspec 非法版本
Build Windows Only / build-windows (push) Successful in 2m21s
build-windows.yml 单独触发时默认 ver=v1.0.4,脚本仅剥 client-v 前缀,
导致 pubspec 写入 version: v1.0.4+1 被 flutter 拒(Invalid version number)。
追加一道 ${VER#v} 剥裸 v;真实发版路径 client-v* 不受影响(无裸 v,空操作)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
winbuild4
2026-06-18 07:54:48 +08:00
wangjia f2f7ab77fa ci(devops): Windows runner bash 改由 Machine PATH 提供,workflow 回退干净 shell: bash
Build Windows Only / build-windows (push) Failing after 19s
runner 主机已把 C:\Program Files\Git\bin 加入 Machine PATH(forgejo-runner
以 LocalSystem 运行,已重启生效,where bash 可解析),故撤掉 cf468f5 的
绝对路径 hack,provision/compile 两步回到 shell: bash + sh scripts/ci/...。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Wdwo7SmgBJU37cBrkhPK
winbuild3
2026-06-18 07:50:09 +08:00
wangjia cf468f51cf ci(devops): Windows runner 将 shell 钉到 Git for Windows 自带 bash 绝对路径
Build Windows Only / build-windows (push) Failing after 15s
Git 安装包默认只把 git.exe 加入 PATH(Git\cmd),不含 bash.exe(Git\bin),
导致 act_runner 解析 `shell: bash` 时报「Cannot find: bash in PATH」。
改用 GitHub Actions 官方等价写法,绕过 PATH 查找:
  C:\Program Files\Git\bin\bash.exe --noprofile --norc -eo pipefail {0}
(bin\bash.exe 包装器会注入 /usr/bin,使脚本内 sh/powershell 可解析)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
winbuild2
2026-06-17 23:42:06 +08:00
wangjia 90f318e246 chore: release client-v1.0.57
Deploy Client / build-windows (push) Failing after 21s
Deploy Client / build-client-web (push) Successful in 42s
Deploy Client / build-macos (push) Successful in 2m8s
Deploy Client / build-android (push) Successful in 1m25s
Deploy Client / build-ios (push) Successful in 2m47s
Deploy Client / release-deploy-client (push) Has been skipped
设备/状态管理屏(查看本店在线设备/会话,管理员可强制下线)、登录携带设备信息、
会话心跳(/auth/ping)、被踢下线/会话失效提示、顶栏精简 + 用户名移至左侧栏底部。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
client-v1.0.57
2026-06-17 23:13:05 +08:00
wangjia 53fa259284 chore: release server-v1.0.56
Deploy Server / release-deploy-server (push) Successful in 40s
会话/设备管理后端:user_sessions 会话表、JWT 加 sid 校验、按平台类限并发登录、
登录失败锁定、修复禁用账号仍可凭 refresh 续期漏洞、/auth/ping、/auth/logout、
GET /sessions、DELETE /sessions/:id(管理员强制下线)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
server-v1.0.56
2026-06-17 23:12:13 +08:00
wangjia 7c82553594 chore: release client-v1.0.56
Deploy Client / build-client-web (push) Successful in 40s
Deploy Client / build-windows (push) Successful in 1m53s
Deploy Client / build-macos (push) Successful in 2m3s
Deploy Client / build-android (push) Successful in 1m11s
Deploy Client / build-ios (push) Successful in 2m32s
Deploy Client / release-deploy-client (push) Successful in 1m10s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
client-v1.0.56
2026-06-17 18:34:29 +08:00
wangjia dfa1920dda feat(client): 列表屏搜索前置/显示字段记忆/移动端表格切换与工具栏瘦身/退出登录归位
- 库存查询搜索框移到工具栏最前(桌面)/独占首行(移动端)
- 修复入库/出库/财务「显示字段」失效:移除 minWidth 运行时强制隐藏,
  用户勾选权威、minWidth 仅作首次默认;新增 ColumnPrefs 持久化记忆(四屏独立)
- 移动端库存支持表格/卡片列表切换
- 移动端三个列表屏工具栏改 Wrap 紧凑布局、导出/显示字段图标化
- 退出登录统一到左侧导航:删系统设置内与桌面右上角下拉,桌面左侧栏底部新增

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 18:33:31 +08:00
wangjia 48e282dd97 feat(devops): macOS 构建接入 Developer ID 签名 + 公证
- compile-macos.sh:flutter build 后 codesign(hardened runtime + timestamp
  + Release.entitlements)→ notarytool 公证(复用 App Store Connect API key)
  → stapler staple → 重新打包,产出已签名+公证+stapled 的 .app
- 强制策略:缺 MACOS_DEVELOPER_ID_CERT_P12_BASE64 / APPSTORE_API_KEY_P8_BASE64
  时在 flutter build 前 fail-fast,绝不产出未签名包
- deploy-client.yml:build-macos 步骤注入证书与 API key secrets
- 新增 docs/macos-signing.md:Developer ID Application 证书创建与 secret 配置

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 12:56:08 +08:00
wangjia 40d9aba657 chore: release client-v1.0.55 / site-v1.0.55 / server-v1.0.55
Deploy Server / release-deploy-server (push) Successful in 42s
Deploy Client / build-client-web (push) Successful in 40s
Deploy Site / release-deploy-site (push) Successful in 22s
Deploy Client / build-macos (push) Successful in 1m28s
Deploy Client / build-android (push) Successful in 1m7s
Deploy Client / build-ios (push) Successful in 2m44s
Deploy Client / build-windows (push) Successful in 1m51s
Deploy Client / release-deploy-client (push) Successful in 1m23s
三条流水线首个独立版本,统一从 1.0.55 起步。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
server-v1.0.55 client-v1.0.55 site-v1.0.55
2026-06-17 08:27:53 +08:00
wangjia aa7099ba94 feat(devops): 发版拆分为 client/site/server 三条独立流水线
将单一 CI/CD 流水线拆成三条互不影响的发布流水线,各有 tag 前缀、独立版本
序列与独立 CHANGELOG:

- client(client-v*):Flutter 全平台 + version.yaml 自更新清单
- site(site-v*):web/ Eleventy 营销站,不含 web 版 app
- server(server-v*):backend Go 服务 + 共享基建 nginx/systemd

新增 3 个 workflow(deploy-client/site/server.yml)替换 deploy.yml;CI 脚本
按 part 拆分为 compile-/release-/deploy-{client,site,server}.sh,抽出公共函数
lib-forgejo.sh;compile-{macos,android,ios,windows}.sh 改去 client-v 前缀;
manual.yml 按前缀路由回滚。

跨流水线解耦:version.yaml 归 client,后端每请求实时读取(不重启、不触发
server 流水线);官网下载页的版本徽章/下载链接/更新日志时间线运行时经
/api/v1/public/release 动态拉取(API 不可达回退构建时静态内容)。为此一次性
扩展后端 changelog 字段(version.go/public.go)与 download.njk 动态渲染。

CHANGELOG.md 重命名为 CHANGELOG-client.md,新增 CHANGELOG-site/server.md;
重写 /release 命令为 /release <part> [version];同步更新 CLAUDE.md 与部署文档。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 08:21:28 +08:00
wangjia eca62ba2c3 fix(backend): 库存导入改用 shakinm/xlsReader,按唯一编号去重,入库日期取自 Excel
extrame/xls 误读真实 .xls(3264 行只读出 455 行、编号丢失、数字被当
日期序列),换用 shakinm/xlsReader 正确读取全部行。去重改为「有商品编号
时仅按编号匹配」,避免不同批次被 NSS 回退合并;Inventory.ProductCode
存行自身唯一编号。入库时间取 Excel 入库日期列写入 created_at。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 08:04:04 +08:00
wangjia 21700fa64c chore: release v1.0.54
Deploy / build-linux-web (push) Successful in 52s
Deploy / build-windows (push) Successful in 1m58s
Deploy / build-macos (push) Successful in 1m27s
Deploy / build-android (push) Successful in 1m32s
Deploy / build-ios (push) Successful in 2m51s
Deploy / release-deploy (push) Successful in 1m55s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
v1.0.54
2026-06-17 06:57:43 +08:00
wangjia 5cfd1795ec fix(backend): 库存导入用 Excel「入库日期」+ 同 key 增量更新/全同跳过
- 读取 Excel「入库日期」列(默认第12列,兼容入库日期/入库时间/入库日),
  显式写入库存 CreatedAt,不再被 GORM 落成导入当天;新增
  parseTimeWithFallback 兼容 yyyy-MM-dd / 含时分秒 / Excel 序列号
- 同 key(商品编码|仓库,回退 名+系列+规格|仓库):全字段一致则跳过,
  仅差异字段增量更新;库存流水仅在 quantity 实际变化时追加
- 响应新增 skipped 计数;多租户 shop_id 隔离不变

go build / vet / test 全过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 00:56:31 +08:00
wangjia f15692bbd5 refactor(client): 只读判断统一走 WriteGuard 控件
将各屏内联的 ref.watch(isReadonlyProvider) 只读判断统一改为
WriteGuard(child:) 或 WriteGuard.isReadonly(ref),全项目只读逻辑
单一入口(仅 write_guard.dart 内部保留 provider 读取)。行为不变。

121 测试通过,analyze 无 error。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 00:56:31 +08:00
wangjia 196901b6d3 feat(client): 只读角色隐藏所有写按钮(WriteGuard 统一控件 + 顶栏只读标识)
- 新增 isReadonlyProvider(role == 'readonly')+ WriteGuard 控件,统一隐藏写控件
- 入库/出库/库存/商品/基础数据/往来单位/财务/设置 各屏:只读时隐藏
  新增/编辑/删除/审核/提交/驳回/结清/盘点/导入/激活/用户管理 等写操作
- 顶栏显示「只读」标识,让只读用户明确当前权限
- 后端 middleware.ReadOnly() 仍兜底 403,UI 隐藏 + 后端拦截双保险

修正:此前误判为后端漏洞/部署 bug,实为前端写按钮未对只读隐藏。
后端经验证正确拦截只读写操作(线上 stock-in/product-options 均 403)。

121 测试通过,analyze 无 error。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 00:42:40 +08:00
wangjia 53465ed704 fix(client): Info.plist 补 NSLocationWhenInUseUsageDescription,消除 ITMS-90683
某依赖引用定位 API,Apple 要求声明用途字符串(即便 App 不主动用定位)。
补上后正式提交 App Store / Beta 审核不再被该警告卡住。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:46:32 +08:00
wangjia 5371d40f05 chore: 彻底停用项目 todo(删除 todo/ 目录 + CLAUDE.md 规则改为停用)
按用户要求停用 todo skill。todo/ 历史保留在 git 记录中可恢复。
CLAUDE.md 项目规则覆盖全局 todo 规则:本项目不再记 todo。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:43:12 +08:00
wangjia a63ee263ca chore: 清空项目 todo(按用户要求,历史保留在 git 记录中)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:38:30 +08:00
wangjia e8bdb19195 feat(client): 抽屉+设置页加退出登录入口;酒行信息显示微信号
- 左侧抽屉底部、系统设置页底部各加「退出登录」按钮(窄屏顶栏菜单
  不便时也能退出;登出后路由 redirect 自动跳 /login)
- 酒行信息 tab 补显示「微信号」行(模型/编辑弹窗早已支持 wechat_id,
  仅只读展示遗漏)

121 测试通过。todo #54 #55。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:26:17 +08:00