Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
486 commits
Select commit Hold shift + click to select a range
f9b1f1c
feat(awdp): 状态硬化——PreparingFix 过渡态 + Pending 语义 + 移除 early_check + En…
fb0sh Aug 13, 2026
c8a75ed
feat(awdp): patch stale 回收 + APPLIED-AT 资格 + practice 配置快照源
fb0sh Aug 13, 2026
a654622
feat(awdp): Competition Individual membership 校验 + admin worker UI + …
fb0sh Aug 13, 2026
ad5f78f
fix(awdp): JudgeServer pull worker 两个端到端 bug + cron seed 幂等
fb0sh Aug 13, 2026
aef101e
fix(scheduler): 启动校验只查引擎会执行的行(pending/running),failed 残留不阻断 API
fb0sh Aug 13, 2026
71dd7ea
fix(awdp): start_run 允许 Pending 进入 launch 分支——修复 Launch 400
fb0sh Aug 13, 2026
ded541d
feat(awdp): 移除 AWDPlusPractice admin judge 配置——训练默认 1h/1h/10m + Judge…
fb0sh Aug 13, 2026
93a8a3e
fix(awdp): data plane 端点更名 judge-server/flag + deploy env 漂移自愈 + 测试清理…
fb0sh Aug 13, 2026
b4c8099
feat(awdp): JudgeServer data plane 移入 80 端口——GameBox 内 curl http://ju…
fb0sh Aug 13, 2026
42212aa
feat(web): Break 页 Flag Endpoint 展示完整地址 http://judge-server/flag
fb0sh Aug 13, 2026
e1b02c9
feat(web): web 类 GameBox 的 Flag Endpoint 可点击(target=_blank)
fb0sh Aug 13, 2026
6a5926e
feat(web): 题面 Endpoint 可点击——web 类 GameBox 靶机地址新标签打开
fb0sh Aug 13, 2026
e7d023c
feat(awdp): patch 上传改 patch.tar.gz + source 包结构 src/+patch.sh 通用模板
fb0sh Aug 13, 2026
84bfe7c
chore: Cargo.lock 补充 flate2 依赖锁定
fb0sh Aug 13, 2026
6558800
feat(awdp): patch 改为解压到容器 /tmp/patch 执行 patch.sh + restart
fb0sh Aug 13, 2026
a40c653
feat(awdp): patch 失败返回并展示具体原因(脚本非 0/超时附 stderr 摘要)
fb0sh Aug 13, 2026
714ddb3
feat(awdp): 通用 patch 模板改为清空并恢复 src/ 到源码目录
fb0sh Aug 13, 2026
1ccfb86
feat(awdp): 练习模式判定与计分改版——check 失败扣 50 分、Test Check 追加 exploit、新增 ALL …
fb0sh Aug 14, 2026
8bdc321
feat(awdp): 练习实例容器命名改为 AWDPP-{user前8}-{gamebox前8}-{run前8}
fb0sh Aug 14, 2026
627db85
fix(awdp): patch 目录改为每提交唯一 /tmp/patch-{submission uuid 前8}
fb0sh Aug 14, 2026
266a557
test(awdp): 新增练习计分/ALL Check/manual exploit 集成测试
fb0sh Aug 14, 2026
c21539e
feat(web): 练习扣分展示、Test Check exploit 结果、ALL Check 按钮
fb0sh Aug 14, 2026
efa076c
chore(test): 移除 test_g 示例 flag.php——测试仅依赖 fcmc 样例 gamebox 与 awdp-judg…
fb0sh Aug 14, 2026
80d5880
feat(fcmc): gamebox 模板对齐 test_g——exploit 走 judge-server/flag、check 改 …
fb0sh Aug 14, 2026
062eb21
fix(awdp): 练习 Test Check(manual)真正执行 exploit 诊断
fb0sh Aug 14, 2026
ef7c563
refactor(web): 练习结束视图只保留 Train Again——移除 Final Score/Break Results/Sc…
fb0sh Aug 14, 2026
56e2084
refactor(web): 练习结束的 Train Again 无边框居中
fb0sh Aug 14, 2026
bf3562b
refactor(web): 练习 GameBox 卡片去掉题目名标题——页面顶部已显示,Endpoints 框内不重复
fb0sh Aug 14, 2026
467142d
refactor(web): 练习 GameBox 卡片标题改为固定「Gamebox Instance」
fb0sh Aug 14, 2026
6bd1bfe
chore(examples): 样例目录改名 test_c→test-c、test_g→test-g,同步 fcmc 文档引用
fb0sh Aug 14, 2026
b8d178e
feat(awdp): 练习 Fix 阶段 /flag 返回 flag{proof-of-exploit}——exploit 真实判定
fb0sh Aug 14, 2026
2b7f01c
feat(awdp): AWDP 赛事积分榜——scoreboard 服务 + player/admin scores API
fb0sh Aug 14, 2026
049ca45
feat(web): AWDP 赛事积分榜页 + 个人/团队参赛流程分流
fb0sh Aug 14, 2026
cc3ce6c
feat(web): AWDP admin Teams/WriteUps/Announcements 页 + ops 积分榜
fb0sh Aug 14, 2026
fddadf3
feat(web): AWDP player Announcement 页 + tab
fb0sh Aug 14, 2026
18c6520
chore: 模板注释对齐 judge-server 语义 + fmt 积分榜代码
fb0sh Aug 14, 2026
78afd88
feat(awdp): 赛事开始自动为全部队伍/用户启动全部 GameBox 实例 + Event 时间修改同步
fb0sh Aug 14, 2026
e1e34f2
feat(web): AWDP 赛事顶部进度条(同 Jeopardy 位置,Break/Fix 分段 + 竖线)
fb0sh Aug 14, 2026
bc9847f
feat(web): AWDP 比赛移除 Overview/GameBoxes tab——所有 gamebox 共享顶部进度条
fb0sh Aug 14, 2026
69db558
feat(web): 恢复 AWDP 赛事 Event 的 Overview/GameBoxes tab——顶部进度条仍保留
fb0sh Aug 14, 2026
3cb0485
feat(web): AWDP 比赛 GameBoxes 精简——去掉顶部状态卡片与 Start/Stop,fix 仅 Test Chec…
fb0sh Aug 14, 2026
84877b8
feat(awdp): 比赛 Reset 次数限制——每人/队每 GameBox 3 次、仅 Fix 阶段
fb0sh Aug 14, 2026
0249513
feat(web): Reset 按钮显示剩余次数——比赛仅 Fix 可用、3 次上限
fb0sh Aug 14, 2026
6738953
feat(web): AWDP 赛事页精简 + 进度条显示阶段与常显竖线
fb0sh Aug 14, 2026
f0e8955
feat(awdp): 赛事参数默认——break/fix 各半、10 分钟一轮、break 分数=Fix 满分×0.6
fb0sh Aug 14, 2026
683cd51
fix(awdp): 比赛实例加入 data 网络——SSRF judge-server/flag 在比赛也可用
fb0sh Aug 14, 2026
dbd7aaf
feat(awdp): tick 阶段推进推 SSE + admin 改配置/事件时间即时推送
fb0sh Aug 14, 2026
0d98d8c
feat(web): 进度条倒计时到点立即重新获取 + 阶段名提示 + SSE 节流
fb0sh Aug 14, 2026
5794bce
feat(awdp): Test Check 同步执行不排队——HTTP 请求内直接跑 healthcheck + judge
fb0sh Aug 14, 2026
d1961b4
fix(web): Configure Break Score 动态计算失效——表单重置/保存后恢复联动
fb0sh Aug 14, 2026
b20aea1
fix(awdp): overview/admin 展示 ended/preparing_fix 阶段——已结束赛事不再误报 pending
fb0sh Aug 15, 2026
b798830
fix(web): AWDP 赛事进度条时间显示——pending 按赛事状态派生文案 + 卡死轮询上限
fb0sh Aug 15, 2026
c7e4cf2
feat(web): AWDP Event GameBoxes 页去掉 Official History/Final Score——由 R…
fb0sh Aug 15, 2026
7e1b24c
feat(awdp): Scoreboard 明细矩阵端点——Break/Fix 每题状态 + 赛制区分 + detach 题在榜
fb0sh Aug 15, 2026
48d279d
feat(web): Scoreboard 双视图(User/Gamebox)——题目视角 Break/Fix 成功主体数
fb0sh Aug 15, 2026
428788d
feat(web): 新建赛事 RULES 预填正规 Markdown 模板
fb0sh Aug 15, 2026
99f0a47
feat(awdp): AWDP 趋势/大屏后端 + Configure Fix 由总时长推导
fb0sh Aug 15, 2026
48d01f1
feat(web): AWDP 趋势页 + 管理端 Data Present + Configure 动态 Timeline
fb0sh Aug 15, 2026
fa450ef
chore: bump api v0.3.3 / web v0.2.8
fb0sh Aug 15, 2026
529c4f6
feat(awdp): 每赛事独立 docker 网络 + 赛事专属 JudgeServer
fb0sh Aug 16, 2026
1c00257
fix(awdp): manual Test Check 同步独占 + 终态清 lease(BUG5);竞赛 Fix exploit 诊断…
fb0sh Aug 16, 2026
5b1f471
fix(awdp): 比赛中新挂 gamebox 自动启动实例(BUG1)
fb0sh Aug 16, 2026
0745b87
feat(awdp): Configure V3 编辑模型 + 可视化时间轴(BUG2)
fb0sh Aug 16, 2026
9c3a45e
feat(web): 管理端 Scoreboard 独立 tab(BUG3)
fb0sh Aug 16, 2026
5f2174b
fix(web): AWDP Testcheck/ALL Check 文案优化(BUG6)
fb0sh Aug 16, 2026
fafd27a
test(awdp): 修复 awdp_scoreboard 既有失效用例
fb0sh Aug 16, 2026
813aa0b
fix(awdp): 练习 check 失败扣分从 -50 改为 -100
fb0sh Aug 26, 2026
984c31f
refactor(awd): add competition config foundation
fb0sh Aug 26, 2026
b8a6c8f
refactor(awd): separate hardening from attack rounds
fb0sh Aug 26, 2026
ebf0494
fix(awd): recover interrupted round transitions
fb0sh Aug 26, 2026
71a404f
refactor(awd): move judge execution to pull leases
fb0sh Aug 26, 2026
c6e4843
fix(awd): run judgeserver as pull worker
fb0sh Aug 26, 2026
213bf92
test(awd): verify judge pull protocol
fb0sh Aug 26, 2026
1ade22b
fix(awd): finalize judge worker ownership handling
fb0sh Aug 27, 2026
6a57725
refactor(awd): finalize score semantics
fb0sh Aug 27, 2026
268c91d
fix(awd): enforce judge score idempotency
fb0sh Aug 27, 2026
0df460b
refactor(awd): enforce reset ban and network rules
fb0sh Aug 27, 2026
1cad40c
fix(awd): harden ban destination blocking and judge scoring
fb0sh Aug 27, 2026
6502826
test(awd): verify reset recovery and network freeze
fb0sh Aug 27, 2026
cb615c8
test(awd): verify network failure timer freeze
fb0sh Aug 27, 2026
b6f7b1c
refactor(awd): finalize competition settlement
fb0sh Aug 27, 2026
5226166
fix(awd): enforce final settlement invariants
fb0sh Aug 27, 2026
b447dbe
fix(awd): enforce finished network lockdown
fb0sh Aug 27, 2026
447dd08
fix(awd): close final judge lifecycle triggers
fb0sh Aug 27, 2026
c5e1d4a
test(awd): close core backend acceptance
fb0sh Aug 27, 2026
741ee6a
test(awd): verify final judge handler wiring
fb0sh Aug 27, 2026
1e420a3
docs(awd): document http acceptance test limitation
fb0sh Aug 27, 2026
e7925ee
fix(awd): authenticate browser sse transport
fb0sh Aug 28, 2026
d7c60d6
fix(awd): finalize sse auth lifecycle
fb0sh Aug 28, 2026
74872a4
fix(awd): separate player and admin sse auth
fb0sh Aug 28, 2026
1f5f465
feat(awd): complete admin and player ui
fb0sh Aug 28, 2026
69ec05f
fix(awd): close final settlement ui semantics
fb0sh Aug 28, 2026
05e0f2e
chore(awd): add core regression results to phase 8.1 report
fb0sh Aug 28, 2026
6e0fed6
test(awd): validate real deployment e2e — environment audit, infrastr…
fb0sh Aug 28, 2026
26ab9c4
fix(awd): 真实部署端到端集成修复(claim 响应信封 / TARGET_IP 注入 / 回程放行等)
fb0sh Aug 31, 2026
a9ff7b2
fix(awd): close real deployment integration
fb0sh Sep 1, 2026
0f56944
test(awd): validate browser deployment e2e
fb0sh Sep 1, 2026
e817a64
feat(deploy): add host initialization
fb0sh Sep 1, 2026
3c06400
chore(deploy): document deployment architecture
fb0sh Sep 1, 2026
e904a45
test(awd): assert no production network harness workarounds
fb0sh Sep 1, 2026
6a16954
fix(awd): make sse reconnect resilient
fb0sh Sep 1, 2026
1a2d091
fix(awd): 自动分配避让宿主 Docker 网络与路由占用
fb0sh Sep 1, 2026
6736833
fix(awd): 部署失败释放网络锁,支持官方恢复路径
fb0sh Sep 1, 2026
050de67
chore(awd): seal production e2e validation
fb0sh Sep 1, 2026
c667b56
docs(deploy): 定稿 Phase 10 部署设计(RustFS 必需、postgres 存储、nginx host 网络、--…
fb0sh Sep 1, 2026
08b5a9c
feat(deploy): 可移植发布产物构建与生产部署基础
fb0sh Sep 1, 2026
c1acda9
fix(deploy): init.sh 归一化 /home/floatctf 顶层属主为 root:floatctf 750(修孤儿 u…
fb0sh Sep 1, 2026
9de56dc
fix(deploy): 容器数据/日志目录归对应容器 uid(rustfs 10001 / postgres 999),修 bind-m…
fb0sh Sep 1, 2026
5c97822
fix(deploy): config/ 目录归 root:floatctf 750(floatctf 组可遍历读取密钥文件),修 API…
fb0sh Sep 1, 2026
cfd45ad
fix(deploy): precheck 放行本平台 infra 容器占用的端口(重部署场景)
fb0sh Sep 1, 2026
3bdaf6c
fix(deploy): precheck 识别 host 网络 nginx 容器端口(仅 HTTP/HTTPS 放行),修 nginx …
fb0sh Sep 1, 2026
9300d74
fix(deploy): postgres 数据属主非 999 时停容器修正(修首次部署遗留属主导致 FATAL Permission d…
fb0sh Sep 1, 2026
0a80d49
fix(deploy): web 目录就地覆盖保留 inode(修 bind-mount nginx 读空目录 403)
fb0sh Sep 1, 2026
3002458
fix(deploy): precheck 放行 floatctf-api.service 占用的 API 端口(重部署场景)
fb0sh Sep 1, 2026
21af491
docs(deploy): 主机可移植性指南 + 极简部署起步文档;归档 scripts/install.sh 至 legacy
fb0sh Sep 1, 2026
42b775e
docs(deploy): Phase 10 部署实现报告(PASS,真实主机验收矩阵全过)
fb0sh Sep 1, 2026
6a1dbb0
chore: 忽略 .mnemon 运行时记忆目录;删除 Phase 9 遗留测试产物
fb0sh Sep 1, 2026
78b22ef
feat(deploy): 新增 clean 与 uninstall 生命周期脚本
fb0sh Sep 1, 2026
f6508d4
feat(deploy): deploy 每次成功部署安装独立卸载脚本到 /home/floatctf/uninstall.sh
fb0sh Sep 1, 2026
5207a79
docs: 新增权威安装运维指南 INSTALL.md 并更新 README
fb0sh Sep 1, 2026
eef0823
docs(report): 安装生命周期实现报告(BLOCKED:live 验收需授权 root 主机)
fb0sh Sep 1, 2026
eef5c01
feat(publish): fcmc 升版 1.2.0 并准备 crates.io 发布(floatctf 服务端补全发布元数据 + 修…
fb0sh Sep 1, 2026
ce65d3f
docs: crates.io 发布指南(fcmc/floatctf 发布顺序与命令)
fb0sh Sep 1, 2026
e047bdc
docs: 更新 Star History 徽章链接为 StarHistory SVG 图表
fb0sh Sep 1, 2026
6c1de2c
chore(config): 开发环境 AWD network_runtime 由 noop 改为 host
fb0sh Sep 1, 2026
4536216
fix(uninstall): --purge 静默退出零输出(parse_args 递归 + set -e 叠加致 exit 1)
fb0sh Sep 2, 2026
b42918c
fix(uninstall): purge 无法删除用户与家目录(sysctl_modules 尾部 && ok 触发 set -e)
fb0sh Sep 2, 2026
be89adf
docs: README/INSTALL 同步 crates.io 发布渠道
fb0sh Sep 2, 2026
3c698cb
chore: 清理无用与旧文件(pyc 缓存 / Phase9 e2e 遗留 / 过时文档 / chore 散落历史稿)
fb0sh Sep 3, 2026
582e21f
chore: 删除 legacy 脚本(scripts/legacy/install.sh + init.release.sh)
fb0sh Sep 3, 2026
065f97b
chore: 删除重复的部署起步文档 docs/deployment/getting-started.md
fb0sh Sep 3, 2026
980cc23
feat(install): 新增 install.sh 一键安装(合并 init+deploy,从 GitHub 下载自包含 tarball)
fb0sh Sep 3, 2026
7665db9
feat(install): 新增 --init-only 选项(只初始化,跳过下载与部署,供开发环境用)
fb0sh Sep 3, 2026
1d1bb87
refactor(install): 参数 --init-only 改名为 --skip-download
fb0sh Sep 3, 2026
be54ae8
fix(install): --skip-download 仅跳过下载,部署照走(改用本地 release/floatctf-* 产物)
fb0sh Sep 3, 2026
95d47be
fix(install): 产物与部署改用 compose.dev.yml + compose.prod.yml 两个文件
fb0sh Sep 3, 2026
e2509f0
refactor(install): install.sh 单文件自包含 + 3 产物下载 + FLOATCTF_HOME + 仅全新安装
fb0sh Sep 3, 2026
1fd60f5
refactor(release): 数据库初始化产物改名 migrate.sql → merged.sql
fb0sh Sep 3, 2026
6986fae
refactor(install): --skip-download 语义改为跳过下载与三产物装配,其余部署照走
fb0sh Sep 3, 2026
9cbee25
feat(install): 新增 --develop 开发模式(源码目录 + dev compose,三产物不下载)
fb0sh Sep 3, 2026
2364edb
fix(install): --develop 复用完整主机初始化(含 nftables/WireGuard,host 网络)
fb0sh Sep 3, 2026
ff565cf
docs: 新增 DEVELOPMENT.md 开发指南 + 修正 INSTALL/README 过时开发说明
fb0sh Sep 4, 2026
5fb2183
docs: 厘清 install(一行流下载)与 develop(clone 后 --develop)两种场景
fb0sh Sep 4, 2026
f80fc26
refactor(install): 只写文件+建服务,绝不自行启动(DB 改首启自动 initdb)
fb0sh Sep 4, 2026
a622181
docs: 同步 install.sh 不启动服务与 DB 自动 initdb 语义
fb0sh Sep 4, 2026
676b6b3
refactor(deploy): migrate reverse proxy from nginx to caddy
fb0sh Sep 7, 2026
7965d4a
feat: harden event runtime and deployment
fb0sh Sep 13, 2026
11f7dfb
fix(awdp): 练习网络网关按子网校验,修复生产环境练习判题建网失败
fb0sh Sep 14, 2026
febdcad
fix(deploy): 生产 API 镜像补 python3-minimal 依赖
fb0sh Sep 14, 2026
b4b444c
fix(awd): 管理端靶机重置主体分列,修复外键冲突 500
fb0sh Sep 14, 2026
02a1aa7
feat(fcmc): 内容契约对齐 floatctf-content/scripts/content.py
fb0sh Sep 16, 2026
92b5054
feat(api): 题目包支持静态/附件题,导入不再强制 src/Dockerfile
fb0sh Sep 16, 2026
6a213e4
refactor(api): GameBox 元数据复用统一内容契约
fb0sh Sep 16, 2026
1d0bd64
fix(api): 内网 HTTP 客户端忽略宿主代理,健康检查不再被劫持
fb0sh Sep 16, 2026
35f372c
feat(web): 静态/附件题按无容器处理
fb0sh Sep 16, 2026
f4c4633
test(api): AWDP 用例改用运行时解析的本地镜像 ID
fb0sh Sep 16, 2026
eceac0c
chore(examples): test-g 增加 /flag.php 并对齐文件权限
fb0sh Sep 16, 2026
abd8c48
fix(api): 迁移脚本使用真实解释器,新增镜像引用注释迁移
fb0sh Sep 16, 2026
73342bf
chore(scripts): e2e 脚本动态统计迁移数并对齐新包格式
fb0sh Sep 16, 2026
a81bd3f
refactor(prod): 生产部署模板内嵌 install.sh,移除 infra/compose|systemd 副本
fb0sh Sep 16, 2026
624d166
refactor(web): AWD 网络配置界面重做(中文分组、统一保存、校验前置)
fb0sh Oct 4, 2026
4fcd402
test(web): 补充 AWD 网络配置页面级与校验用例
fb0sh Oct 4, 2026
7f76185
test(api): 补充 AWD flag 提交边界回归用例
fb0sh Oct 4, 2026
b953297
chore(scripts): AWD 业务 E2E 支持 hardening/reset 边界场景
fb0sh Oct 4, 2026
dd041e0
docs(agents): 补充 AWD 真实宿主 E2E 入口与场景说明
fb0sh Oct 4, 2026
187d9f2
fix(web): 登录 401 时不再因空响应抛 TypeError 崩溃
fb0sh Oct 4, 2026
98afed0
fix(api): 宿主 nftables 状态改经 helper 观测,消除生产误报
fb0sh Oct 4, 2026
0ea6d6a
fix(api): wireguard_public_endpoint 支持显式清空
fb0sh Oct 4, 2026
997c42b
fix(api): 删除赛事时拆除 AWD 运行时资源
fb0sh Oct 4, 2026
59cd8ea
feat(web): 运维页展示预检失败原因(errors/notes)
fb0sh Oct 4, 2026
8163227
fix(web): 通用表单提交成功后关闭对话框
fb0sh Oct 4, 2026
b5a2a9b
fix(web): 赛事网段必须 /16 或更大,前后端一致拦截
fb0sh Oct 4, 2026
c0c9473
fix(api): 归档赛事时释放平台网段并自愈历史泄漏
fb0sh Oct 5, 2026
0b4ccf4
fix(api): 重复提交 flag 不再被事务边界吞成 500
fb0sh Oct 5, 2026
f8154a2
fix(api): 错误响应不再泄漏数据库细节并去掉英文前缀
fb0sh Oct 5, 2026
e8b7f00
fix(api): 重名建队与空标题赛事改为业务错误,校验文案中文化
fb0sh Oct 5, 2026
4f9067b
fix(api): AWDP 判题容器名冲突时退避重试而非直接放弃
fb0sh Oct 5, 2026
badaaf7
fix(web): 接口错误统一为中文文案,登录页错误解释与无障碍
fb0sh Oct 5, 2026
ce2a596
fix(web): 通用表单对话框中文标签、必填拦截与失败保留输入
fb0sh Oct 5, 2026
34a9288
fix(web): 未开赛的 AWD 赛事不再显示「Hardening」
fb0sh Oct 5, 2026
1e7b6b0
fix(web): AWD 配置页、运维页与玩家端文案中文化
fb0sh Oct 5, 2026
0fefcd0
fix(web): 手动分配网段校验示例改为合法 /16
fb0sh Oct 5, 2026
8d3a868
fix(api): 账号创建补校验,唯一冲突映射为业务错误
fb0sh Oct 5, 2026
04219cc
fix(infra): API 镜像安装完整 python3(判题脚本依赖标准库)
fb0sh Oct 5, 2026
f22a285
fix(web): 新增用户对话框中文标签与必填校验
fb0sh Oct 5, 2026
7119748
test(api): flag 提交边界断言跟随中文化文案
fb0sh Oct 5, 2026
16fd99d
chore(api): cargo fmt
fb0sh Oct 5, 2026
1b40055
fix(api): 漏传 event_id 的竞赛提交不再被当成练习记 0 分
fb0sh Oct 5, 2026
606c04e
fix(api): 重复加入赛事改为幂等,修正加入/退出文案
fb0sh Oct 5, 2026
9362176
fix(web): 玩家端未加入/未找到/提交成功文案中文化
fb0sh Oct 5, 2026
19655ab
chore(api): cargo fmt
fb0sh Oct 5, 2026
1c3f4bd
fix: 练习提交防御按 purpose 判定 + 修复结果不再误报已修复
fb0sh Oct 5, 2026
8d88931
docs: 全量测试矩阵与修复清单(练习/管理/比赛 + 边界/并发/压力)
fb0sh Oct 5, 2026
6fe9526
fix: Check 可修复题目构建状态;其余管理端对话框标签中文化
fb0sh Oct 5, 2026
afa0ce3
fix(api): 定时任务创建/更新补字段校验
fb0sh Oct 5, 2026
56ddd63
docs: 补充第 3 轮实测(F28/F36/F37 与公告/武器/题目集 CRUD)
fb0sh Oct 5, 2026
7fd3d99
docs: 补充 AWDP 竞赛全生命周期实测(F38/F40 记录)
fb0sh Oct 5, 2026
adfccb3
fix(web): AWDP 配置/运维/工作台文案中文化
fb0sh Oct 5, 2026
3df82aa
docs: F40 定论(按回合设计,非缺陷)、F41 排除、测试残留说明
fb0sh Oct 5, 2026
b1fc1e5
fix: 通用增删改提示与 SQL 控制台文案中文化
fb0sh Oct 5, 2026
64563d5
fix(awdp): 判题脚本改到赛事数据面执行(可用配置开关回退)
fb0sh Oct 5, 2026
c1cb812
docs: F24 结论(非缺陷)、F26/F44 修复与 10 连测方法论/残留量化
fb0sh Oct 5, 2026
e68579a
docs: 10 连测 10/10 PASS、浏览器 E2E 10/10、残留量化与 teardown 建议
fb0sh Oct 5, 2026
a5b00db
fix: 边界测试发现的提取器/唯一冲突/端点校验缺陷
fb0sh Oct 5, 2026
184051a
fix(awdp): 分数上限与饱和派生,避免启动物化时 i64 溢出
fb0sh Oct 5, 2026
d3f1d37
docs: 边界专项测试矩阵(AWD/AWDP/文本/时间/分页/权限/网络)与 F45–F48 修复记录
fb0sh Oct 5, 2026
1594c97
test(awdp): 断言改匹配中文校验文案,补齐配置校验中文化
fb0sh Oct 5, 2026
e2ac11e
fix: 分页边界——page=0 夹到第 1 页,避免第 1 页点「上一页」列表变空
fb0sh Oct 5, 2026
fb73871
fix(api): 错误响应一致性——未匹配路由与未认证统一走 JSON 信封
fb0sh Oct 5, 2026
1a99599
docs: 边界专项第 2 轮(F49 分页、F50/F51 响应一致性、禁用态与容量观察)
fb0sh Oct 5, 2026
a11973a
fix: 赛事文本长度上限(F52)
fb0sh Oct 5, 2026
c9ef5fd
docs: 边界专项第 3 轮(F52 赛事文本上限与验证结果)
fb0sh Oct 5, 2026
ef39a4b
fix: 选手/管理端状态与查找类错误文案中文化
fb0sh Oct 5, 2026
0e0695e
docs: 边界专项第 3 轮续(状态/查找类文案中文化记录)
fb0sh Oct 5, 2026
bba5942
fix: 补齐查找类错误文案的内联捕获变体(57 处)
fb0sh Oct 5, 2026
b92b404
fix(awd): 「awd event {id}」查找失败文案改为中文且语义完整
fb0sh Oct 5, 2026
62cd456
feat(web): 管理端表头与通用按钮中文化(第一批)
fb0sh Oct 5, 2026
f58f896
fix(web): 补齐 JSX 单行文本的英文按钮(导入/检查/扫描/新增等)
fb0sh Oct 5, 2026
a0d6f0e
test(web): 同步按钮中文化后的 role 断言(Submit→提交)
fb0sh Oct 5, 2026
0e46436
feat(web): 管理端表头中文化(第二批,72 处)
fb0sh Oct 5, 2026
f73cc0e
feat(web): 管理端表头中文化(第三批)
fb0sh Oct 5, 2026
2e10f16
feat(web): 管理端表头中文化(第四批,收尾)
fb0sh Oct 5, 2026
f4c5ead
fix: 未参赛者启动实例的英文错误文案(F53)+ 稳定性验证报告
fb0sh Oct 5, 2026
6329464
fix(jeopardy): 实例存活性对账(F54)+ 修复失效的清理候选查询
fb0sh Oct 5, 2026
4e7dcd6
docs: F54 已修并验证(含更深根因:清理候选查询失效)
fb0sh Oct 5, 2026
a692c19
docs: 稳定性第 10 轮——真实 flag 写路径(6320 次零失败、无重复计分)、10 分钟 soak 无慢泄漏、F54 二次验证
fb0sh Oct 5, 2026
174f1db
docs: 稳定性第 11 轮——尖峰与真实容量(702 RPS,此前 400 为客户端瓶颈)、清理脚本误删生产 API 的事故与四条护栏
fb0sh Oct 5, 2026
ea2042a
docs: 稳定性第 12 轮——FD 无泄漏(72→峰值123→74);AWD 多回合测试被 F55(归档赛事不释放子网,致 deplo…
fb0sh Oct 5, 2026
611bf44
fix(awd): 部署冲突检查忽略已归档赛事,消除「分配成功但部署 409」(F55)
fb0sh Oct 5, 2026
0250159
docs: 稳定性第 13 轮——AWD 多回合负载通过(6 回合准点、475 RPS、零 5xx)、F55 已验证、F56 撤项、F57…
fb0sh Oct 5, 2026
b9f6f13
docs: 稳定性第 14 轮——AWD 攻击/计分负载的可执行手册(接口、顺序、幂等核验点、清理步骤)
fb0sh Oct 5, 2026
22fb5d0
docs: 稳定性第 15 轮——AWD 并发攻击计分幂等(10 并发=1 次计分)、FlagServer :8080 端点、三层护栏实测
fb0sh Oct 5, 2026
51460bf
fix(awd): precheck 返回具体失败原因(F57)
fb0sh Oct 5, 2026
6fcc8d6
docs: 稳定性第 16 轮——同时开赛 5/5、日志零 5xx、F57 已修并验证(precheck 返回具体失败项)
fb0sh Oct 5, 2026
cda0585
docs: 稳定性第 17 轮——结算边界并发(结束前 200/400 正常、结束后提交干净拒绝+轮询仍 200、solves=10 唯一…
fb0sh Oct 5, 2026
deec3fa
chore(stability): 处理 6 项遗留——Redis maxmemory、API nofile、英文文案中文化、清理任务日志…
fb0sh Oct 5, 2026
558cd4c
fix(jeopardy): 回收孤儿实例容器,删除赛事不再泄漏(F58)
fb0sh Oct 5, 2026
e61ab78
docs: 文档与代码对齐(AWD 改名、AppConfig 字段、请求路径、watch 语义)
fb0sh Oct 5, 2026
986050d
fix(ci): 修复三条失效/误报的安全守卫,并把 CI 覆盖到 awd 分支
fb0sh Oct 5, 2026
5b5689b
fix(api): 选手侧实例接口不再返回真实 flag
fb0sh Oct 5, 2026
5af4b64
fix(api): 未发布的赛事题目不再可启动与计分
fb0sh Oct 5, 2026
255959d
fix(api): 计分榜「已解出」与分数口径不一致
fb0sh Oct 6, 2026
b218aa7
fix(awdp): 修 Test/ALL Check 判定恒失败与卡死(ACL conntrack / 锁等待 / NO_PATCH 扣…
fb0sh Oct 6, 2026
7073923
fix(awd,web): 补记分榜鉴权、去掉 AWD 路由双前缀影子端点、前端补统一路由守卫
fb0sh Oct 6, 2026
8af651b
chore(ci): 门禁补 Web 类型检查、修好永久空转的 Flag/Judge smoke、PR 上强制编译集成测试
fb0sh Oct 6, 2026
f03dd5d
fix(web): AWD 事件流失效列表与页面实际 query key 对齐(抽共享常量防漂移)
fb0sh Oct 6, 2026
33ed689
fix(api,db): 删掉两个从未被读取的配置项、补齐 5 个从未 seed 的设置键、空操作任务如实化、DROP 孤儿枚举
fb0sh Oct 6, 2026
69661eb
docs,fix(install): 记录主密钥三用/调度器反直觉点/同名列陷阱,安装器占位地址改为快速失败
fb0sh Oct 6, 2026
e9731c1
feat(auth): 拆开 jwt_secret / awd_root_key / internal_token_key,并让判题容器随…
fb0sh Oct 6, 2026
8f8fbbb
chore(release): 版本号提升到 1.0.0(api + web)
fb0sh Oct 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
94 changes: 86 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,67 @@ name: CI

on:
push:
branches: [master, main]
branches: [awd, main, master]
pull_request:
branches: [master, main]
branches: [awd, main, master]
workflow_dispatch:

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

# 三层分层(CI-fast / CI-docker / CI-host-network,见下):
# CI-fast(PR 必跑) —— 单测 + mock + 架构/安全 grep
# CI-docker(PR 或 on-demand)—— Docker E2E(Flag/Judge smoke + 场景 A/B/C/G/H)
# CI-host-network(手动触发)—— root + nftables/WG 系统级场景 D/E/F/I
jobs:
rust:
name: Rust checks
fast-rust:
name: CI-fast · Rust unit + security grep
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --all
# 注意:`cargo fmt --all` 是「写入模式」,即使有格式违规也退出 0(只是静默改写文件),
# 因此它不是门禁;必须用 `-- --check` 才会在违规时非零退出。
- run: cargo fmt --all -- --check
- run: cargo clippy --workspace --all-targets --all-features
- run: cargo test --workspace
- run: cargo test --workspace --lib
# 集成测试(apps/api/tests/ 下 44 个独立 crate target)不在 `--lib` 范围内,它们只在
# CI-docker 任务里真正执行。这里强制它们至少**编译通过**:PR 全绿不该掩盖「共享
# helper / 契约目录改坏导致集成测试编译失败」这类问题。
- run: cargo test --workspace --tests --no-run
- name: Security architecture grep (P5-12)
run: |
# 两个坑,都曾让守卫失真:
# 1) grep 对不存在的路径返回 2,直接放进 `if` 会「静默放行」→ 先断言路径存在;
# 2) 注释里「提到」禁止项也会命中 → 只检查非注释行,并限定 *.rs
# (apps/api/src/sql/ 下是冻结的 migrations,不该被这些守卫约束)。
for p in apps/api/src/bootstrap apps/api/src apps/api/src/modules/event/awd apps/api/src/modules/event/awdp; do
[ -d "$p" ] || { echo "FAIL: $p missing (path drifted; guard would silently pass)"; exit 1; }
done
# 过滤掉 Rust 注释行:`//`、`/*`、块注释续行 `* `、结束行 `*/`。
# 注意用 `\*[[:space:]]` 而非裸 `\*`,否则会误滤以解引用开头的真实代码行(`*ptr = ..`)。
code_only() { grep -vE ':[0-9]+:[[:space:]]*(//|/\*|\*[[:space:]]|\*/)'; }
if grep -rn --include='*.rs' 'vec!\[0u8; 32\]' apps/api/src/bootstrap | code_only; then
echo "FAIL: zero-key fallback"; exit 1
fi
if grep -rn --include='*.rs' 'nft flush ruleset' apps/api/src | code_only; then
echo "FAIL: nft flush ruleset forbidden"; exit 1
fi
for d in apps/api/src/modules/event/awd apps/api/src/modules/event/awdp; do
if grep -rn --include='*.rs' 'sh -c' "$d" | code_only; then
echo "FAIL: shell concat forbidden in $d"; exit 1
fi
done
echo "security greps OK"

web:
name: Web checks
fast-web:
name: CI-fast · Web checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -44,3 +79,46 @@ jobs:
- run: pnpm --filter @floatctf/web lint
- run: pnpm --filter @floatctf/web test
- run: pnpm --filter @floatctf/web build

docker-e2e:
name: CI-docker · AWD infra smoke (on-demand)
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'docker-e2e')
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: floatctf_db
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# 这里才是集成测试(apps/api/tests/)真正执行的作业:无 live API 时它们自行 soft-skip,
# 需要行为级验证时在 PR 上打 `docker-e2e` 标签或手动 dispatch。
- run: cargo test --workspace
- name: Flag/Judge smoke(真构建 bookworm 二进制 + 起容器 + /health)
run: ./apps/api/scripts/e2e_flag_judge.sh
env:
RUN_DOCKER_TESTS: "1"

host-network:
name: CI-host-network · nftables/WG scenarios (nightly)
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: nftables prototype gate (P1-0, needs CAP_NET_ADMIN)
run: sudo -E apps/api/scripts/nft_prototype.sh
- name: cargo unit (host)
run: cargo test --workspace
81 changes: 64 additions & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ permissions:
contents: write

jobs:
web:
name: Build web release
runs-on: ubuntu-latest
release:
name: Build release artifacts
# API runtime image 固定 ubuntu:24.04;构建机同版可避免 release ELF 引用更新 glibc。
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

# ── 前端 ──
- uses: pnpm/action-setup@v4
with:
version: 11.20.0
Expand All @@ -25,22 +28,66 @@ jobs:
cache-dependency-path: pnpm-lock.yaml
- run: pnpm install --frozen-lockfile
- run: pnpm --filter @floatctf/web build
- run: tar -czf web-dist.tar.gz -C apps/web/dist .
- uses: softprops/action-gh-release@v2
with:
files: web-dist.tar.gz
generate_release_notes: true

rust:
name: Build Rust release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ── 后端(全 workspace 二进制)──
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --workspace --release
- run: tar -czf rust-binaries.tar.gz -C target/release floatctf fcmc floatctf-migration awd_flagserver awd_judgeserver
- uses: softprops/action-gh-release@v2
# Release 只构建真正发布的 API + host helper 二进制。
# 不构建 tests / benches / examples,也不为未发布的 workspace bin 产生本地 artifact。
- run: cargo build --locked --release -p floatctf -p floatctf-helper --bins

# ── 发布 4 个产物(供 install.sh 下载部署)──
# 1. floatctf API 二进制(installer 以此本地构建生产容器 image)
# 2. floatctf-helper 宿主控制面二进制
# 3. web-dist.tar.gz 前端静态产物
# 4. merged.sql 单个 SQL(fresh-DB bootstrap)
- name: Assemble release artifacts
shell: bash
run: |
set -euo pipefail

# 1) API 二进制
install -m 0755 target/release/floatctf floatctf

# 2) 宿主控制面
install -m 0755 target/release/floatctf-helper floatctf-helper

# 3) 前端静态产物
tar -czf web-dist.tar.gz -C apps/web/dist .

# 4) merged.sql(确定性 fresh-DB bootstrap)
bash apps/api/src/sql/migrate.sh make
install -m 0644 apps/api/src/sql/merged.sql merged.sql

echo "release artifacts:"
ls -la floatctf floatctf-helper web-dist.tar.gz merged.sql

- name: Verify production API image
shell: bash
run: |
set -euo pipefail
rm -rf .release-api-image
mkdir .release-api-image
install -m 0755 floatctf .release-api-image/floatctf
version="${GITHUB_REF_NAME#v}"
docker build \
--build-arg "FLOATCTF_VERSION=${version:-ci}" \
-f infra/docker/api/Dockerfile \
-t floatctf/api:release-test \
.release-api-image
test "$(docker image inspect -f '{{.Config.User}}' floatctf/api:release-test)" = "65532:65532"
docker run --rm --entrypoint sh floatctf/api:release-test -c '
set -eu
ldd /usr/local/bin/floatctf | tee /tmp/ldd.txt
! grep -q "not found" /tmp/ldd.txt
'

- name: Upload release artifacts
uses: softprops/action-gh-release@v2
with:
files: rust-binaries.tar.gz
files: |
floatctf
floatctf-helper
web-dist.tar.gz
merged.sql
generate_release_notes: true
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ dist/
/app
/tmp
/chore
/.mnemon
/HANDOFF.md
/var
/.codegraph/
# migrate.sh 的 flock 锁文件(临时)
apps/api/src/sql/.migrate.lock
apps/api/src/sql/merged.sql
/examples/*.zip
__pycache__/
release/
52 changes: 35 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,59 @@

基于 Rust(Actix Web + SeaORM + PostgreSQL + RustFS)与 React 的 CTF 实训/竞赛平台(Jeopardy + AWD 双赛制),monorepo 结构:`apps/api`(后端)、`apps/web`(前端)、`crates/`(共享与独立服务)。

## HANDOFF.md(会话交接记忆)

若项目根目录存在 `HANDOFF.md`,说明上一会话/开发者留下了交接记忆:**先完整读取并记住其中的内容(上下文、决策、未完成事项、约束),再开始任何任务**;工作过程中若有新增的关键决策/进展,也及时同步写回该文件,供下次会话延续。该文件是开发者私有的会话记忆,已被 gitignore,不会提交共享。

## 必读文档

| 文档 | 用途 |
|------|------|
| [docs/agents/ARCHITECTURE.md](docs/agents/ARCHITECTURE.md) | 架构速览:模块分层、关键类型、配置体系、数据流 |
| [docs/agents/ADD-FEATURE.md](docs/agents/ADD-FEATURE.md) | **开发新功能**:8 步流程 + 测试清单 |
| [docs/agents/FIX-BUG.md](docs/agents/FIX-BUG.md) | **修 bug**:复现/定位/根因/最小修复/回归 |
| [docs/agents/DATABASE.md](docs/agents/DATABASE.md) | **改数据库**:迁移 → 应用 → 实体/类型再生成 |
| [docs/agents/DATABASE.md](docs/agents/DATABASE.md) | **改数据库**:迁移 → 应用 → 实体/类型再生成(**已有 migrations 不可直接改**) |
| [docs/agents/DATA-FETCHING.md](docs/agents/DATA-FETCHING.md) | **前端数据页面**:缓存分级、keepPreviousData、queryKey 失效 |
| [docs/agents/TESTING.md](docs/agents/TESTING.md) | 测试规范:层级、写法、禁忌 |
| [docs/agents/RULES.md](docs/agents/RULES.md) | **用户反复强调的规则与返工教训**:前端形态细则、禁原生弹窗、数据必须真实、环境约定 |

## 铁律(违反即返工)

1. **配置只从 TOML 读取**:`FLOATCTF_CONFIG` → `apps/api/config/development.toml` → `AppConfig`(经 `ReqCtx.config` 注入)。禁止新增环境变量读取;动态设置用 `get_setting`。
2. **实体是生成的**:手改 `apps/api/src/entity/` 会被覆盖。Schema 变更必须:`mise run db:migration:new` → 写幂等 SQL + 中文 COMMENT → `db:migration:merge` → 应用到开发库 → `mise run db:gen`。**sea-orm-cli 必须 1.1.20**(2.0.1 生成产物会导致全项目编译失败)。
3. **三处一致**:数据库 Schema / 生成实体 / 业务代码引用必须一致(`entity/代码/库` 漂移是历史最高频 bug 源)。
4. **敏感值走 `Secret`**:Debug/日志必须脱敏;`auth.jwt_secret` 等不落日志、不入库。
5. **提交规范**:中文 message(feat/fix/chore/docs/refactor 前缀),按角度分批提交;提交前 `cargo fmt --all && cargo check -p floatctf` 与相关测试全绿。**push 前必须本地完整过一遍验证**:`mise run check` 全绿,前端额外 `tsc --noEmit` 与 `vite build` 通过(CI 跑的是 `vite build && tsc`,本地不绿推送必红)。
6. **先诊断后修复**:修 bug 先定位根因并给证据;涉及行为/数据变更,先向用户说明方案获批后再动手。
2. **Migrations 只前进,无论如何都不可以直接动已有迁移文件**:`apps/api/src/sql/migrations/` 下**已经存在**的文件(含 baseline `20260810121925-initial-schema.sql` / `20260810121926-initial-data.sql`,以及任何已提交或已 apply 的迁移)**绝对禁止**直接修改、删除、重命名、重写、squash、回滚式改写。改 Schema / 修 Schema 错误 / 补数据 **只能** `mise run db:migration:new <名称>` 追加**新**迁移,把 SQL 写进这个新文件。禁止手改 `merged.sql`(生成产物);禁止在 migration 或业务代码里操作 `schema_migrations`(由 migrate.sh 独占)。唯一允许写入的对象:刚 `new` 出来、尚未 apply、尚未作为历史固化的**新文件**。详细见 [DATABASE.md](docs/agents/DATABASE.md)。
3. **实体是生成的**:手改 `apps/api/src/entity/` / `apps/web/src/entity/` 会被覆盖。Schema 变更流程:`db:migration:new` → 写幂等 SQL + 中文 COMMENT(**文件内禁止 BEGIN/COMMIT**)→ `db:migration:validate` → `db:migration:apply` → `mise run db:gen`。`merged.sql` 由 release 流程从 migrations 确定性生成;日常开发启动不依赖它。**sea-orm-cli 必须 1.1.20**。`public.schema_migrations` 不是领域实体(generator 已排除)。API 计算字段(如 settings `resolved_value`)放 manual DTO,不要写回生成文件。
4. **三处一致**:数据库 Schema / 生成实体 / 业务代码引用必须一致(`entity/代码/库` 漂移是历史最高频 bug 源)。
5. **敏感值走 `Secret`**:Debug/日志必须脱敏;`auth.jwt_secret` 等不落日志、不入库。
6. **宿主权限只走 helper**:生产 API 是 Compose 内的非 root 容器,必须保持 `cap_drop=ALL`、`no-new-privileges`、read-only rootfs,禁止挂载 `/var/run/docker.sock`、加入 docker 组或获得 `CAP_NET_ADMIN`;Docker 走 `helper-docker.sock`,WireGuard/nftables/conntrack 走 `helper-control.sock`。新增高权限能力必须先扩展 helper 的受限协议/策略。宿主 systemd 只管理 `floatctf-helper.service` + `floatctf-infra.service`/`floatctf.target`,不要恢复 `floatctf-api.service`。
7. **提交规范**:中文 message(feat/fix/chore/docs/refactor 前缀),按角度分批提交;提交前 `cargo fmt --all && cargo check -p floatctf` 与相关测试全绿。**push 前必须本地完整过一遍验证**:`mise run check` 全绿,前端额外 `tsc --noEmit` 与 `vite build` 通过(CI 跑的是 `vite build && tsc`,本地不绿推送必红)。
8. **先诊断后修复**:修 bug 先定位根因并给证据;涉及行为/数据变更,先向用户说明方案获批后再动手。
9. **前端仿照既有页面**:新页面先找同域参照页(赛事详情参照 `service/events/jeopardy.$id/*` 与 `awd.$id/*`、管理列表参照 `admin/challenges.tsx`、导航配置参照 `navigation/*`),结构/布局/交互与参照页保持一致;优先复用 `components/` 现有组件(GenericTable、EventStatusBadge、SubmitWriteup、MsgBanner、AppLink、FilterBar 等)与 `@primer/react`,禁止另起炉灶自创视觉风格或手写重复实现。管理页必须用 Challenges 内置 GenericTable 增删改查形态、样式对照要"一模一样"、默认最简方案等细则与全部返工案例见 [RULES.md](docs/agents/RULES.md)。
10. **用户偏好(详细见 [RULES.md](docs/agents/RULES.md))**:禁止原生 `alert(`/`confirm(` 弹窗(一律用 Primer `useConfirm`/`Dialog`/`useMsgBanner`);展示数据必须来自真实接口、禁止假数据/占位糊弄("不要随便搞点数据糊弄我"),状态判定必须与后端一致。

## 常用命令速查

```bash
mise run infra:up / infra:logs / infra:down # 基础设施(Postgres/RustFS/Nginx)
mise run dev:api / dev:web / dev # 启动开发服务
mise run db:migration:new <名称> # 新建 SQL 迁移
mise run db:migration:merge # 合并迁移 → merged.sql
mise run db:gen # 重新生成 Rust 实体 + TS 类型
mise run fmt / lint / test / check / build # 质量门禁
cargo test -p floatctf <关键词> # 跑指定单元测试
mise run setup # 新开发机一次性:工具链 + 主机能力 + helper
mise run dev # 唯一开发入口:infra + migrations + API watch + Vite
mise run dev:down / dev:reset / dev:logs # 停止 / 清库重建 / 基础设施日志
mise run db:migration:new <名称> # 新建 SQL 迁移(文件内无 BEGIN/COMMIT)
mise run db:migration:validate # 校验迁移文件(不连库)
mise run db:migration:status # 查看迁移状态(只读)
mise run db:migration:verify # 校验迁移历史(checksum)
mise run db:migration:apply # 执行未应用的迁移,fresh DB 可从 #1 开始
mise run db:migration:merge # release/fresh-production 用 merged.sql
mise run db:gen # 重新生成 Rust 实体 + TS 类型
mise run fmt / lint / test / check / build # 质量门禁
cargo test -p floatctf <关键词> # 跑指定单元测试
```

## 开发环境速记

- API:`http://localhost:9090`(mise run dev:api);Web:`http://localhost:3000`;统一入口 `http://localhost:7780`(Nginx)
- 开发库:`postgres://postgres:postgres@127.0.0.1:5432/floatctf_db`(容器 floatctf-dev-db)
- 对象存储:RustFS `http://127.0.0.1:9000`(桶 `floatctf-public` / `floatctf-private`)
- 配置样例:`apps/api/config/development.toml`;启动日志:`WORK_DIR/logs/api/`(按天滚动,开发库 WORK_DIR=`../../app` → `app/logs/api/`)
- 唯一开发模式:`mise run dev`;不存在 A/B 双轨与 `floatctf-dev-infra.service`。
- API:当前开发者 UID 运行,`watchexec` 自动重编译/重启;`dev-api-run.sh` 每次启动时丢弃 docker 等附加组和 capabilities;Web:Vite HMR。
- 宿主控制面:`floatctf-helper.service`,用户 `floatctf-helper` + docker group + `CAP_NET_ADMIN`;API 通过 `/run/floatctf/helper-control.sock` 与 `/run/floatctf/helper-docker.sock` 调用,API 自身无 Docker socket / 网络 capability。
- 开发库:`postgres://postgres:postgres@127.0.0.1:5432/floatctf_db`;fresh DB 直接 `migration apply`,开发启动不需要 `merged.sql`。
- Redis:`redis://127.0.0.1:6379`;RustFS:`http://127.0.0.1:9000`;Caddy/DB/Redis/RustFS 开发端口均回环绑定。Redis 是 API 必需基础设施:正常开发/生产必须提供 `[redis].url` 且 bootstrap PING 成功;禁止重新引入“未配置 Redis 也能正常启动”的生产路径,in-memory/noop 仅限显式测试。
- 配置:`apps/api/config/development.toml`,正常 `awd.network_runtime = "helper"`;`noop` 仅供测试/mock。
- 生产:API/PostgreSQL/Redis/RustFS/Caddy 由生产 Compose 承载(模板内嵌在 `scripts/install.sh`,安装后为 `$FLOATCTF_HOME/compose.prod.yml`,默认根 `/var/lib/floatctf`);API 不发布宿主 9090,通过 external internal `fctf-platform-control`(API `10.42.8.2`)接收 FlagServer/JudgeServer 回调。生产 TOML 使用 Compose DNS。宿主只创建 `floatctf` 组(不创建该用户),API 容器以数值 `65532:$FLOATCTF_GID` 运行。
- 修改 `crates/floatctf-helper/` / `crates/helper-protocol/` 后重新执行 `mise run setup`,刷新 root-owned `/usr/local/libexec/floatctf-helper`。
Loading
Loading