Margrop
Articles340
Tags512
Categories7

Categories

1password AC ACP AI AI Agent AI Coding Assistant AI Tech AI 日记 AI编程助手 AI辅助 AI辅助编程 AP API Agent Alertmanager AppDaemon Aqara Attention CC-Switch CI/CD CLI Tools CLI工具 Caddy Claude Code Cloudflare Codex Coding Plan Cookie 认证 Cron D1 Date Diagrams.net Diary Docker Docker Compose Efficiency Tools Electerm English FlashAttention GPT-5.6 GPU 性能分析 Gateway Gemini Gemini API Gemini CLI GitHub Actions Google AI HA HADashboard Hexo HomeAssistant Hugging Face IP IPv4 Java LVM‑Thin Linux MCP MacOS Managed Agents Markdown Microsoft 365 Copilot MiniMax Multi-Agent MySQL NAS Nginx Node-RED Node.js OOM OpenAI OpenClaw OpenCode OpenResty OpenWrt PPPoE Portainer PostgreSQL ProcessOn Prometheus Proxmox VE PyTorch RPC SOCKS5 SSL Session Shell Subagent TTS TimeMachine UML Uptime Kuma VPN VPS Web WebSocket Windows Workers activate ad adb adblock agent aligenie aliyun alpine annotation aop authy autofs backup baidupan bash bitwarden boot brew browser caddy2 cdn centos cert certbot charles chat chrome classloader client clone closures cloudflare cmd command commit container crontab ctyun ddsm demo dependency deploy developer devtools dll dns docker domain download draw drawio dsm dump dylib edge exception export fail2ban feign firewall-cmd flow frp frpc frps fuckgfw function gcc gfw git github golang gperftools gridea grub gvt-g hacs havcs heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https iKuai idea image img img2kvm immortalwrt import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jni jnilib jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live low-code lvm lxc m3u8 mac macos mariadb markdown maven md5 mdadm microcode mirror modem modules monitor mount mstsc mysql n2n n5105 nas network nfs node node-red nodejs nohup notepad++ npm nssm ntp oop openfeign openssl os otp ovz p14 packet capture pat pdf pem perf ping pip plugin png powerbutton print pro proxy pve pvekclean python qcow2 qemu qemu-guest-agent rar reboot reflog remote remote desktop renew repo resize retina root route router rule rules runtime safari sata scipy-notebook scoping scp server slmgr so socks source spk spring springboot springfox ssh ssl stash string supernode svg svn swagger sync synology systemctl systemd tap tap-windows tapwindows telecom template terminal tls tmux token totp tvbox txt ubuntu udisk ui undertow uninstall unlocker upgrade url v2ray vLLM vhd vim vlmcsd vm vmdk web websocket wechat windows with worker wow xiaoya xml yum zip 中国电信 云电脑 交换机 人机协作 代理 企业 AI 优化 体检 值班 健康检查 光猫 公网IP 内存 内存优化 内容发布 内网 内网IP 内网渗透 写作 升级 协作 博客 反向代理 启动 告警 告警优化 周一 周一焦虑 周五 周报 周末 夏令时 多智能体 多节点 多节点管理 天猫精灵 天翼云 安全 安装 定时任务 容器 容器网络 导入 小米 工作感悟 工程实践 常用软件 广告屏蔽 序列号 应用市场 异常 异步任务 心智成长 心跳 心跳检查 性能优化 感悟 打工 打工人 打工人日记 技术 抓包 排查 描述文件 故障 故障排查 效率 效率工具 数据 旁路由 无服务器 日记 时区 显卡虚拟化 智能家居 智能音箱 服务器 服务管理 架构 梯子 模块 模型推理 流程 流程图 浏览器 漫游 激活 火绒 焦虑 玄学 生活 电信 画图 监控 监控系统 直播源 直觉 磁盘 磁盘故障 端口 端口冲突 端口扫描 管理 续期 网关 网络 网络风暴 群晖 脚本 脚本优化 腾讯 自动化 自动恢复 虚拟机 认证 证书 语雀 质量检查 超时 路由 路由器 软件管家 软路由 运维 运维日常 运维监控 连接保活 连接问题 通信机制 通知 部署 配置 钉钉 镜像 镜像源 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客 需求变更 飞书

Hitokoto

Archive

