# CONDO Owner Desk CONDO Owner Desk 是一套面向酒店公寓运营团队的业主年度住宿权益管理系统。它把业主账户、房型规则、入住使用记录和年度剩余权益集中在一个工作台中,并由后端统一计算房晚、扣减倍率和余额,避免浏览器直接修改权威数据。 当前版本由原生 Web 前端、TypeScript/Fastify API 和 PostgreSQL 数据层组成,可通过 Docker 部署,也可使用 Mock API 或本地历史审计快照进行演示。 ## 主要功能 - 受保护的运营人员登录、12 小时 HttpOnly 会话和主动退出。 - Dashboard 展示业主房间数、剩余权益、已用权益、房型分布与月度使用情况。 - 按编号、业主、房号、单元号、会员号和房型查询业主账户。 - 查询、筛选和分页浏览使用记录及业主详情。 - 新增使用记录时预览扣减结果;Night、倍率、Use 和 Balance 最终由后端计算。 - 删除使用记录时通过事务恢复账户余额。 - 英语、简体中文和泰语界面切换。 - 支持 PostgreSQL 持久化模式、完整历史快照预览模式和内置原型数据模式。 ## 系统架构 ```mermaid flowchart LR Browser[浏览器
HTML / CSS / JavaScript] Nginx[Nginx
静态资源与 /api 反向代理] API[Fastify API
认证、校验、业务事务] DB[(PostgreSQL
booking_test / condon)] Browser --> Nginx Nginx --> API API --> DB ``` - 前端没有打包步骤,可直接由任意静态 Web 服务器托管。 - Docker 模式下,浏览器只访问 Nginx;`/api/*` 被同源代理到后端,后端端口不对外发布。 - PostgreSQL 不包含在 `docker-compose.yml` 中,后端连接现有的 `booking_test` 数据库,并且只使用隔离的 `condon` schema。 - 浏览器不接触数据库凭据,也不直接连接 PostgreSQL。 ## 快速体验 ### 前置条件 - Node.js 24 或更高版本。 - Python 3(仅用于下面的本地静态文件服务;也可换成其他静态服务器)。 ### 使用内置原型数据 这是全新克隆仓库后最容易复现的方式,不需要 PostgreSQL,也不会写入真实数据。 在第一个终端启动本地认证 Mock API: ```bash node tests/mock-api-server.mjs ``` 在第二个终端从仓库根目录启动前端: ```bash python3 -m http.server 4173 --bind 127.0.0.1 ``` 打开 ,使用本地开发账号登录: ```text Username: wyndhamcondon Password: wyndhamcondon ``` `?mode=demo` 使用前端内置的 190 条原型账户;登录由 Mock API 完成。演示期间新增或删除的数据只保存在当前进程内存中,进程重启后恢复初始状态。 > 默认账号只用于本地开发和演示。任何共享或生产环境都必须通过环境变量更换密码。 ## 运行模式 ### 1. PostgreSQL 持久化模式 前端默认运行在 API 模式。后端需要可访问且已经应用 `condon` 迁移的 `booking_test` 数据库。 ```bash cd backend npm ci cp .env.example .env ``` 编辑 `.env` 中的数据库连接和认证信息,然后在 zsh/bash 中加载环境变量并启动后端: ```bash set -a source .env set +a npm run dev ``` 另开终端,在仓库根目录启动前端: ```bash python3 -m http.server 4173 --bind 127.0.0.1 ``` 打开 。前端会连接当前主机的 `3000` 端口,并在认证成功后加载数据库中的业主、使用记录和 Dashboard 聚合数据。 数据库迁移、导入和只读部署验证需要额外的运维步骤,详见 [后端说明](./backend/README.md) 和 [Docker 部署说明](./DOCKER_DEPLOYMENT.md)。 ### 2. 完整历史快照预览 历史预览不连接 PostgreSQL,提供与正式 API 相同的认证和业务接口。但预览所需的审计 JSON 含业务数据,位于 Git 忽略目录,**不会随仓库克隆或推送**。 只有已安全取得该批次材料时才可使用此模式。默认目录为: ```text .planning/data_import_audit/import_batch_2026_07_31 ``` 也可以通过 `CONDO_IMPORT_SNAPSHOT_DIR` 指向外部安全目录。准备好材料后执行: ```bash cd backend npm ci npm run build npm run preview:history:check npm run preview:history ``` 再从仓库根目录启动 `4173` 端口的前端并打开默认 URL。快照写入只存在内存中,预览进程停止后即丢失。 当前脚本校验的历史基线为:388 个业主账户、157 条使用记录、2026 年已使用 438 个权益晚、剩余 5,394 个权益晚。 ### 3. Docker 部署 复制生产环境示例文件: ```bash cp deploy/.env.production.example .env ``` 至少填写 `DB_HOST`、`DB_USER`、`DB_PASSWORD` 和 `AUTH_PASSWORD`。如果不是通过 `http://localhost:8080` 访问,还要把 `CORS_ORIGINS` 改为浏览器实际访问的完整 Origin;HTTPS 环境应设置 `AUTH_COOKIE_SECURE=true`。 ```bash docker compose build docker compose up -d ``` 默认访问地址为 。停止服务: ```bash docker compose down ``` 部署拓扑、迁移命令和连接输入格式见 [Docker 部署说明](./DOCKER_DEPLOYMENT.md)。 ## 核心业务规则 每个业主房号独立拥有年度权益期间,当前默认年度新增为 15 晚,可包含上一年度结转。一次使用的权威计算为: ```text Night = Check-out - Check-in Multiplier = max(1, Used Tier - Purchased Tier + 1) Use = Night × Multiplier Balance After = Balance Before - Use ``` 房型分级如下: | Tier | 房型 | | --- | --- | | 1 | RM1、RM2、RM3、RM4、UG1、UG2 | | 2 | SU1、SU2、SU6 | | 3 | SU3 | AC2 不进入自动分级;购买房型或使用房型涉及 AC2 时,运营人员必须选择 1–3 的人工倍率,后端再次校验。 使用记录创建和删除、权益流水及当前余额在 PostgreSQL 事务中同步更新。系统拒绝余额不足、日期无效、跨权益年度、房型规则不符和幂等键冲突等请求。完整表结构和规则见 [后端数据模型](./backend-data-model.md)。 ## API 概览 除三个 `/auth/*` 接口和 CORS 预检外,其他接口(包括 `/docs`)都要求有效的 `condon_session` Cookie。 | Method | Path | 说明 | | --- | --- | --- | | POST | `/auth/login` | 登录并创建会话 | | GET | `/auth/session` | 查询当前会话 | | POST | `/auth/logout` | 注销当前会话 | | GET | `/health` | 检查数据库、schema 和迁移版本 | | GET | `/room-types` | 获取房型与倍率规则元数据 | | GET | `/owner-accounts` | 搜索和分页查询业主账户 | | GET | `/owner-accounts/:id` | 查询业主账户详情与年度余额 | | GET | `/usage-records` | 查询使用记录 | | POST | `/usage-records` | 事务性新增使用记录并扣减余额 | | DELETE | `/usage-records/:id` | 事务性删除使用记录并恢复余额 | | GET | `/dashboard` | 查询年度 Dashboard 聚合 | 后端运行时可通过 `/docs` 查看 OpenAPI UI。请求字段、返回模型和数据库函数详见 [后端说明](./backend/README.md)。 ## 主要配置 后端本地配置模板为 [`backend/.env.example`](./backend/.env.example),Docker 配置模板为 [`deploy/.env.production.example`](./deploy/.env.production.example)。 | 变量 | 默认值/要求 | 用途 | | --- | --- | --- | | `API_HOST` | `127.0.0.1` | 后端监听地址 | | `API_PORT` | `3000` | 后端监听端口 | | `CORS_ORIGINS` | 本地 `4173` Origin | 允许携带 Cookie 的前端来源,逗号分隔 | | `AUTH_USERNAME` | 本地默认 `wyndhamcondon` | 运营登录名 | | `AUTH_PASSWORD` | 生产必须设置 | 运营登录密码 | | `AUTH_SESSION_TTL_HOURS` | `12` | 会话有效期,允许 1–168 小时 | | `AUTH_COOKIE_SECURE` | 生产默认 `true` | 是否只通过 HTTPS 发送 Cookie | | `DB_HOST` / `DB_USER` / `DB_PASSWORD` | 必填 | PostgreSQL 连接信息 | | `DB_NAME` | 必须为 `booking_test` | 防止误连其他数据库 | | `DB_SSL` | `false` | 是否启用数据库 SSL | | `CONDO_API_BASE_URL` | Docker 默认 `/api` | 前端 API 根地址 | | `CONDO_DEFAULT_MODE` | `api` | 前端默认数据模式 | | `CONDO_PERIOD_YEAR` | 当前 UTC 年 | Dashboard 与账户权益年度 | 应用不会自动读取 `.env` 文件;本地运行需要先把其中的值导出到当前 shell。不要提交真实环境文件或凭据。 ## 目录结构 ```text . ├── index.html / styles.css / app.js # 原生前端界面与交互 ├── api-client.js / runtime-config.js # API 客户端与前端运行时配置 ├── owners-data.js # demo 模式原型数据 ├── backend/ │ ├── src/ # Fastify API、认证、仓储和配置 │ ├── migrations/ # condon schema SQL 迁移 │ ├── scripts/ # 迁移、导入、冒烟和部署验证工具 │ └── tests/ # 后端单元与仓储测试 ├── tests/ # 前端 Node 测试和 Mock API ├── deploy/ # Nginx 与 Docker 运行时配置 ├── docker-compose.yml # 前后端容器编排 ├── backend-data-model.md # 数据模型与业务规则规格 └── DOCKER_DEPLOYMENT.md # Docker 运维说明 ``` `业主账户.md` 和 `使用记录.md` 是历史业务资料摘要,含个人与运营数据。共享、复制或导出前请遵循适用的数据保护要求。 ## 开发与验证 前端测试: ```bash node --test tests/*.test.mjs ``` 后端检查: ```bash cd backend npm ci npm run typecheck npm test npm run build npm run db:check-migrations ``` 需要真实数据库的命令包括 `db:inventory`、`db:migrate:up`、`db:verify`、`db:verify-import` 和 `db:test-integration`。其中 `db:test-integration` 只允许针对空的测试 schema 执行,不能用于已导入业务数据的环境。 ## 安全与当前边界 - 生产环境必须更换默认登录凭据,并通过 Secret Manager 或运行时环境变量注入数据库密码。 - 会话令牌只通过 HttpOnly Cookie 发送,服务端只保存其 SHA-256 键;当前会话存储在后端内存中,后端重启后所有会话失效。 - 后端日志对 Cookie、认证信息和数据库密码做脱敏处理。 - 当前版本是单一运营账号模型,尚未实现多用户身份、角色权限和持久化会话。 - 当前不支持人工余额调整或跨权益年度入住。 - 数据库回滚属于显式运维操作;业务数据导入后不要执行迁移回滚。 ## 相关文档 - [后端 API、数据库命令与验证](./backend/README.md) - [后端数据模型与业务规则](./backend-data-model.md) - [Docker 部署与数据库运维](./DOCKER_DEPLOYMENT.md) - [前端设计系统](./design-system/condo-owner-desk/MASTER.md)