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 行,每条事件按告警哈希链接到前一事件。 - 验证端点会重新计算哈希并报告完整性结果。 ## 图表 ### 架构图 ![CrisisBridge 架构图](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/4cb7daca03123409.svg) ### 宾客告警流程图 ![宾客告警流程图](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/ab22419d7f123411.svg) ### 员工处理流程图 ![员工处理流程图](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/51d9571d03123412.svg) ## 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, 事件升级, 二维码, 优先级面板, 后台管理, 实时事件, 实时数据库, 审计日志, 客诉处理, 宾客安全, 工作流, 库, 应急响应, 房间预订, 技术栈, 数据完整性, 管理控制台, 紧急协调平台, 背景同步, 自定义脚本, 酒店业