diff --git a/docs/architecture/Lotto-Architecture-v1.md b/docs/architecture/Lotto-Architecture-v1.md
new file mode 100644
index 0000000..6ce828e
--- /dev/null
+++ b/docs/architecture/Lotto-Architecture-v1.md
@@ -0,0 +1,1225 @@
+# 双色球自动化系统 — 架构设计文档
+
+| 字段 | 值 |
+|------|-----|
+| 文档编号 | ADR-LOTTO-001 |
+| 版本 | v1.0 |
+| 创建日期 | 2026-07-03 |
+| 架构师 | 梁思筑(Serena) |
+| 评审状态 | 待评审 |
+| 关联 PRD | PRD-双色球 WebUI-v1.0(沈路明) |
+| 关联 Issue | BIZ-74 / 父任务 BIZ-68 |
+
+---
+
+## 1. 系统概述
+
+### 1.1 业务定位
+
+双色球自动化系统是一套面向内部用户的福利彩票双色球辅助工具,核心功能包括:
+- **数据采集**:每日自动从 55128.cn 抓取双色球历史开奖数据
+- **号码生成**:基于历史数据分析(热冷号、奇偶比、大小比、和值、跨度)+ 随机策略生成推荐号码
+- **Web 展示**:提供响应式 Web UI,支持 PC + 移动端访问,局域网内可多人同时使用
+
+### 1.2 用户场景
+
+| 场景 | 角色 | 触发方式 | 预期结果 |
+|------|------|----------|----------|
+| 生成号码 | 刘总/团队成员 | Web UI 点击「生成」 | 3s 内返回号码列表 + 统计指标 |
+| 查看历史 | 刘总/团队成员 | Web UI 切换 Tab | 分页查看历史开奖数据 |
+| 下载结果 | 刘总/团队成员 | Web UI 点击「下载」 | 获取 Excel 文件 |
+| 自动抓取 | 系统 | Cron 定时触发 | 凌晨 2:30 自动更新历史数据 |
+
+### 1.3 系统边界
+
+- 数据来源:55128.cn(外部网站,仅读取)
+- 用户终端:PC/移动端浏览器(内网访问)
+- 数据存储:本地 Excel + JSON 文件
+- 服务进程:Flask 单进程 + threaded=True
+- 部署环境:Ubuntu Server (192.168.1.99)
+
+## 2. 系统架构图
+
+### 2.1 系统拓扑
+
+```
+┌────────────────────────────────────────────────────┐
+│ 用户浏览器 │
+│ (PC / 移动端 / 微信内置) │
+│ http://192.168.1.99:8085 │
+└───────────────────────┬────────────────────────────┘
+ │ HTTP (内网)
+ ▼
+┌────────────────────────────────────────────────────┐
+│ Flask Web 服务 (app.py) │
+│ 监听 0.0.0.0:8085 │
+│ ┌──────────┬──────────┬──────────┬──────────────┐ │
+│ │ /api/ │ /api/ │ /api/ │ /api/ │ │
+│ │ generate │ history │ records │ statistics │ │
+│ ├──────────┼──────────┼──────────┼──────────────┤ │
+│ │ /api/ │ /api/ │ /api/ │ / │ │
+│ │ download │ status │ config │ (index.html) │ │
+│ └──────────┴──────────┴──────────┴──────────────┘ │
+└───────┬────────────────────┬───────────────────────┘
+ │ │
+ ▼ ▼
+┌───────────────┐ ┌──────────────────┐
+│ lottery.py │ │ fetch_data.py │
+│ 号码生成核心 │ │ 数据抓取脚本 │
+│ (NumPy+Pandas)│ │ (requests+BS4) │
+└───────┬───────┘ └────────┬─────────┘
+ │ │
+ ▼ ▼
+┌──────────────────────────────────────┐
+│ 本地文件系统 │
+│ ┌─────────────┬──────────────────┐ │
+│ │双色球历史数据 │.generation_ │ │
+│ │ .xlsx │records.json │ │
+│ └─────────────┴──────────────────┘ │
+│ ┌──────────────────────────────────┐│
+│ │ lottery/ (生成结果 Excel 目录) ││
+│ └──────────────────────────────────┘│
+└──────────────────────────────────────┘
+```
+
+### 2.2 数据流
+
+```
+数据抓取流:
+ 55128.cn → HTTP GET → fetch_data.py → BeautifulSoup 解析 → Excel 写入
+
+号码生成流:
+ 双色球历史数据.xlsx → lottery.py → 统计分析 → 策略调整 → Excel 输出 → app.py JSON 返回
+
+前端数据流:
+ index.html → fetch() → app.py API → JSON → DOM 渲染
+
+记录管理流:
+ 生成 → add_record() → .generation_records.json
+ 删除 → remove file + update JSON
+```
+
+### 2.3 模块依赖图
+
+```mermaid
+graph TD
+ A[index.html
前端 UI] -->|HTTP API| B[app.py
Flask 后端]
+ B -->|import| C[lottery.py
号码生成器]
+ B -->|read/write| D[.generation_records.json]
+ B -->|read| E[双色球历史数据.xlsx]
+ C -->|read| E
+ C -->|write| F[lottery/*.xlsx]
+ B -->|send_file| F
+ G[fetch_data.py
数据抓取] -->|HTTP GET| H[55128.cn]
+ G -->|write| E
+ I[web_executor.py
抓取控制台] -->|subprocess| G
+ K[Cron
fetch_daily.sh] -->|exec| G
+ L[web_console.html] -->|HTTP API| I
+```
+
+## 3. 技术选型对比
+
+### 3.1 后端框架
+
+| 维度 | Flask (当前选择) | FastAPI | Django |
+|------|:-:|:-:|:-:|
+| 学习成本 | ★★★★★ 团队熟悉 | ★★★★ 需学异步 | ★★★ 概念重 |
+| 异步支持 | ★★ 需 threaded | ★★★★★ 原生 async | ★★ 有限 |
+| 依赖体积 | ★★★★★ 轻量 | ★★★★ 较轻 | ★★ 笨重 |
+| 适合度 | ✅ 项目规模小、路由少 | 未来升级 | 过度设计 |
+
+**决策**:维持 Flask。现有代码已基于 Flask 开发且运行稳定;项目路由仅 8 个,无异步需求。
+
+### 3.2 前端方案
+
+| 维度 | 原生 HTML/CSS/JS (当前) | Vue 3 | React |
+|------|:-:|:-:|:-:|
+| 构建工具 | 无需 | 需 Vite | 需 Vite |
+| 交互复杂度 | ★★ 满足当前 | ★★★★★ | ★★★★★ |
+| 包体积 | 0 KB | ~30KB(gz) | ~40KB(gz) |
+| 适合度 | ✅ 4 Tab + 表单 | 未来增强 | 过度设计 |
+
+**决策**:维持原生 HTML/CSS/JS。当前 UI 仅 4 个 Tab + 少量表单交互,引入框架不合理。
+
+### 3.3 数据存储方案
+
+| 维度 | Excel + JSON (当前) | SQLite | MySQL |
+|------|:-:|:-:|:-:|
+| 运维成本 | ★★★★★ 零运维 | ★★★★ 嵌入式 | ★★★ 独立部署 |
+| 并发读写 | ★ 文件锁 | ★★★★ | ★★★★★ |
+| 数据量需求 | <1MB | <1GB | 任意 |
+| 适合度 | ✅ 120条/12KB | 可选升级 | 过度设计 |
+
+**决策**:维持 Excel + JSON。数据量极小(120 条记录、12KB),无并发写入场景。若未来 >10,000 条迁移 SQLite。
+
+### 3.4 部署方式
+
+| 维度 | systemd + Cron (当前) | Docker Compose | 裸进程 |
+|------|:-:|:-:|:-:|
+| 隔离性 | ★★ 系统级 | ★★★★★ 容器 | ★ 无 |
+| 开机自启 | ★★★★★ systemd | ★★★★ restart:always | ★★ 手动 |
+| 适合度 | ✅ 内网单服务 | 未来扩展 | 不推荐 |
+
+**决策**:维持 systemd + Cron。内网单服务,引入 Docker 增加不必要复杂度。
+
+## 4. 模块详细设计(单文件/单函数级)
+
+### 4.1 app.py — Flask Web 主服务
+
+**路径**: `/home/vincent/Studio/lottoData/app.py`
+**职责**: 提供 Web UI 和 REST API,系统唯一入口
+**规模**: ~490 行
+**依赖**: Flask, lottery.py, pandas, openpyxl, numpy
+
+#### 4.1.1 模块配置
+
+```python
+CONFIG = {
+ 'host': '0.0.0.0', # 监听地址(局域网可访问)
+ 'port': 8085, # 端口
+ 'history_file': '双色球历史数据.xlsx',
+ 'lottery_output_dir': 'lottery/',
+ 'records_file': '.generation_records.json',
+ 'api_token': 'lotto2026', # auth_enabled=True 时生效
+ 'auth_enabled': False, # 认证开关
+ 'max_tickets': 1000, # 单次生成上限
+ 'default_tickets': 10, # 默认注数
+}
+```
+
+#### 4.1.2 函数清单
+
+| 函数 | 输入 | 输出 | 依赖 | 说明 |
+|------|------|------|------|------|
+| `load_records()` | 无 | `list[dict]` | JSON 文件 | 加载生成记录 |
+| `save_records(records)` | `list[dict]` | 无 | JSON 文件 | 保存生成记录 |
+| `add_record(strategy, num_tickets, filename)` | str, int, str | `dict` | load/save | 添加一条记录 |
+| `require_auth(f)` | Flask route | decorator | CONFIG | API 认证装饰器 |
+| `api_generate()` | POST body | JSON | lottery.py | **核心**:生成号码 |
+| `get_statistics_data()` | 无 | `dict` | pandas,numpy | 计算统计数据 |
+| `api_statistics()` | 无 | JSON | get_statistics_data | GET 统计接口 |
+| `api_records()` | query: page,page_size | JSON | load_records | 分页获取记录 |
+| `api_delete_record(record_id)` | URL param | JSON | load/save_records | 删除记录+文件 |
+| `api_download(filepath)` | URL param | File | send_file | 下载 Excel |
+| `api_history()` | query: page,search | JSON | pandas | 分页历史数据 |
+| `api_status()` | 无 | JSON | os | 系统状态 |
+| `api_config()` | 无 | JSON | CONFIG | 前端配置 |
+| `index()` | 无 | HTML | send_from_directory | 返回 index.html |
+
+#### 4.1.3 核心接口:api_generate()
+
+```
+输入: POST /api/generate
+ Body: {"num_tickets": int (1-1000), "strategy": "advanced"|"basic"}
+
+处理流程:
+ 1. 解析并校验请求参数(num_tickets 1-1000,strategy advanced/basic)
+ 2. 实例化 DoubleColorBallGenerator(history_file)
+ 3. generator.load_history_data() 加载历史数据
+ 4. generator.generate_multiple_tickets(num_tickets, strategy) 生成号码
+ 5. generator.save_to_excel() 保存结果文件
+ 6. add_record() 记录生成历史
+ 7. get_statistics_data() 获取统计信息
+ 8. 构建 JSON 响应(前端最多展示 50 注)
+
+输出: {
+ success: true,
+ data: {
+ tickets: [{index, reds[6], blue, sum_value, odd_even, size_ratio, span}],
+ total: int, filename: str, download_url: str, record: dict, statistics: dict
+ }
+}
+
+边界条件:
+ - num_tickets < 1 或 > 1000 → 400
+ - strategy 非 advanced/basic → 400
+ - 历史数据文件不存在 → 500
+ - load_history_data() 返回 False → 500
+ - tickets_df.empty → 500
+ - save_to_excel 返回 None → 500
+```
+
+#### 4.1.4 核心接口:get_statistics_data()
+
+```
+处理流程:
+ 1. 读取 Excel(header=None, iloc[1:] 跳过描述行)
+ 2. 解析红球(6个)+蓝球(1个)从拼接字符串(每2字符=1球)
+ 3. Counter 统计频次 → 排序取热冷号
+ 4. 统计奇偶比/大小比频次
+ 5. numpy 计算和值/跨度的 min/max/mean/std
+
+输出: {
+ hot_reds: [int...15], cold_reds: [int...15],
+ hot_blues: [int...8],
+ common_odd_even: "3:3", common_size_ratio: "4:2",
+ sum_range: {min, max, mean, std},
+ span_range: {min, max, mean, std},
+ history_count: int
+}
+
+边界条件:
+ - Excel 不存在 → 返回 {}
+ - 数据行为空 → 返回 {}
+ - 号码字符串长度 <14 → 跳过该行
+ - 号码超出范围 → 跳过
+```
+
+#### 4.1.5 核心接口:api_history()
+
+```
+处理流程:
+ 1. 读取 Excel(header=None, iloc[1:])
+ 2. 硬编码列名: ['开奖日期','期号','红球','开机号','和值特征','奇偶形态','大小比','奇偶形态2','跨度','其他']
+ 3. 解析红球列表(前12字符每2位) + 蓝球(第13-14位)
+ 4. search 非空 → 全列字符串匹配过滤
+ 5. 分页切片 → JSON
+
+⚠️ 已知问题:
+ - 每次请求都重新读取 Excel,无缓存(120 条可接受)
+ - 列名硬编码,Excel 格式变化需同步修改
+ - 搜索全列匹配可能误匹配
+```
+
+#### 4.1.6 核心接口:api_download(filepath)
+
+```
+安全检查:
+ 1. os.path.normpath(filepath) 规范化
+ 2. 拒绝以 ../ 开头 → 403
+ 3. 拒绝以 / 开头 → 403
+ 4. 拼接 BASE_DIR + filepath,检查文件存在
+
+⚠️ 安全建议(costcodev 实施时加固):
+ - 增加 os.path.realpath() 确保最终路径在 BASE_DIR 内
+ - 当前 normpath 检查可被符号链接绕过
+```
+
+### 4.2 lottery.py — 号码生成核心
+
+**路径**: `/home/vincent/Studio/lottoData/lottery.py`
+**职责**: 基于历史数据分析 + 随机策略生成双色球号码
+**规模**: ~1100 行
+**依赖**: pandas, numpy, openpyxl, datetime, collections.Counter, re
+
+#### 4.2.1 类定义:DoubleColorBallGenerator
+
+```python
+class DoubleColorBallGenerator:
+ def __init__(self, history_file="双色球历史数据.xlsx", config=None):
+ # config 默认值:
+ # hot_red_count=15, cold_red_count=10, hot_blue_count=8
+ # hot_blue_probability=0.7, max_adjustment_attempts=20
+```
+
+#### 4.2.2 方法清单
+
+| 方法 | 输入 | 输出 | 说明 |
+|------|------|------|------|
+| `__init__(history_file, config)` | str, dict | None | 初始化配置 |
+| `load_history_data()` | 无 | bool | 加载 Excel + 统计计算 |
+| `_calculate_statistics()` | 无 | None | 计算热冷号/奇偶/大小/和值/跨度 |
+| `get_hot_red_balls(n=10)` | int | `list[int]` | 红球热号 TOP n |
+| `get_cold_red_balls(n=10)` | int | `list[int]` | 红球冷号 TOP n |
+| `get_hot_blue_balls(n=5)` | int | `list[int]` | 蓝球热号 TOP n |
+| `parse_ratio(ratio_str)` | str | tuple | 解析比例字符串 |
+| `_select_hot_cold_balls()` | 无 | tuple | 选择热冷号组合 |
+| `_adjust_odd_even_ratio(red_balls)` | list | list | 调整奇偶比至 2:4~4:2 |
+| `_adjust_size_ratio(red_balls)` | list | list | 调整大小比至 2:4~4:2 |
+| `_adjust_sum_range(red_balls)` | list | list | 调整和值至 [90,120] |
+| `_adjust_span_range(red_balls)` | list | list | 调整跨度至 [22,30] |
+| `_select_blue_ball()` | 无 | int | 选蓝球(热号概率0.7) |
+| `generate_single_ticket_advanced()` | 无 | list[6]+int | 高级策略生成单注 |
+| `generate_single_ticket_basic()` | 无 | list[6]+int | 基础策略生成单注 |
+| `generate_multiple_tickets(n, strategy)` | int, str | DataFrame | 批量生成号码 |
+| `save_to_excel(df, n, strategy)` | df, int, str | str\|None | 保存为 Excel |
+| `display_statistics()` | 无 | None | 控制台输出统计 |
+| `run_tests()` | 无 | None | 内置测试 |
+| `main()` | 无 | None | CLI 入口 |
+
+#### 4.2.3 关键算法:generate_single_ticket_advanced()
+
+```
+高级策略生成流程:
+ 1. _select_hot_cold_balls() → 从热号选3-4个 + 冷号选2-3个 = 6个
+ 2. 排序红球
+ 3. _adjust_odd_even_ratio() → 目标奇偶比 2:4~4:2,尝试上限20次
+ 4. _adjust_size_ratio() → 目标大小比 2:4~4:2
+ 5. _adjust_sum_range() → 目标和值 [90, 120]
+ 6. _adjust_span_range() → 目标跨度 [22, 30]
+ 7. 红球去重 + 范围校验 (1-33)
+ 8. _select_blue_ball() → 70%热号 + 30%随机,范围1-16
+ 9. 返回 reds[6] + blue
+
+边界条件:
+ - 历史数据不足10条 → 警告但可生成
+ - 调整超 max_adjustment_attempts → 接受当前结果
+ - 红球不允许重复
+```
+
+#### 4.2.4 关键算法:generate_multiple_tickets()
+
+```
+输入: num_tickets (1-1000), strategy ("advanced"|"basic")
+处理:
+ 1. 循环 num_tickets 次
+ 2. 每次调用 generate_single_ticket_advanced/basic()
+ 3. 计算每注统计指标(和值、奇偶比、大小比、跨度)
+ 4. 构建 pandas DataFrame
+输出 DataFrame 列: 序号 | 红球1-6 | 蓝球 | 和值 | 奇偶比 | 大小比 | 跨度
+
+边界条件:
+ - 单注生成失败 → 跳过并记日志
+ - 全部失败 → 返回空 DataFrame
+ - 1000注耗时预估 5-8s
+```
+
+#### 4.2.5 关键算法:save_to_excel()
+
+```
+输入: tickets_df, num_tickets, strategy
+处理:
+ 1. 文件名: 双色球_YYYYMMDD_HHMMSS_策略_N注.xlsx
+ 2. 保存到 lottery/ 目录(不存在自动创建)
+ 3. openpyxl 写入
+输出: 文件完整路径 or None(失败)
+```
+
+---
+
+### 4.3 fetch_data.py — 数据抓取脚本
+
+**路径**: `/home/vincent/Studio/lottoData/fetch_data.py`
+**职责**: 从 55128.cn 抓取双色球历史开奖数据,更新本地 Excel
+**规模**: ~130 行
+**依赖**: requests, beautifulsoup4, pandas, openpyxl
+
+#### 4.3.1 函数清单
+
+| 函数 | 输入 | 输出 | 说明 |
+|------|------|------|------|
+| `fetch_lottery_data()` | 无 | `list[list]`\|None | HTTP GET + BS4 解析表格 |
+| `save_to_excel(data_rows)` | `list[list]` | bool | DataFrame → Excel 覆盖写入 |
+| `main()` | 无 | None | CLI 入口 |
+
+#### 4.3.2 fetch_lottery_data() 详细设计
+
+```
+处理流程:
+ 1. requests.get(URL, headers=HEADERS, timeout=30)
+ 2. BeautifulSoup(response.text, "html.parser")
+ 3. soup.find("table") → 定位数据表格
+ 4. 遍历 table.find_all("tr") → 解析每行
+ 5. 提取:期号、日期、红球6个、蓝球、和值、奇偶比、大小比、跨度
+ 6. 返回 data_rows
+
+边界条件:
+ - HTTP 超时(30s) → 返回 None
+ - 非 200 → raise_for_status()
+ - 表格不存在 → 返回 None
+ - 行数据不完整 → 跳过
+
+数据源说明:
+ - URL: https://www.55128.cn/kjh/fcssq-history-120.htm
+ - 内容:最近 120 期开奖数据
+ - 频率:每日 1 次(Cron 2:30)
+ - 无需登录、无 API 限流
+```
+
+#### 4.3.3 save_to_excel() 详细设计
+
+```
+处理:
+ 1. 构建 pandas DataFrame
+ 2. 覆盖写入 双色球历史数据.xlsx
+
+⚠️ 覆盖写入决策:
+ - data_rows 最多 120 行,数据量极小
+ - 覆盖过程中服务短暂数据不可用(毫秒级,可接受)
+ - 替代方案"增量追加"复杂度高、收益低
+```
+
+---
+
+### 4.4 web_executor.py — 数据抓取 Web 控制台
+
+**路径**: `/home/vincent/Studio/lottoData/web_executor.py`
+**职责**: 提供 Web 界面手动触发数据抓取
+**规模**: ~220 行
+**依赖**: Flask, subprocess, threading
+
+#### 4.4.1 函数清单
+
+| 函数 | 输入 | 输出 | 说明 |
+|------|------|------|------|
+| `load_status()` | 无 | dict | 从 .fetch_status.json 加载 |
+| `save_status()` | 无 | None | 保存状态到文件 |
+| `index()` | 无 | HTML | 返回 web_console.html |
+| `api_status()` | 无 | JSON | 获取抓取状态 |
+| `api_execute()` | 无 | JSON | 异步触发 fetch_data.py |
+| `check_dependencies()` | 无 | JSON | 检查依赖 |
+
+#### 4.4.2 api_execute() 设计
+
+```
+处理流程:
+ 1. 检查 is_running 状态锁
+ 2. 已在运行 → 返回 409
+ 3. 启动 threading.Thread → subprocess.Popen 执行 fetch_data.py
+ 4. 更新全局 execution_status + .fetch_status.json
+
+边界条件:
+ - 并发触发 → status_lock 保护,返回 409
+ - subprocess 退出码非 0 → 记录 last_error
+ - ⚠️ 缺少 subprocess 超时(建议加 timeout=120s)
+```
+
+#### 4.4.3 与 app.py 的关系
+
+```
+app.py (端口 8085) → 号码生成/历史/记录/统计
+web_executor.py (端口 5000) → 手动触发抓取
+
+两个独立 Flask 服务,共享数据文件但端口不同。
+⚠️ 架构建议:长期应合并为单一服务,通过路由区分功能。
+```
+
+---
+
+### 4.5 index.html — 前端 UI
+
+**路径**: `/home/vincent/Studio/lottoData/index.html`
+**职责**: 响应式 Web UI,4 个功能 Tab
+**规模**: ~1170 行(HTML + CSS + JS 单文件)
+**依赖**: 无外部 CDN
+
+#### 4.5.1 页面结构
+
+```
+index.html
+├──