从代码审查到作品发布:一个值班排班系统的完整上链记
一、起因
我在 GitCode 上有个仓库 [lightyearssssr/scheduling-app]——一个基于 Flask 的值班排班管理系统。功能挺完整:固定 6 人班底全年轮值、9-12 月增援 2 人、贪心评分算法保证全年均衡差距 ≤ 2。但"能跑"和"没问题"是两回事,于是让 AI 架构伙伴帮忙审一遍。
二、审查:三层问题
审查结果按严重程度分了三档,这里只说结论,不贴大段代码。
🔴 安全风险
debug=True 绑定 0.0.0.0。 Flask 的 debug 模式会启用 Werkzeug 交互式调试器,一旦暴露公网,任何人触发一个异常就能在服务器上执行任意 Python 代码——等于后门。本地玩没事,部署就是灾难。
🟡 Bug / 名不副实
seed 参数是摆设。 Scheduler 存了 self.seed,但全文件没有 import random,算法是纯确定性贪心,没有任何随机成分。结果就是前端那个"🔄 重新生成"按钮点 100 次,结果一模一样。按钮是假的。
前端 XSS。 renderRestInfo 用 innerHTML 拼接人员名,而人员名来自用户输入(localStorage 或 API 参数),后端只校验非空不转义。构造一个带 <img onerror> 的名字就能注入。
🟢 工程化缺失
没有 requirements.txt、没有 .gitignore、没有测试、有死代码、schedule_cache 只增不删……一堆不影响运行但该补的整洁度问题。
三、修复:只动实质问题,工程问题留 TODO
策略是先修会出事的,工程整洁度明天再说。三个实质问题逐一改:
Fix 1:关闭 debug
# 之前
app.run(host='0.0.0.0', port=8080, debug=True)
# 之后
app.run(host='0.0.0.0', port=8080,
debug=os.environ.get('FLASK_DEBUG', '0') == '1')
默认关闭,仅本地开发时用 FLASK_DEBUG=1 环境变量显式开启。
Fix 2:让 seed 真正生效
接入 random.Random(seed),并在选人时对同分候选随机打破平局:
# __init__ 里
self.rng = random.Random(seed) if seed is not None else random.Random()
# 选人时
max_score = max(scores.values())
candidates = [p for p, sc in scores.items() if abs(sc - max_score) < 1e-9]
duty_person = self.rng.choice(candidates)
验证结果很有意思:365 天里只有 10 天会出现同分平局,所以随机性只影响 10 天的选择——但因为评分会传导到后续日期的累计计数,最终全年有 92 天的排班明细会变化。年度统计恰好相同(算法均衡性太强),但排班表确实不同了。"重新生成"终于名副其实。
Fix 3:消除 XSS
把 innerHTML 拼接改成 textContent 逐节点构建 DOM,人员名不再被当 HTML 解析。
TODO 留档
工程问题写进 TODO.md,列成 checklist 留给第二天:
- 新增
requirements.txt/.gitignore - 补自动化测试(至少断言
balance_gap <= 2) - 删死代码(
generate_month_schedule、未使用的expectedCount参数) schedule_cache加 LRU 上限- 年份选择器动态化
四、推送 GitCode
改完提交,踩了个小坑:__pycache__/*.pyc 因为没有 .gitignore 被误提交了——正好是 TODO 里那条的活体演示。从提交里剔除后干净推送:
commit 28cd213
app.py | 6 +++++-
scheduler.py | 9 ++++++++-
static/js/app.js | 15 ++++++++++++---
TODO.md | 26 ++++++++++++++++++++++++++
GitCode 用 OAuth 扫码登录,token 存本地,push 完把 remote URL 里的凭证抹掉保持干净。
五、复盘
几个值得记一笔的点:
- “能跑"不等于"没问题”。 这个项目功能完整、代码清晰,但 debug 漏洞和假按钮这种问题,不审不会自己浮出来。审查的价值就在这。
- 随机性是个有意思的放大器。 只有 10 天有平局,但传导后 92 天排班变了。确定性算法里加一点随机打破对称,效果比想象的大。
TODO 里的工程问题明天处理。今天的活儿到这。
- 点赞
- 收藏
- 关注作者
评论(0)