MdTowfikomer/CrisisBridge
GitHub: MdTowfikomer/CrisisBridge
专注于酒店场景的紧急协调平台,实现宾客到员工的快速事件响应与流程管理。
Stars: 1 | Forks: 0
# CrisisBridge
CrisisBridge 是一个专注于酒店场景的紧急协调平台,用于实现快速的宾客与员工事件响应。它包含宾客紧急触发界面、响应者仪表板,以及一个专用的管理控制台,提供实时事件可见性、房间二维码/NFC 配置、升级工作流和防篡改事件日志。
## 关键特性
- 宾客紧急触发流程(火灾、安保、医疗),并附带上下文房间/物业元数据
- 实时事件订阅源,供响应者和酒店管理员使用(Firebase RTDB)
- 专用管理路由(`/admin`),包含左侧导航与实时优先级事件面板
- B2B 房间配置 API(签名房间链接、QR 工件、CSV 导出、NFC 载荷支持)
- 未确认告警的升级管道
- 防篡改的追加型审计账本与完整性验证端点
- 支持后台同步重试的 PWA 服务工作器(用于分诊请求)
## 目录
- [技术栈](#tech-stack)
- [仓库结构](#repository-structure)
- [前置条件](#prerequisites)
- [快速开始](#getting-started)
- [环境变量](#environment-variables)
- [本地运行应用](#run-the-app-locally)
- [路由与视图](#routes-and-views)
- [架构与数据流](#architecture-and-data-flow)
- [图表](#diagrams)
- [API 参考](#api-reference)
- [可用脚本](#available-scripts)
- [故障排查](#troubleshooting)
- [发布到 GitHub](#publish-to-github)
- [团队笔记](#team-notes)
## 技术栈
| 层级 | 技术 |
| --- | --- |
| 单体仓库 | pnpm workspaces |
| 前端 | React 19, Vite 8, Tailwind CSS |
| 后端 | Fastify 5, Zod |
| AI | Google Gemini(`@google/genai`) |
| 实时数据 | Firebase Realtime Database |
| 事件记录 | Firebase + 防篡改服务器账本 |
| 升级机制 | SendGrid |
| 离线重试 | Workbox Background Sync(`vite-plugin-pwa`) |
## 仓库结构
```
CrisisBridge/
├─ apps/
│ ├─ web/ # React guest/admin/responder UI
│ │ ├─ src/
│ │ │ ├─ components/
│ │ │ │ ├─ AdminConsole.jsx
│ │ │ │ ├─ ResponderDashboard.jsx
│ │ │ │ ├─ ProvisioningDashboard.jsx
│ │ │ │ └─ FlareTrigger.jsx
│ │ │ ├─ lib/firebase.js
│ │ │ ├─ sw.js
│ │ │ └─ assets/ # Architecture + process diagrams
│ │ ├─ .env.example
│ │ └─ vite.config.js
│ └─ server/ # Fastify API and incident services
│ ├─ services/
│ │ ├─ triage.js
│ │ ├─ escalation.js
│ │ ├─ propertyProvisioning.js
│ │ └─ auditLedger.js
│ ├─ data/ # Runtime audit ledger file (ignored)
│ ├─ .env.example
│ └─ index.js
├─ packages/
│ └─ types/ # Shared Zod schemas
├─ CrisisBridge_Workflow.md
└─ package.json
```
## 前置条件
- **Node.js** 20+
- **pnpm** 10+(仓库使用 `pnpm@10.15.1`)
- 一个 **Firebase 项目**,需包含:
- 已启用的实时数据库
- 已启用的 Firestore
- 完整功能所需(可选):
- Google Gemini API 密钥(AI 分诊 + 摘要质量)
- SendGrid API 密钥(邮件升级)
## 快速开始
### 1. 克隆仓库
```
git clone
cd CrisisBridge
```
### 2. 安装依赖
```
pnpm install
```
### 3. 创建本地环境文件
PowerShell:
```
Copy-Item apps\web\.env.example apps\web\.env
Copy-Item apps\server\.env.example apps\server\.env
```
Bash:
```
cp apps/web/.env.example apps/web/.env
cp apps/server/.env.example apps/server/.env
```
### 4. 填写环境变量
请参考 [环境变量](#environment-variables) 中的表格。
### 5. 启动开发环境
```
pnpm dev
```
这将同时启动:
- Web:`http://localhost:5173`
- 服务器:`http://localhost:3001`
## 环境变量
### `apps/web/.env`
| 变量 | 是否必需 | 描述 | 示例 |
| --- | --- | --- | --- |
| `VITE_BACKEND_URL` | 否 | 前端使用的后端基础 URL;本地请保持 `/api` 以使用 Vite 代理 | `/api` |
| `VITE_FIREBASE_API_KEY` | 是 | Firebase Web API 密钥 | `AIza...` |
| `VITE_FIREBASE_AUTH_DOMAIN` | 是 | Firebase 认证域 | `your-project.firebaseapp.com` |
| `VITE_FIREBASE_DATABASE_URL` | 是 | 实时数据库 URL | `https://your-project-default-rtdb.firebaseio.com` |
| `VITE_FIREBASE_PROJECT_ID` | 是 | Firebase 项目 ID | `your-project` |
| `VITE_FIREBASE_STORAGE_BUCKET` | 是 | Firebase 存储桶 | `your-project.appspot.com` |
| `VITE_FIREBASE_MESSAGING_SENDER_ID` | 是 | Firebase 发送者 ID | `1234567890` |
| `VITE_FIREBASE_APP_ID` | 是 | Firebase 应用 ID | `1:1234567890:web:abcd1234` |
### `apps/server/.env`
| 变量 | 是否必需 | 描述 | 示例 |
| --- | --- | --- | --- |
| `GEMINI_API_KEY` | 推荐 | AI 分诊与摘要生成;若缺失将使用降级逻辑 | `AIza...` |
| `SENDGRID_API_KEY` | 可选 | 升级邮件发送密钥 | `SG.xxxxx` |
| `ESCALATION_EMAIL_TO` | 若启用 SendGrid 则必需 | 升级接收邮箱 | `security.lead@hotel.example` |
| `ESCALATION_EMAIL_FROM` | 若启用 SendGrid 则必需 | SendGrid 中已验证的发件人邮箱/域 | `crisisbridge@hotel.example` |
| `GUEST_APP_BASE_URL` | 推荐 | 用于生成房间二维码/NFC 链接的基础 URL | `http://localhost:5173` |
| `ROOM_LINK_SIGNING_SECRET` | **生产环境必需** | 房间链接签名的密钥 | `long-random-secret` |
## 本地运行应用
### 推荐方式(启动全部服务)
```
pnpm dev
```
### 分别运行服务
```
pnpm dev:web
pnpm dev:server
```
### 快速本地验证
1. 打开宾客 UI:`http://localhost:5173/?property=HOTEL-101&room=305`
2. 打开管理 UI:`http://localhost:5173/admin`
3. 触发一次宾客告警,并确认其在管理端实时出现。
4. 从管理端或响应者端确认并解决。
5. 检查后端健康状态:`http://localhost:3001/health`
6. 验证审计日志(替换告警 ID):
```
curl http://localhost:3001/audit/
```
## 路由与视图
| 路由 | 用途 |
| --- | --- |
| `/` | 宾客紧急触发视图 |
| `/?property=HOTEL-101&room=305` | 限定物业与房间的宾客视图 |
| `/?entry=nfc&property=HOTEL-101&room=305` | 通过 NFC 上下文打开的宾客视图 |
| `/admin` | 酒店管理控制台(默认显示实时事件) |
| `/admin/overview` | KPI 概览 |
| `/admin/provisioning` | 二维码/CSV 房间配置 |
| `/admin/nfc` | NFC 标签/贴纸工作流 |
| `/responder` | 响应者操作仪表板 |
## 架构与数据流
### 运行时流程
1. 宾客在 Web 应用中触发紧急事件。
2. 前端调用后端 `POST /triage`。
3. 后端通过 Gemini 进行分类(或降级处理),启动升级计时器,并追加审计事件。
4. 前端将告警写入 Firebase RTDB(路径:`alerts/*`)。
5. 管理端与响应者仪表板订阅 RTDB 并实时更新。
6. 确认或解决后,仪表板更新 RTDB 状态并调用后端生命周期端点。
7. 后端写入哈希链式审计事件,并可通过 `/audit/:alertId` 验证链完整性。
### B2B 房间配置流程
1. 管理员请求某物业的房间工件。
2. 后端为每个房间生成签名宾客 URL,用于二维码/NFC 入内。
3. 管理员下载 CSV 清单,并通过浏览器 Web NFC 写入标签(如支持)。
### 离线与重试行为
- 服务工作器使用 Workbox 的 `BackgroundSync` 缓存并重试 `POST /triage` 请求。
- 开发环境中的服务行为可能与生产不同;请通过 `build + preview` 模式验证离线重放。
### 审计账本行为
- 账本文件:`apps/server/data/incident-audit-ledger.jsonl`
- 格式:仅追加的 JSON 行,每条事件按告警哈希链接到前一事件。
- 验证端点会重新计算哈希并报告完整性结果。
## 图表
### 架构图

### 宾客告警流程图

### 员工处理流程图

## API 参考
基础 URL(本地):`http://localhost:3001`
前端本地代理路径:`/api` → `http://localhost:3001`
| 方法 | 端点 | 用途 |
| --- | --- | --- |
| `GET` | `/health` | 健康检查与账本文件路径 |
| `POST` | `/triage` | 创建分诊结果、升级计时器与审计触发事件 |
| `POST` | `/acknowledge` | 标记告警已确认并取消升级计时器 |
| `POST` | `/resolve` | 最终化事件,生成 AI 摘要并追加解决审计 |
| `GET` | `/audit/:alertId` | 检索事件记录并验证完整性 |
| `POST` | `/b2b/properties/:propertyId/provision` | 生成签名房间链接、QR 数据 URL 与 NFC 载荷 |
| `POST` | `/b2b/properties/:propertyId/provision/csv` | 导出房间配置清单 CSV |
### 示例:配置房间工件
```
curl -X POST "http://localhost:3001/b2b/properties/HOTEL-101/provision" \
-H "Content-Type: application/json" \
-d "{\"floorStart\":1,\"floorEnd\":2,\"roomsPerFloor\":5}"
```
## 可用脚本
### 根目录
| 命令 | 描述 |
| --- | --- |
| `pnpm dev` | 并行运行 Web 与服务器 |
| `pnpm dev:web` | 仅运行 Web 应用 |
| `pnpm dev:server` | 仅运行服务器 |
| `pnpm build` | 构建工作区(Web 构建) |
| `pnpm lint` | 运行工作区 Lint 任务 |
### Web(`apps/web`)
| 命令 | 描述 |
| --- | --- |
| `pnpm --filter web dev` | 启动 Vite 开发服务器 |
| `pnpm --filter web build` | 生产构建 |
| `pnpm --filter web preview` | 预览生产构建 |
| `pnpm --filter web lint` | Web 应用的 ESLint |
### 服务器(`apps/server`)
| 命令 | 描述 |
| --- | --- |
| `pnpm --filter server dev` | 在监听模式下启动 Fastify API |
| `pnpm --filter server start` | 启动 Fastify API |
## 故障排查
| 现象 | 可能原因 | 修复方法 |
| --- | --- | --- |
| 前端 `NetworkError when attempting to fetch resource` | 后端未运行或后端 URL 错误 | 启动服务器(`pnpm --filter server dev`)并保持本地 `VITE_BACKEND_URL=/api` |
| 告警未在管理/响应者端显示 | Firebase 配置或规则问题 | 验证 `apps/web/.env` 值与实时数据库规则/连接 |
| 配置端点失败 | 无效的 `propertyId` 或请求体格式 | 使用字母数字/短横线格式物业 ID,并校验请求体格式 |
| 升级邮件未发送 | SendGrid 变量缺失 | 设置 `SENDGRID_API_KEY`、`ESCALATION_EMAIL_TO`、`ESCALATION_EMAIL_FROM` |
| 离线重放在本地开发中不可见 | 开发模式下的服务行为差异 | 通过 `pnpm --filter web build && pnpm --filter web preview` 验证 |
## 发布到 GitHub
若这是该本地仓库的首次推送:
```
git init
git add .
git commit -m "Initial CrisisBridge setup"
git branch -M main
git remote add origin https://github.com//.git
git push -u origin main
```
若仓库已初始化,添加或更新远程并推送:
```
git remote -v
git remote set-url origin https://github.com//.git
git push -u origin main
```
## 团队笔记
- 密钥仅保存在本地 `.env` 文件中(绝不提交凭据)。
- `apps/server/data/*.jsonl` 被故意忽略(运行时审计工件)。
- `CrisisBridge_Workflow.md` 跟踪工作流级能力与就绪状态。
- 计划中的管理部分目前为占位符;当前实际运行中的部分包括:
- 实时事件
- 概览
- 房间配置 / NFC
标签:B2B API, Fastify, Firebase, NFC, PWA, QR码, React, SendGrid, Service Worker, Syscalls, Tailwind CSS, Tamper-evident, Vite, Zenmap, Zod, 事件升级, 二维码, 优先级面板, 后台管理, 实时事件, 实时数据库, 审计日志, 客诉处理, 宾客安全, 工作流, 库, 应急响应, 房间预订, 技术栈, 数据完整性, 管理控制台, 紧急协调平台, 背景同步, 自定义脚本, 酒店业