修「去密码硬编码」那一步自己引入的三个 bug

上一版把明文密码换成随机生成时，引入了三个问题。都是我自己的补丁
造成的，而且症状都像"功能坏了"，实际是环境和脚本的问题。

== bug 1：兜底替换把函数调用塞进了字符串 ==

fix_hardcoded_password.py 里有句兜底：
    text = text.replace(OLD, '_admin_password()')

而原代码是：
    {"username": "xmz7891", "password": "@<老密码>"}
                                            ^ @ 在引号**里面**

正则要求引号紧贴老密码，这里中间有个 @，所以没匹配上；
兜底替换就把老密码换成了函数调用，结果成了**字符串字面量**：

    {"username": "xmz7891", "password": "@_admin_password()"}

7 个文件被这样弄坏。它们拿这串东西当密码去登录，
当然登不上 -> 401「请先登录」-> 管理接口测试全红（12 项失败）。

教训：**批量替换里的兜底 str.replace 太危险**，它不看上下文。
替换完必须检查有没有"函数调用被引号包起来"这种形状。

== bug 2：测试和它自己起的中转对不上密码 ==

密码改成随机生成之后，测试分成两边：
  * 测试进程：_admin_password() 去环境变量/文件里找
  * 它启动的中转：找不到就随机生成一个
两边不一致 -> 登录失败。

修法：测试在**模块级**（import 时）生成一个本次运行专用的随机密码，
写进 os.environ["RELAY_ADMIN_PASSWORD"]。测试启动中转用的是
dict(os.environ)，所以会自动传过去 —— 两边就是同一个密码。

用随机而不是写死：写死就又变成"密码进仓库"了，白改一场。

== bug 3：全新部署启动后没有密码文件 ==

admin_password() 原来只在有人访问登录页时才调用，于是全新部署
启动后 data/admin_password.txt 一直不存在，日志里也看不到密码，
管理员不知道该用什么登。

修法：main() 里在 admin_key() 后面补一句 admin_password()，
和钥匙一样的道理 —— 启动时生成并打印一次。

== 验证 ==

    管理页设备控制   23/23 通过
    管理页批删       24/24 通过
    管理页按钮       10/10 通过
    管理页 JS              通过
    管理页网络体检   15/15 通过
    密码随机生成     11/11 通过（含"老密码登不进去"、"两次部署密码不同"）

工作区搜不到明文密码了（git 历史里还有，等用户确认后重写）。
