Files
codex-helper/docs/frontend/application.md
T

4.4 KiB
Raw Blame History

前端应用

前端位于 frontend/,使用 React 19、TypeScript、Vite、React Router、Lucide 和 Recharts。应用壳和页面位于 frontend/src/main.tsx,API 错误与请求生命周期集中在 api.ts,传输类型和运行时 decoder 位于 types.ts,认证与主题分别由 context 管理。Recharts 图表通过动态 import 独立打包。

状态与路由

应用启动先请求 system/status,已初始化时再请求 auth/me。未初始化渲染安装页;初始化后未登录渲染公开只读 / 总览和 /login 登录页,登录后由 BrowserRouter 提供 / 总览和 /settings 设置,未登录访问 /settings 回到公开总览,未知路径回到 /。状态响应中的构建版本以 v<version> 徽标显示在安装页、登录页、公开总览和登录后侧栏的品牌区域;登录后侧栏使用放大的品牌图标,图标、名称和版本徽标保持单行排列。这些分支只负责交互,服务端 session 才是安全边界。

主题以服务端通用设置为持久来源,localStorage 仅用于首屏缓存;system 模式会跟随系统主题变化。总览先加载账号列表,再并发加载每个账号的 Dashboard,并在每轮请求完成 30 秒后重新读取;每个账号独立维护请求、加载和错误状态,校验响应账号,避免迟到响应覆盖其他账号。公开总览使用匿名只读接口并隐藏身份配置字段,隐藏手动刷新按钮和设置导航;服务器固定每 5 分钟同步全部账号,登录后总览默认只展示账号摘要,展开卡片后显示完整限额、统计和 Token 图。

桌面端使用固定侧栏,800px 及以下改为紧凑顶栏和固定底部主导航;GitHub、主题和退出位于顶栏辅助菜单。移动布局最低支持 320px,使用动态视口高度和 CSS safe-area 环境变量避开 iOS 浏览器工具栏与设备安全区。内容必须为底部导航保留空间,表单控件避免 iOS 聚焦缩放,主要交互保持至少 44px 触控区域。

API 客户端

所有请求使用相对 /api/v1/、credentials: same-origin 和 X-Requested-With: codex-helper,仅 JSON body 设置 content type。请求支持取消和 timeout;非 2xx 响应转换为保留 status 的 ApiError,401 会统一回到登录界面。JSON 响应先作为 unknown,经端点 decoder 校验后进入组件。新增下载或非 JSON 响应不能直接套用当前 api helper。

API 类型精确区分后端 null 与 optional,并为秘密设置拆分读写形状;空数组及 unknown 套餐按后端返回值处理。邮箱在 Web 界面的账号选择器、总览和设置中统一经过 maskEmail;不得把未掩码邮箱添加到新的 Web 可见位置。Telegram /account 是独立的已绑定会话输出,当前显示完整邮箱。

总览与设置

总览显示账户连接、套餐、每个限额窗口的剩余百分比和重置时间、当前重置周期 Token 合计、本周期单日峰值、其他摘要及每日 Token 图;登录后账号有可用重置卡时,详情额外显示卡片数量和到期时间。当前周期 Token 与本周期单日峰值都由后端按 app-server 的有效最长限额窗口和每日 bucket 汇总,不包含周期外或未来日期;详情会显示周期起止时间和“按每日数据汇总”提示。usedPercent 展示前限制到 0–100,但原始数据语义不得在 API 类型层改写。缺失摘要显示“暂无”,缺失限额显示明确空状态。匿名公开 Dashboard 不显示重置卡信息。

设置页四个 tab 全部保持挂载,以保留未提交表单状态;非活动 panel 使用 aria-hidden 和 inert 隔离。tab 支持方向键、Home 和 End,程序化切换不得改变页面滚动和布局。账号删除必须保留不可撤销确认,并清理正在显示的设备码和本地账号选择。

验证重点

纯逻辑和组件测试使用 Vitest;Oxlint 检查 TypeScript/React 正确性,Prettier 检查格式,构建门禁限制单个 JavaScript chunk 不超过 500 KB。浏览器测试使用 Playwright 的 desktop Chrome、Android Chrome 和 iOS WebKit 项目,覆盖设置布局、移动导航、键盘操作、隐藏表单隔离、账号删除、窄屏溢出、邮箱掩码、session 失效和跨账号竞态。修改 effect、轮询或异步加载时应覆盖卸载清理、错误状态及旧响应覆盖新状态;修改 CSS 时同时跑三个浏览器项目。