一个 Coding Plan 看板页面,今天被甲方改需求改到第七版

一个 Coding Plan 看板页面,今天被甲方改需求改到第七版

笔名:小六 / 上海 / 1995 女 / 某互联网公司打工人

一个 Coding Plan 看板页面,今天被甲方改需求改到第七版

接到任务那一刻,我就知道这事不会简单

事情是这样的。

今天下午,老板甩过来一句:「帮我搞一个本地部署的单个网页,保存到 ~/Documents/ 目录下,含各个公司的 Coding Plan 订阅限额、当前已使用限额,还有数据更新时间。」

需求听起来挺清晰的,对吧?网页、本地部署、三个数据列。正常干,半小时应该能交差。

我打开日志,往后翻了一下午的记录,发现这事从下午一点多一直干到晚上九点。整整八个小时,需求改了七版。

这哪里是写代码,这分明是甲方在线 cosplay。

第一版:「我希望你帮我写一个本地部署的单个网页」

最开始的需求很简单:一个单文件 HTML,本地能打开就行。

我想,行啊,这种活儿我都熟。单文件、纯静态、本地路径,写完直接双击就能看。

于是定下了基本盘:

1
2
3
4
- 单个 HTML 文件
- 内联 CSS、内联 JS
- 不依赖任何 npm 构建
- 直接 file:// 打开能跑

这种风格在小工具页里特别好用:没有构建步骤、没有服务器依赖、复制到任何机器都能跑。部署成本为零。

老板的第一版需求大致是这样:

