You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

17 KiB

HappyWedding 开发环境与启动说明

本文档用于固定 HappyWedding(简称 hw)当前阶段的本地开发方式,重点说明如何使用项目内 .venv 进行依赖安装、运行测试和启动应用。

说明:本文件里若出现旧 /entry、旧长辈登录流或 bottom-sheet 编辑流的描述,请将其视为历史兼容信息。当前产品交互与页面边界以现代码为准:后台主页面、/quick-entry/s/{token}。系统初始化后不预置默认标签;户搜索统一围绕户主、成员、拼音、标签、备注。

1. 项目名称

  • 项目全名:HappyWedding
  • 项目简写:hw

2. 当前技术基线

  • 后端:Python 3 + Flask
  • ORM:Flask-SQLAlchemy / SQLAlchemy 2.x
  • 前端:SSR 模板 + 原生 JavaScript 交互增强 + 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. 当前目录结构

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
│   │   ├── quick_entry.py
│   │   ├── health.py
│   │   ├── main.py
│   │   ├── share.py
│   │   └── admin.py
│   ├── services/
│   │   ├── __init__.py
│   │   ├── audit.py
│   │   ├── demo_seed.py
│   │   ├── households.py
│   │   └── csv_tools.py
│   ├── static/
│   └── templates/
├── migrations/
├── docs/
│   ├── technical-design.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,可执行:

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt

如果 .venv 已存在,更新依赖可执行:

.venv/bin/python -m pip install -r requirements.txt

如果仓库中还没有前端依赖,或 Tailwind 样式源文件有更新,请执行:

npm install

首次使用或样式有改动后,先编译一次 CSS:

npm run build:css

如需持续调样式,建议额外开启监听:

npm run watch:css

6. 启动应用

当前项目已实现 Flask 应用工厂和健康检查路由。

6.1 一键开发启动(推荐)

npm run build:css
.venv/bin/python -m flask dev-bootstrap

默认会自动完成:

  • 执行数据库迁移 flask db upgrade
  • 初始化基础种子 flask seed-all
  • 初始化演示账号与演示户数据 flask seed-demo
  • 输出可直接登录的演示账号
  • 启动本地 Flask 开发服务

如只想准备数据但暂时不启动服务,可执行:

.venv/bin/python -m flask dev-bootstrap --skip-server

如果当前正在做样式开发,推荐使用两个终端:

# 终端 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 直接运行

.venv/bin/python run.py

默认行为:

  • 使用 development 配置
  • 若未设置 DATABASE_URL,默认使用 SQLite 本地库
  • SQLite 文件默认位于:instance/happywedding.db

6.3 健康检查

启动后可访问:

GET /health

预期返回:

{
  "project": "HappyWedding",
  "short_name": "hw",
  "status": "ok"
}

7. 运行测试

当前基础测试覆盖:

  • create_app("testing") 是否成功创建应用
  • /health 路由是否可访问
  • 六张核心表是否进入元数据
  • 关键字段是否存在
  • 核心外键是否存在
  • 关键唯一约束是否存在

执行单元 / 页面测试命令:

.venv/bin/python -m pytest tests

执行 Playwright 端到端测试前,需先安装浏览器:

.venv/bin/python -m playwright install chromium

执行 E2E 测试:

.venv/bin/python -m pytest tests/e2e -q

当前 E2E 目录中的核心用例包括:

  • tests/e2e/test_core_flow_admin_edit.py:管理员登录 → 搜索/筛选 → 打开编辑页 → 保存
  • tests/e2e/test_entry_flow.pyentry_only 账号登录 → 快速录入搜索 → 单独编辑页保存
  • tests/e2e/test_share_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 越权回跳 → 退出登录
  • tests/e2e/test_theme_flow.py:主题切换与跨页面持久化

当前状态:

  • 测试应通过 .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 /?partial=resultsGET /quick-entry/?partial=search-resultsGET /s/{token}?partial=results
  • 当前最新一次验证结果请以本地实际运行输出为准,避免文档中的固定数字滞后于代码演进

8. 数据库迁移与初始化命令

当前项目已接入 Flask-Migrate / Alembic,并已生成首个 migration 文件。

8.1 初始化迁移目录(首次执行)

FLASK_APP=run.py .venv/bin/flask db init

