# HappyWedding 开发环境与启动说明 本文档用于固定 HappyWedding(简称 `hw`)当前阶段的本地开发方式,重点说明如何使用项目内 `.venv` 进行依赖安装、运行测试和启动应用。 ## 1. 项目名称 - 项目全名:`HappyWedding` - 项目简写:`hw` ## 2. 当前技术基线 - 后端:Python 3 + Flask - ORM:Flask-SQLAlchemy / SQLAlchemy 2.x - 前端:SSR 模板 + jQuery 增强 + Tailwind CSS(CLI 编译模式) - 数据库: - 本地开发 / 测试:SQLite - 正式环境:MySQL - 测试:pytest 补充说明: - 当前页面样式基线已从 Skeleton CSS 切换到 Tailwind CSS,并已进一步切换为 **Tailwind CLI 编译模式**。 - Tailwind 源文件位于:`app/static/src/styles.css` - 编译输出位于:`app/static/css/main.css` - `base.html` 通过 `{{ url_for('static', filename='css/main.css') }}` 引用编译结果 - 当前已支持 light / dark 双主题切换,使用 `localStorage('hw-theme')` 持久化,并在 CSS 加载前执行主题初始化脚本以避免首屏闪烁。 - 模板文件继续使用 Jinja2 语法(如 `{% ... %}`、`{{ ... }}`);Tailwind 主题变量、组件层与 `@source` 扫描规则已迁移到独立 CSS 源文件中。 - 部分 HTML/CSS LSP(例如 Biome)仍可能对 Jinja 模板或 Tailwind 指令报 parse error;这属于工具链兼容性限制,不代表运行时有问题,当前应以 `npm run build:css`、实际页面渲染与 pytest / E2E 结果为准。 ## 3. 当前目录结构 ```text hw/ ├── README.md ├── requirements.txt ├── run.py ├── app/ │ ├── __init__.py │ ├── auth.py │ ├── cli.py │ ├── config.py │ ├── extensions.py │ ├── models/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── account.py │ │ ├── audit_log.py │ │ ├── gift_record.py │ │ ├── household.py │ │ ├── household_member.py │ │ └── option_item.py │ ├── routes/ │ │ ├── auth.py │ │ ├── csv_tools.py │ │ ├── entry.py │ │ ├── health.py │ │ ├── main.py │ │ └── admin.py │ ├── services/ │ │ ├── __init__.py │ │ ├── audit.py │ │ ├── demo_seed.py │ │ ├── households.py │ │ └── csv_tools.py │ ├── static/ │ └── templates/ ├── migrations/ ├── docs/ │ ├── requirements.md │ ├── technical-design.md │ ├── todo-progress.md │ ├── development-setup.md │ ├── production-deployment.md │ └── production-ops.md └── tests/ ├── __init__.py ├── e2e/ │ ├── __init__.py │ ├── conftest.py │ ├── helpers.py │ ├── test_admin_account_flow.py │ ├── test_admin_audit_flow.py │ ├── test_admin_smoke_pages.py │ ├── test_auth_flow.py │ ├── test_core_flow_admin_edit.py │ ├── test_csv_flow.py │ ├── test_entry_flow.py │ └── test_household_management_flow.py ├── test_app_bootstrap.py ├── test_admin_pages.py ├── test_auth.py ├── test_cli_seed.py ├── test_csv_pages.py └── test_household_pages.py ``` ## 4. 使用 `.venv` 的原因 当前系统 Python 受到 PEP 668 保护,不能直接在全局环境里执行 `pip install -r requirements.txt`。 因此,项目开发统一使用仓库内虚拟环境: - 虚拟环境目录:`.venv/` - 已在 `.gitignore` 中忽略 - 所有依赖安装、测试执行、脚本运行都应优先通过 `.venv/bin/python` 完成 ## 5. 初始化开发环境 如果仓库中还没有 `.venv`,可执行: ```bash python3 -m venv .venv .venv/bin/python -m pip install -r requirements.txt ``` 如果 `.venv` 已存在,更新依赖可执行: ```bash .venv/bin/python -m pip install -r requirements.txt ``` 如果仓库中还没有前端依赖,或 Tailwind 样式源文件有更新,请执行: ```bash npm install ``` 首次使用或样式有改动后,先编译一次 CSS: ```bash npm run build:css ``` 如需持续调样式,建议额外开启监听: ```bash npm run watch:css ``` ## 6. 启动应用 当前项目已实现 Flask 应用工厂和健康检查路由。 ### 6.1 一键开发启动(推荐) ```bash npm run build:css .venv/bin/python -m flask dev-bootstrap ``` 默认会自动完成: - 执行数据库迁移 `flask db upgrade` - 初始化基础种子 `flask seed-all` - 初始化演示账号与演示户数据 `flask seed-demo` - 输出可直接登录的演示账号 - 启动本地 Flask 开发服务 如只想准备数据但暂时不启动服务,可执行: ```bash .venv/bin/python -m flask dev-bootstrap --skip-server ``` 如果当前正在做样式开发,推荐使用两个终端: ```bash # 终端 1:监听 Tailwind 源文件 npm run watch:css # 终端 2:启动 Flask 开发服务 .venv/bin/python -m flask dev-bootstrap ``` 默认演示账号: - `admin / ChangeMe123!` - `editor-demo / EditorDemo123!` - `entry-demo / EntryDemo123!` ### 6.2 直接运行 ```bash .venv/bin/python run.py ``` 默认行为: - 使用 `development` 配置 - 若未设置 `DATABASE_URL`,默认使用 SQLite 本地库 - SQLite 文件默认位于:`instance/happywedding.db` ### 6.3 健康检查 启动后可访问: ```text GET /health ``` 预期返回: ```json { "project": "HappyWedding", "short_name": "hw", "status": "ok" } ``` ## 7. 运行测试 当前基础测试覆盖: - `create_app("testing")` 是否成功创建应用 - `/health` 路由是否可访问 - 六张核心表是否进入元数据 - 关键字段是否存在 - 核心外键是否存在 - 关键唯一约束是否存在 执行单元 / 页面测试命令: ```bash .venv/bin/python -m pytest tests ``` 执行 Playwright 端到端测试前,需先安装浏览器: ```bash .venv/bin/python -m playwright install chromium ``` 执行 E2E 测试: ```bash .venv/bin/python -m pytest tests/e2e -q ``` 当前 E2E 目录中的核心用例包括: - `tests/e2e/test_core_flow_admin_edit.py`:管理员登录 → 搜索/筛选 → 打开编辑页 → 保存 - `tests/e2e/test_entry_flow.py`:长辈账号登录 → 搜索选择 → 编辑有限字段 → 保存 - `tests/e2e/test_admin_smoke_pages.py`:账号管理 / 审计日志 / CSV 页面 smoke - `tests/e2e/test_household_management_flow.py`:管理员新增一户 → 新增成员 → 编辑成员 → 删除成员 - `tests/e2e/test_admin_account_flow.py`:创建账号 → 编辑账号 → 重置密码 → 停用 / 启用账号 - `tests/e2e/test_admin_audit_flow.py`:制造审计记录 → 按动作筛选 → 查看审计详情 before/after 快照 - `tests/e2e/test_csv_flow.py`:下载模板 → 导出全部 / 当前筛选 → 上传 CSV → 预览 → 确认导入 → 回查结果 - `tests/e2e/test_auth_flow.py`:错误密码登录失败 → 未登录重定向 → entry_only 越权回跳 → 退出登录 当前状态: - 测试应通过 `.venv/bin/python -m pytest tests` 与 `.venv/bin/python -m pytest tests/e2e -q` 执行 - 当前推荐的验证命令为:先跑 `.venv/bin/python -m pytest tests/e2e -q`,再跑 `.venv/bin/python -m pytest tests` - 新增页面测试已覆盖:`GET /reports`、`GET /?partial=results`、`GET /entry/?partial=search-results`、`GET /entry/?partial=edit-sheet` - 当前最新一次验证结果请以本地实际运行输出为准,避免文档中的固定数字滞后于代码演进 ## 8. 数据库迁移与初始化命令 当前项目已接入 Flask-Migrate / Alembic,并已生成首个 migration 文件。 ### 8.1 初始化迁移目录(首次执行) ```bash FLASK_APP=run.py .venv/bin/flask db init ``` 说明: - 该命令只需首次执行一次 - 当前仓库已经生成了 `migrations/` 目录与首个 migration 文件 ### 8.2 生成迁移脚本 ```bash FLASK_APP=run.py .venv/bin/flask db migrate -m "Initial migration" ``` 当前已验证: - SQLite 本地下可正常生成 migration - 生成结果会保留跨库 ID 类型定义:SQLite 为 `INTEGER`,MySQL 为 `BIGINT` - 索引变更在 SQLite 下通过 batch 模式处理 ### 8.3 执行迁移 ```bash FLASK_APP=run.py .venv/bin/flask db upgrade ``` 说明: - 在执行任何 `seed-*` 命令前,应先运行 `flask db upgrade` - 若只是本地快速初始化,也可使用 `flask init-db` 直接 `create_all()` ### 8.4 初始化数据命令 创建管理员账号: ```bash FLASK_APP=run.py .venv/bin/flask seed-admin ``` 初始化基础选项: ```bash FLASK_APP=run.py .venv/bin/flask seed-options ``` 同时初始化管理员和基础选项: ```bash FLASK_APP=run.py .venv/bin/flask seed-all ``` 说明: - `seed-admin` 默认创建 `admin` 账号 - `seed-all` 首次执行会创建管理员和 14 条基础 `option_items` - `seed-demo` 首次执行会创建 2 个演示账号和 3 户演示 household + member 数据 - `seed-stress` 用于生成大规模压力测试数据,默认创建 `1000` 户、平均每户 `4` 人、`STRESS-` 前缀的 household / member 数据 - 重复执行具备幂等性,不会重复插入已有数据 - 若数据库尚未建表,会明确提示:先执行 `flask db upgrade` 或 `flask init-db` 新增演示数据命令: ```bash FLASK_APP=run.py .venv/bin/flask seed-demo ``` 新增压力测试数据命令: ```bash FLASK_APP=run.py .venv/bin/flask seed-stress ``` 常见自定义用法: ```bash FLASK_APP=run.py .venv/bin/flask seed-stress --household-count 500 --members-per-household 3 --prefix TEST- ``` ## 9. 当前实现范围 当前已经落地: 1. Flask 应用工厂 `create_app()` 2. 数据库扩展初始化 3. 健康检查路由 4. 六个核心模型: - `Account` - `Household` - `HouseholdMember` - `GiftRecord` - `AuditLog` - `OptionItem` 5. 跨 SQLite / MySQL 的统一 ID 类型兼容方案 6. Flask-Migrate / Alembic 迁移能力 7. seed 初始化命令 8. 最小认证闭环(登录 / 登出 / Session / 当前用户上下文 / 角色边界) 9. 审计日志基础写入(认证链路) 10. SSR 页面闭环(登录页、带左侧边栏的管理端页面、管理首页只读总览、管理端单条编辑页、管理端新增一户页、长辈专用搜索与有限字段编辑页、账号管理页、审计日志页) 11. household 页面服务层(统计、搜索、管理员/长辈表单解析、脱敏展示、建议户编码与新建 draft) 12. 认证与业务保存审计日志(`update_household_entry` / `update_household` / `create_household` / `create_account` / `update_account` / `reset_password` / `toggle_account_status`) 13. 长辈专用编辑页保存前确认摘要与显式防误操作提示 14. 长辈专用编辑页未保存离开提醒与儿童人数前端校验 15. 管理首页与长辈页基于 partial HTML 的动态刷新(300ms debounce + fetch + DOM 局部替换) 16. 独立统计与报表页 `/reports` 17. 长辈页移动端优先 bottom-sheet 编辑交互 18. light / dark 双主题切换与通用组件样式层 19. 压力测试数据生成命令 `seed-stress` 20. 页面相关测试与 Playwright 端到端测试(请以最新一次本地运行结果为准) 当前**已完成的核心可用版本闭环**: - 管理页搜索、组合筛选、排序、筛选统计、单条编辑与新增一户 - 管理页 live refresh、筛选结果 partial、低频导入导出入口右上角收纳 - 管理端家庭成员管理(HouseholdMember):成员列表、新增、编辑、删除与审计日志 - 管理端礼金明细管理(gift_records):明细列表、新增、编辑、软删除、自动汇总回写与审计日志 - 长辈页搜索、结果实时刷新、目标确认与 bottom-sheet 有限字段编辑 - 独立统计与报表页(总览卡片、礼金 Top 10、最近更新) - 账号管理页与审计日志页 - 认证与关键业务保存审计 - 中文 / 拼音 / 首字母搜索 - CSV 模板下载、导出全部、导出当前筛选、上传预览、校验、冲突处理、确认导入与导入审计 当前**仍待后续优化 / 迭代**: - 更丰富的统计报表与历史往来分析 - 桌席安排与婚宴现场协作能力 - CSRF 与更多正式发布前安全加固 ## 10. 配置说明 配置文件位于:`app/config.py` 当前提供: - `BaseConfig` - `ProductionConfig` - `TestConfig` - `CONFIG_MAPPING` 数据库连接优先级: 1. 环境变量 `DATABASE_URL` 2. 默认 SQLite:`sqlite:///instance/happywedding.db` 当前生产配置已落地: - `ProductionConfig` 已启用 `SESSION_COOKIE_SECURE=True` - `ProductionConfig` 已设置 `PREFERRED_URL_SCHEME=https` - `ProductionConfig.validate()` 会强制检查 `HW_SECRET_KEY` 与 `DATABASE_URL` - `ProductionConfig` 已包含基础数据库连接池参数(`pool_pre_ping`、`pool_recycle`) - 正式生产部署文档与容器化部署脚本见 `docs/production-deployment.md` 仍建议后续按正式上线需要继续补充: - 更细粒度的日志配置 - 面向生产环境的更多安全加固(例如 CSRF) ## 11. 当前模型设计提醒 ### 11.1 JSON 字段 以下字段当前使用 JSON 语义: - `households.tag_option_ids_json` - `option_items.extra_json` - `audit_logs.before_data_json` - `audit_logs.after_data_json` 当前约定: - MySQL 使用 JSON 类型 - SQLite 本地测试通过 SQLAlchemy 兼容能力处理 - MVP 阶段尽量避免依赖数据库方言差异较大的 JSON 条件查询 ### 11.2 聚合字段 `households.total_gift_amount` 是聚合展示字段。 当前管理员侧已完成礼金明细增删改与软删除,且会同步重算该字段,避免与 `gift_records` 脱节。 ### 11.3 乐观锁 `households.version` 已保留。 后续管理页和长辈页在保存户级数据时,应基于该字段实现乐观锁校验。 ## 12. 当前阶段说明 当前仓库已经完成核心可用版开发,并补齐 Linux 单机生产容器化部署文档与配套脚本。按照当前约定,功能需求先暂停扩展,本阶段以部署落地、文档同步与必要修复为主。 如未来恢复功能迭代,可优先参考以下方向: 1. 桌席安排与更完整的婚宴现场协作能力 2. CSRF 与更多正式发布前安全加固 3. 统计报表、历史往来与数据沉淀能力增强 ## 13. 开发命令速查 ### 初始化 / 更新依赖 ```bash .venv/bin/python -m pip install -r requirements.txt ``` ### 运行测试 ```bash .venv/bin/python -m pytest tests ``` ### 运行 E2E 测试 ```bash .venv/bin/python -m pytest tests/e2e -q ``` ### 安装 Playwright 浏览器 ```bash .venv/bin/python -m playwright install chromium ``` ### 启动服务 ```bash npm run build:css .venv/bin/python run.py ``` ### 一键开发启动 ```bash .venv/bin/python -m flask dev-bootstrap ``` ### 生成并执行迁移 ```bash FLASK_APP=run.py .venv/bin/flask db migrate -m "Your migration message" FLASK_APP=run.py .venv/bin/flask db upgrade ``` ### 初始化基础数据 ```bash FLASK_APP=run.py .venv/bin/flask seed-all ``` ### 初始化演示数据 ```bash FLASK_APP=run.py .venv/bin/flask seed-demo ``` ### 初始化压力测试数据 ```bash FLASK_APP=run.py .venv/bin/flask seed-stress ``` ### 认证基础能力验证 启动应用后,可验证以下最小链路: 1. 访问 `/auth/login` 打开登录页。 2. 使用 `flask seed-admin` 或 `flask seed-all` 创建的管理员账号登录。 3. `admin` / `editor` 登录后默认跳转到 `/`。 4. `entry_only` 登录后默认跳转到 `/entry/`。 5. 未登录访问 `/` 或 `/entry/` 会被重定向到登录页。 6. 认证相关关键事件会写入 `audit_logs`:登录成功、登录失败、停用账号登录、登出、未登录访问受限页、越权访问。 当前已落地的权限边界: - `admin` / `editor`:可进入管理首页 `/` - `admin` / `editor` / `entry_only`:可进入长辈录入页 `/entry/` - `entry_only`:不能停留在管理首页,会被重定向回 `/entry/` ### 查看当前 Git 状态 ```bash git status --short ```