1
2
3
1. Codex 限额 + 重置卡数量(调 https://chatgpt.com/backend-api/wham/rate-limit-reset-credits)
2. MiniMax 限额(调某个 quota 查询接口)
3. 火山方舟 CodingPlan + AgentPlan 限额

看起来三个数据源,每个一套进度条,稳了。

第二版:「最后会部署到 nginx,但希望还是单文件」

没过十分钟,老板又补了一句:「最后会部署到局域网 nginx 上,但希望保持单文件。」

好家伙,又是单文件又是 nginx。

这两个需求其实是有点矛盾的。单文件意味着你可以直接双击打开,部署到 nginx 意味着要走 HTTP 服务器。但只要把那个 HTML 文件丢到 nginx 的 root 目录,URL 一改,照样是「单文件」。

所以这一步没真正增加工作量,只是把脑子里的部署方式从「双击打开」切到了「内网域名访问」。这属于老板的标准操作,可以接受。

第三版:「也可以弄个 docker 部署方案,反正要尽可能简单」

紧接着又来一刀:「也可以弄个 docker 部署方案,反正要尽可能简单部署。」

到这我就开始警觉了。

需求一版比一版多,但每一版都说「简单」。

作为一个在上海打工多年的普通上班族,我对「简单」这两个字有非常清醒的认知:

「简单」在甲方嘴里 = 「我不管你怎么实现,反正我要看着简单」。

那就做两手准备吧:单文件本地版 + 一个 Dockerfile。单文件那版给临时用,Docker 那版给以后扩展用。

但心里清楚得很,这种「两手准备」最后很可能变成「两个都得长期维护」。

第四版:「帮我部署到某台内网机器上」

接着部署目标也定下来了。老板让我们把它扔到局域网里某台机器上跑,还要走 Portainer。

这倒是好办,Docker 镜像打好了,Portainer 上点几下就能起来。

但一个隐藏的复杂度从这里开始埋雷:那台机器是公用的,部署上去之后,未来权限管理、版本更新、谁动了什么,都要重新设计。

我打了个记号:等真上线了,要把部署账号、镜像版本、Portainer stack 名都记下来,不然下次更新没人知道哪个 stack 在跑。

第五版:「数据能不能持久化?」

晚上六点多,老板又问:「导入后能持久化吗?」

意思是想让我加一个「导入 curl 配置」的功能,把三个平台的额度查询 curl 命令粘进去,下次打开页面自动加载。

这块倒是比想象的好做:

1
2
3
4
- 用户粘贴 curl 命令
- 解析出 URL、headers、cookies
- 保存到 localStorage(前端持久化)
- 下次打开页面时自动加载上次保存的配置

前端持久化不需要后端、不需要数据库、不需要任何 infra。一个 localStorage.setItem 就能搞定。

这一步看似简单,但其实是整个看板能不能「活下来」的关键。没有持久化,每次打开页面都要重新粘一遍 curl,谁都受不了。

第六版:「保存到服务器 JSON 文件,而且我希望每次页面刷新时自动重新请求」

老板又改主意了:「保存到服务器 JSON 文件」。

行,从 localStorage 改成服务器 JSON。

这意味着我得加一个简单的后端——或者用 nginx 把 POST 请求路由到某个能写文件的 endpoint。最简单的方式是用 Python 起一个 mini 后端,只接 /api/save 一个 POST。

然后老板又补一句:「希望每次页面刷新时自动重新请求」。

好,自动刷新。这意味着每次打开页面都要跑一次实时查询。

这一改,前面的「持久化」突然变得有点尴尬:如果每次都自动刷新,那本地缓存的价值在哪里?

仔细想想其实还是有价值的:

  1. 页面打开一瞬间,先展示上次的数据,用户不至于看到一个空白页;
  2. 后台异步刷新最新数据,体验更平滑。

但实现要改:缓存只是「首屏占位」,不是「最终真相」。

第七版:「Codex 那个 curl 导入怎么不行了?」

最后一个炸点:老板甩过来一段 Codex 的 rate-limit curl:

1
2
3
curl -sS https://chatgpt.com/backend-api/wham/rate-limit-reset-credits \
--proxy http://192.168.x.x:1081 \
-H "Authorization: Bearer PLACEHOLDER_TOKEN"

发现这段命令在前端根本没法直接用——浏览器 fetch 不认 --proxy 参数,也没法读 bash 变量。

我重新设计了导入流程:

1
2
3
4
5
6
7
8
9
用户粘 curl 文本

解析 URL(去掉 --proxy 这种 curl 专属参数)
解析 headers(包括 Authorization)
解析 cookies(如果有 -b)

构造 fetch 请求

发送请求

这中间最难的不是解析 curl 本身(一个正则就能搞定 URL 和 headers),而是处理 proxy 的问题。前端浏览器没法直接走代理。

最终方案是:解析 curl 时把 --proxy 那一行丢掉,因为前端本来就在用户的机器上跑,根本不需要代理。

顺便学到的几条打工道理

回看今天这一整天的需求变更,有些东西值得记下来:

第一,AI 不是不会干活,它只是不理解「干完了」是什么意思。

老板从头到尾都没说「实现功能就停」,他每一版都在加约束。AI 写到第三版就以为交活了,结果老板说「不是啊,我后面还要改的」。

这跟我们打工时遇到的「这个需求今晚要」很像——你以为要的是结论,他要的是过程。

第二,「简单」是相对的。

老板嘴里的简单 = 「我点一下就能用」。工程师嘴里的简单 = 「代码量少」。这两个「简单」经常是反义词。

今天最终交付的方案是:单文件 HTML + 一个 Python 小后端 + 一个 Dockerfile。单文件本身够简单,但配套的导入、持久化、刷新逻辑加进来之后,整体复杂度已经超出「半小时写完」的预期。

第三,需求变更本身不是问题,没有版本管理才是。

七版需求,如果每一版都直接覆盖上一版,最后交付的肯定是混乱的。我把每一版的关键决策都记到了仓库的 CHANGELOG.md 里:哪一版加了持久化、哪一版改成 Docker、哪一版处理 proxy——这样回溯的时候不用从代码 diff 里反推。

写在最后

今天的 Coding Plan 看板,从「一个 HTML 文件」开始,到「单文件 + Docker + 后端 + 持久化 + 自动刷新」结束。

表面上看,活儿比预期多了三倍。但打工人嘛,谁还没被甲方改过需求呢。

关键是:每一次需求变更,都要写下来;每一个部署版本,都要能回滚;每一个甲方拍脑袋的决定,都要变成可追溯的 commit message。

这样就算明天老板再来一句「这个设计不太对,我们换个思路吧」,我也不至于从零开始。

打工人的安全感,不是来自「需求一次到位」,而是来自「不管需求怎么改,我都能接住」。

明天继续。希望 Codex、MiniMax、火山方舟的额度都不要超。


作者:小六,一个在上海努力跟需求变更赛跑的普通打工人

Author:Margrop
Link:http://blog.margrop.com/post/2026-07-14-coding-plan-dashboard-seven-versions/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可