说明:

  • 该命令只需首次执行一次
  • 当前仓库已经生成了 migrations/ 目录与首个 migration 文件

8.2 生成迁移脚本

FLASK_APP=run.py .venv/bin/flask db migrate -m "Initial migration"

当前已验证:

  • SQLite 本地下可正常生成 migration
  • 生成结果会保留跨库 ID 类型定义:SQLite 为 INTEGER,MySQL 为 BIGINT
  • 索引变更在 SQLite 下通过 batch 模式处理

8.3 执行迁移

FLASK_APP=run.py .venv/bin/flask db upgrade

说明:

  • 在执行任何 seed-* 命令前,应先运行 flask db upgrade
  • 若只是本地快速初始化,也可使用 flask init-db 直接 create_all()

8.4 初始化数据命令

创建管理员账号:

FLASK_APP=run.py .venv/bin/flask seed-admin

初始化基础选项:

FLASK_APP=run.py .venv/bin/flask seed-options

同时初始化管理员和基础选项:

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 upgradeflask init-db

新增演示数据命令:

FLASK_APP=run.py .venv/bin/flask seed-demo

新增压力测试数据命令:

FLASK_APP=run.py .venv/bin/flask seed-stress

常见自定义用法:

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. 管理首页、快速录入页与分享页基于 partial HTML 的动态刷新(300ms debounce + fetch + DOM 局部替换)
  15. 快速录入页当天默认值与最小新增流程
  16. 管理首页统计摘要与筛选结果页
  17. light / dark 双主题切换与通用组件样式层
  18. 压力测试数据生成命令 seed-stress
  19. 页面相关测试与 Playwright 端到端测试(请以最新一次本地运行结果为准)

当前已完成的核心可用版本闭环

  • 管理页搜索、组合筛选、排序、筛选统计、单条编辑与新增一户
  • 管理页 live refresh、筛选结果 partial、低频导入导出入口右上角收纳
  • 管理端家庭成员管理(HouseholdMember):成员列表、新增、编辑、删除与审计日志
  • 管理端礼金明细管理(gift_records):明细列表、新增、编辑、软删除、自动汇总回写与审计日志
  • 快速录入页搜索、结果实时刷新、单独编辑页 / 新增页的当天录礼金流程
  • 分享页搜索、结果实时刷新、单独编辑页保存后返回搜索
  • 管理首页统计摘要(总览卡片、结果统计、最近更新驱动的排序入口)
  • 账号管理页与审计日志页
  • 认证与关键业务保存审计
  • 中文 / 拼音 / 首字母搜索
  • 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_KEYDATABASE_URL
  • ProductionConfig 已包含基础数据库连接池参数(pool_pre_pingpool_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. 开发命令速查

初始化 / 更新依赖

.venv/bin/python -m pip install -r requirements.txt

运行测试

.venv/bin/python -m pytest tests

运行 E2E 测试

.venv/bin/python -m pytest tests/e2e -q

安装 Playwright 浏览器

.venv/bin/python -m playwright install chromium

启动服务

npm run build:css
.venv/bin/python run.py

一键开发启动

.venv/bin/python -m flask dev-bootstrap

生成并执行迁移

FLASK_APP=run.py .venv/bin/flask db migrate -m "Your migration message"
FLASK_APP=run.py .venv/bin/flask db upgrade

初始化基础数据

FLASK_APP=run.py .venv/bin/flask seed-all

初始化演示数据

FLASK_APP=run.py .venv/bin/flask seed-demo

初始化压力测试数据

FLASK_APP=run.py .venv/bin/flask seed-stress

认证基础能力验证

启动应用后,可验证以下最小链路:

  1. 访问 /auth/login 打开登录页。
  2. 使用 flask seed-adminflask seed-all 创建的管理员账号登录。
  3. admin / editor 登录后默认跳转到 /
  4. entry_only 登录后默认跳转到 /quick-entry/
  5. 未登录访问 //quick-entry/ 会被重定向到登录页。
  6. 认证相关关键事件会写入 audit_logs:登录成功、登录失败、停用账号登录、登出、未登录访问受限页、越权访问。

当前已落地的权限边界:

  • admin / editor:可进入管理首页 /
  • admin / editor / entry_only:可进入快速录入页 /quick-entry/
  • entry_only:不能停留在管理首页,会被重定向回 /quick-entry/

查看当前 Git 状态

git status --short