workbuddy.xpcool.com/.workbuddy/memory/MEMORY.md

79 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# xpcool.com 工作空间 · 统一规则与项目索引
> 本文件随会话自动加载。保持精简:只放规则与索引,详细历史在各项目 CHANGELOG。
## 三条铁律(全项目通用)
1. 中文注释:写/改代码时,在应有处(函数、复杂逻辑、配置项、非显然分支)加中文注释。
2. 做记录:每次请求/变更/修复/文档动作,都在对应项目 CHANGELOG.md 顶部追加一条。
3. 中文优先:与用户的思考、输出、交流,能中文尽量中文。
## 接口设计规范2026-08-27 起 · 全项目强制)
> 用户拍板:新建 HTTP 接口**全部采用 POST****URL 中不得带任何参数**(查询参数与路径参数 `{id}` 都禁止);**所有入参一律通过请求体 bodyJSON传递**。
- 路由用静态 path`/recruitment/info/update``id` 等也放 body不用 `/update/{id}`
- 既适用于 service 后端g.Meta `method:"post"`),也适用于 admin 前端(`requestClient.post(url, data)`url 无参)。
- **首个落地模块**service.xpcool.com 的 `recruitment`(招聘考试聚合),作为规范范本;后续新接口(含 house 之外的模块)一律遵守,存量接口逐步迁移。
## 界面开发约定2026-08-26 起)
- **admin.xpcool.com 后台界面开发优先使用 TDesign MCP**`tdesign-mcp-server`,已配置于 `~/.workbuddy/mcp.json``npx -y tdesign-mcp-server@latest`toolsget-component-docs / get-component-list / get-component-changelog / get-component-dom / search-icons
- 写/改 tdesign 组件代码前,先通过 MCP 查官方文档,用官方封装属性与推荐用法,避免踩自造轮子/已知坑。
- 树形表格必须用 `t-enhanced-table`t-table/PrimaryTable 不支持 tree异步数据后需 `await nextTick()` + `tableRef.value.expandAll()`defaultExpandAll 只在首次渲染生效)。
## 工作空间说明git 管理 · 跨设备同步)
- 本工作空间仓库:`workbuddy.xpcool.com`含本规则、每日日志、README远程`https://git.xpcool.com/xpcool/workbuddy.xpcool.com.git`
- **布局约定(跨设备必须一致)**:所有项目与工作空间仓库位于同一父目录下:
```
<父目录>/
├── workbuddy.xpcool.com/ ← 本工作空间(规则+索引+日志)
├── admin.xpcool.com/
├── service.xpcool.com/
└── tool.xpcool.com/
```
换设备时按此布局 clone索引即全部生效无需改任何路径。
## 项目索引(变更记录在各项目 .workbuddy/memory/CHANGELOG.md
| 项目 | 类型 | 相对路径(相对本工作空间) | 远程仓库 |
|------|------|--------------------------|---------|
| admin.xpcool.com | Vue 管理后台前端 | ../admin.xpcool.com/.workbuddy/memory/CHANGELOG.md | https://git.xpcool.com/xpcool/admin.xpcool.com.git |
| service.xpcool.com | Go 后端服务 | ../service.xpcool.com/.workbuddy/memory/CHANGELOG.md | https://git.xpcool.com/xpcool/service.xpcool.com.git |
| tool.xpcool.com | 前端工具站 | ../tool.xpcool.com/.workbuddy/memory/CHANGELOG.md | https://git.xpcool.com/xpcool/tool.xpcool.com.git |
(新增项目:在此加一行 + 在其 .workbuddy/memory/ 建 CHANGELOG.md + git.xpcool.com 建仓库)
## 记录格式(省 token · 快速命中)
- 倒序:最新在上,一行一条
- 模板:`YYYY-MM-DD | 类型 | 一句话摘要`
- 类型REQ 请求 / CHG 变更 / FIX 修复 / DOC 文档 / CFG 配置 / DEP 依赖
- 示例:`2026-08-26 | CHG | 新增用户列表分页接口并补中文注释`
## 命中流程
1. 判断是否涉及某项目(看项目名/路径)。
2. 读该项目 CHANGELOG.md 头部(最新 1015 条)了解近况。
3. 处理后于 CHANGELOG 顶部追加本次记录。
4. 新增项目时同步更新上方索引表。
## 生产部署(腾讯云 193.112.118.168SSH 22025/xxcoolDocker+宿主机 Nginx
- 站点落点:前端静态 → `/data/www/<域名>/`nginx 配置 → `/data/nginx/conf.d/<域名>.conf`80→301→443 + 反代/静态);证书 → `/data/nginx/ssl/<域名>/<域名>_bundle.crt|.key`(本地源:`E:\xxcool\ssl\<域名>_nginx/`)。
- service 后端容器:`service.xpcool.com:new``127.0.0.1:10100:10100`,网络 `xpcool-net`env`GF_GCFG_ENV=prod` + `DB_DSN=mysql:service:xxx@tcp(xpcool-mysql:3306)/service?...`**必须带 mysql: 类型前缀**+ `JWT_SECRET`;容器内必须有 `manifest/config/config.yaml`(基础配置),否则 GF 启动报「找不到 config」构建目录 `/data/deploy/projects/service.xpcool.com/`main + manifest/config + resourceDockerfile 用 COPY manifest/config 整体拷贝)。
- DB`xpcool-mysql` 容器root 密码见该容器 env库名 `service`,种子执行顺序 003→004→004b→007服务器表结构旧必须先 003 加列;导入用 `sudo sh -c 'docker exec -i xpcool-mysql mysql ... < file'` 宿主机重定向)。
- 权限映射admin_menu type=2 行的 path 必须匹配实际路由(现为 `POST /api/service/admin/...`,见 manifest/sql/007_menu_permissions_v3.sql
- 文件下载站2026-09-03 上线,当晚迁移):`file.xpcool.com` = **FileBrowser Quantum** 容器 `fbq``gtstef/filebrowser:stable` v1.5.5`127.0.0.1:10881→80`restart unless-stopped`/data/share:/srv:ro` **只读挂载**,数据卷 `/data/filebrowser-q`config.yaml+database.db+tmp属主=镜像 uid1000+ nginx 反代。**要点**:初始凭据 **admin/admin**(首登后立即改密);配置走 `config.yaml`sources/cacheDir管理走网页 UIAPI 与原版不兼容(需用户建 long-live token/swagger 亦需);镜像默认非 root(uid1000);原版 filebrowser(容器 `filebrowser`/10880/db `/data/filebrowser/database`)已于 2026-09-01 归档、现已停用**保留回滚**Quantum v2.0 beta 权限模型改 per-source(view/download/modify/create/delete)。改密/建只读账号/临时分享(过期+密码+匿名)均在网页 UI。
- SSH 凭据/密码不入库,需要时询问用户或查对话记忆;远程批量命令用 paramiko 脚本(`%TEMP%\wb_deploy\ssh_exec.py`,支持第 2 参数超时秒数docker build 用服务器端 nohup+日志轮询防超时。**2026-09-11 密钥轮换后更新)**:当前登录 = 本地 `~/.ssh/xpcool_ed25519`ed25519注释 xpcool-server-20260904`xxcool@193.112.118.168:22025`root 被拒;密码登录已禁);旧 `CentOS.pem`(RSA对应服务器公钥 `skey-q6pq6jb3`)**已作废并从 authorized_keys 移除**(因私钥误提交 Gitea 事件而轮换),服务器 authorized_keys 另存 2 把钥(`mcp-server-manager@local`、`xxcoolwork@gmail.com`)为其他用途、保留不动;安全组按出口 IP 限放 22025本机出口 1.204.105.116 曾因未放行连不上80/443 可达);本机旧记录 `~/.ssh/id_ed25519` 与 wb_deploy 脚本**在当前设备不存在**。
- **服务器安全加固2026-08-27 完成)**firewalld 已启用(放行 22025/80/443/3000/2222cockpit/rpcbind 已停fail2ban 保护 sshd(port=22025, maxretry5/bantime1h);监控脚本 `/usr/local/bin/server-monitor.sh` + cron 每 10 分钟(调度在 **xxcool 的 crontab**`*/10 * * * * sudo /usr/local/bin/server-monitor.sh`;日志 `/var/log/server-monitor.log`Bark 推送配 `/etc/server-monitor.conf``BARK_URL`**告警去重终版2026-09-11**:状态目录 `/var/lib/server-monitor/` —— `banned-ips.state`(已提醒过的封禁 IP**只增不减 → 同一 IP 永不重复提醒**)、`ssh-src-ips.state`(已提醒过的登录来源 IP**仅新 IP 首次登录**才提醒)、`ports.state`(当前已告警的未登记端口,消失后清除)、`ssh-brute.state`(爆破告警状态机:`attacking`=本轮已提醒 / `idle`=已复位;攻击持续不刷屏,攻击停止静默复位,**再犯视为新一波才重新提醒**);完整审计仍在 fail2ban.log + journald 且已上报 admin 后台(脚本备份 `server-monitor.sh.bak.20260911`);另有安全日志上报器 `/usr/local/bin/server-security-collector.sh`cron **每 5 分钟**xxcool crontab→ POST 到 `127.0.0.1:10100/api/service/open/security/log/report`,配置 `/etc/server-security.conf`INTERNAL_TOKEN、状态 `/var/lib/server-security/last.ts`dnf-automatic 每天 06:00 自动安全补丁SSH 密钥登录已部署(现用 `~/.ssh/xpcool_ed25519`)、密码登录已禁。**2026-09-11 加固**:已关闭 `X11Forwarding`**生效位置是 drop-in `/etc/ssh/sshd_config.d/50-redhat.conf:17`,主配置里那行是注释、改了无效**;改前备份 `.bak.20260911``sshd -t` 预检 + `sshd -T` 核对 + `systemctl reload sshd` 不断连nginx 遗留垃圾已清理(`.code.xpcool.com.conf.swo`、`tool.xpcool.com.conf.download.0` → 移入 `/data/nginx/_junk_backup_20260911/`,未直接删、可回滚)。**nginx 配置目录约定**`include /data/nginx/conf.d/*.conf;`,故 conf.d 下非 `.conf` 后缀文件不会被加载。**遗留待办**`lighthouse` 账号(腾讯云自带 uid1000NOPASSWD ALL是否锁定待用户决策。**坑**:① 腾讯云安全组未放行 3000/2222/8081Gitea 走 nginx 反代 80/443② 改 sshd 前必须先 `sshd -t` 预检+备份(曾因脏行导致 SSH 断开);③ EPEL 源需腾讯云镜像(`mirrors.cloud.tencent.com/epel`)且 baseurl 必须手动写全;④ CentOS9 的 fail2ban 在 EPEL。**⑤2026-09-04 新坑)腾讯云改带宽若切计费模式会触发实例冷重启,重启后 firewalld 自定义端口规则曾丢失致 SSH 22025 失联80/443 正常——firewall-cmd 放行务必带 `--permanent`,且实例冷重启后要复查 22025 放行**。另:带宽 3M→5M 已升级2026-09-04实测 619KB/s 满速)。**⑥2026-09-11 溯源新坑)本机出口 IP `1.204.105.116` 曾于 09-03 23:00 被自己的 fail2ban 封禁、09-04 23:00 才解封——这正是当时「SSH 22025 超时」的真因当时误判为安全组未放行绕了远路。SSH 突然不通时,排查顺序应为:先 `fail2ban-client status sshd` + `grep Ban /var/log/fail2ban.log`,再怀疑安全组**。**⑦2026-09-11 体检结论)服务器未发现被入侵迹象**UID0 仅 root、无空密码账号、无异常 SUID/后门/劫持、无特权容器、系统目录近 30 天无改动;外网暴露面实测仅 **22025/80/443**3000/2222/8081 等均被安全组挡住firewalld 虽放行 3000/2222 但安全组是第二道闸)。
- 本地 pnpm 修复2026-08-27 升级为 wrapper 方案):根因=本环境 MSYS 路径转换故障,把 `/c/...` 参数转成 `E:\c\...`(多 `E:\c\` 前缀)致 corepack shim 与 node 都找不到 pnpm.js。**已建持久 wrapper**`~/.workbuddy/binaries/node/bin/pnpm`(内容:`export NODE_OPTIONS=--experimental-sqlite; exec "<托管node.exe>" "C:/Users/ybtdevxxl/.workbuddy/binaries/node/workspace/node_modules/pnpm/bin/pnpm.cjs" "$@"`,关键=给 node 传 Windows 风格路径 `C:/...` 规避 MSYS 转换)。**提交/构建前需 `PATH="~/.workbuddy/binaries/node/bin:$PATH"` 前置**pre-commit 钩子(lefthook oxlint/oxfmt/eslint/stylelint/checkType)即可正常运行;否则钩子崩 → 只能 --no-verify。已验证 pnpm 11.16.0 + `pnpm exec oxlint` 1.79.0。
## 日常同步习惯(建议)
- 每次工作结束:在各改动项目 `git add + commit`,本工作空间同样提交(规则/日志变化时)。**只 commit、不要 push**2026-09-01 用户明确推送由用户自行完成AI 无需代为 push避免凭据交互失败
- **验证分工2026-09-01 用户明确)**AI 能做的验证(类型检查、构建、单元/二进制测试、自动化冒烟)照做;**AI 不方便验证的部分(真实浏览器交互体验、视觉效果、下载弹窗等)直接交给用户手动验证**,不要反复折腾自动化工具。
- 换设备开工前:先 `git pull` 各仓库,保证规则与记录最新。
## 本机 Windows/PowerShell 工具链坑位2026-09-10 实测,写脚本必看)
- **PowerShell 工具不回显 stdout**exit code 正常但看不到输出;必须把结果 `Out-File` 落盘,再用 Read 读取。Bash 里调 `powershell.exe` 会被安全策略拒绝。
- **`[byte] -shl 8` 会溢出归零**(结果仍是 byte 宽度)。字节拼 16 位整数必须先 `[int]` 转换,否则高位丢失(剪贴板/协议解析类代码的高频坑)。
- **给 .ps1 加 BOM 绝不能用 `Get-Content -Raw` + `Out-File`**:本机默认按 GBK 解码 UTF-8 文件,中文会被永久破坏且不可逆。正确做法是字节级前置 `EF BB BF``[System.IO.File]::WriteAllBytes`)。
- **PATH 被裁剪**:脚本里直接写 `ping` / `netsh` 会报"无法识别",须用 `$env:SystemRoot\System32\xxx.exe` 绝对路径;且不要写 `& $exe args 2>$null | Out-String`(会报"无法在管道中间运行文档"),改用 `$out = & $exe args``@($out) -join ' '`
- **PowerShell 变量名不区分大小写**`$R` 与循环变量 `$r` 是同一个变量,会导致集合被静默覆盖。
- **后台监听的进程可能杀不掉**Stop-Process / taskkill 均无效),换端口重新起更省事。
- **防火墙规则按可执行文件路径匹配**:一批 node.exe 规则指向已不存在的路径(失效);目前 `C:\Users\xxl\AppData\Roaming\nvm\v23.0.0\node.exe` 有有效的 Public 档「TCP+UDP 任意端口」入站放行规则——需要做**免提权的入站可达性测试**时就用它监听。
- 测入站**不要用 ping**Windows 默认拦 ICMPv6/ICMP 入站,必须用 TCP 端口测试。
- 国内测速Cloudflare 端点不可用;用 **Ookla 官方 CLI**`install.speedtest.net` 可直连下载)。
- 本机网络备注:家里的宽带是**运营商级 NATCGNAT第 2 跳 100.64.0.1**,无公网 IPv4但有**公网 IPv6**`240e:338:263:3600::/64`)。以太网被判定为 Public 网络档。