Haswanthkumar11/RescueLensAI
GitHub: Haswanthkumar11/RescueLensAI
一个 AI 驱动的应急救援图像分析平台,利用 Gemini 视觉模型对灾难图片进行风险分诊并自动生成事故报告,支持角色化仪表盘与完整的事件追踪流程。
Stars: 0 | Forks: 0
# 🚑 RescueLens AI
AI 驱动的紧急图像分诊系统,助力更快的灾难响应。
本仓库是项目说明书中描述架构的一个可用脚手架:
React + Vite + Tailwind 前端,FastAPI 后端,Gemini 2.5 Flash
视觉分析,确定性风险评分引擎,以及用于存储
+ 数据库的 Supabase。只要你添加了自己的 API key,它就可以端到端运行 —— 请参阅
下文的 **“运行此项目前你必须更新的内容”**。
## 项目结构
```
RescueLens/
├── frontend/ React + Vite + Tailwind
├── backend/ FastAPI
├── docs/
│ ├── ARCHITECTURE.md
│ └── supabase_schema.sql
└── README.md
```
## 快速开始
### 1. Supabase
1. 在 supabase.com 创建一个项目。
2. 打开 SQL 编辑器并运行 `docs/supabase_schema.sql`(全新项目) —
这现在包含了 `incidents`/`detections` 表 **以及**
`user_profiles` 表 + 认证触发器。如果你已经有一个旧版
数据库,请按顺序运行 `docs/migrations/` 中的迁移文件代替
(001 添加了事故时间线,002 添加了认证)。
3. 创建一个名为 `incident-images` 的 **public** 存储桶。
4. 复制你的 Project URL、`anon`/`public` key 和 `service_role` key
(Project Settings → API)。后端使用 service-role key;
前端使用 anon key。
5. 在 Authentication → Providers 中,确认 Email 已启用。在
Authentication → URL Configuration 中,将 `http://localhost:5173/**`
(以及以后你部署的前端 URL)添加到重定向允许列表中,否则
电子邮件验证 / 密码重置链接将不起作用。
6. **首个管理员账户**:通过应用程序注册一次(这将创建一个
默认为 `viewer` 的 `user_profiles` 行),然后在 SQL 编辑器中运行:
update user_profiles set role = 'admin' where email = 'you@example.com';
其他所有新注册的用户将保持为 `viewer`,直到管理员从
Profile → 管理工具中提升他们(`PATCH /profile/users/{id}/role`)。
### 2. 后端
```
cd backend
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # fill in GEMINI_API_KEY, SUPABASE_URL, SUPABASE_SERVICE_KEY
uvicorn app.main:app --reload --port 8000
```
访问 `http://localhost:8000/docs` 查看交互式 API 文档。
### 3. 前端
```
cd frontend
npm install
cp .env.example .env # set VITE_API_URL, VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY
npm run dev
```
访问 `http://localhost:5173`。
## 运行此项目前你必须更新的内容
这个脚手架代码已完成,但 **无法开箱即用** —— 有一些
地方需要真实的凭证或由你来决定:
1. **`backend/.env`** — 添加真实的 `GEMINI_API_KEY`(Google AI Studio)和你的
Supabase `SUPABASE_URL` / `SUPABASE_SERVICE_KEY`。没有这些,什么都无法运行。
2. **在首次请求之前**,在你的 Supabase 项目中 **运行 `docs/supabase_schema.sql`** —
后端假定 `incidents` 和 `detections` 表以及
`incident-images` 存储桶已经存在。
3. **Gemini 模型访问权限** — 模型是通过 `backend/.env` 中的 `GEMINI_MODEL`
设置的(默认为 `gemini-3.5-flash`)。如果 Google 废弃了该模型,或者你的 key
没有访问权限,只需更新这一个环境变量 — 无需更改代码。
4. **CORS origin** — `backend/.env` 中的 `FRONTEND_ORIGIN` 默认为
`http://localhost:5173`。一旦你部署了前端(Vercel URL),请更新它。
5. **`frontend/.env` → `VITE_API_URL`** — 在部署前端之前,将其指向你部署的后端
(Render URL),否则每个请求都会尝试访问
`localhost:8000`。
6. **`npm install`** 尚未在此脚手架中运行(生成时没有网络访问权限) —
`node_modules` 文件夹尚不存在,因此请在本地运行它
然后再执行 `npm run dev`。
7. **部署**:此脚手架不包含 `vercel.json` / `render.yaml`。
将 `frontend/` 部署到 Vercel(框架预设:Vite),并将 `backend/` 部署到
Render(构建:`pip install -r requirements.txt`,启动:
`uvicorn app.main:app --host 0.0.0.0 --port $PORT`) — 在那里设置与你的本地 `.env` 文件中相同的环境变量。
8. **认证**:有关完整的架构、
迁移顺序和故障排除,请参阅下文的“Authentication”部分。
9. **尚未根据“附加功能”列表实现的内容**(说明书要求挑选
2–3 个,所以我没有构建所有的):语音播报,图像对比
(“情况是否恶化”),多语言报告和二维码分享。PDF
导出 **已** 实现(`GET /incident/{id}/report.pdf`,已连接到
Result 和 History 页面)。如果你想要额外的润色,可以再选 1–2 个。
10. **加载页面** — 说明书将“加载屏幕”列为单独的页面;我
将其作为 Upload 页面上的就地状态实现,而不是一个
单独的路由,因为整个流程是一个单一的 upload → analyze 调用,
在请求中途更改路由只会增加复杂性而没有好处。如果你希望 URL 反映它,
以后很容易将其拆分为 `/loading`。
11. **用于测试的图像输入** — 你需要真实或图库的灾难照片
才能获得有意义的 Gemini 输出;风险引擎仅对 Gemini
实际检测到的内容进行评分。
## 身份验证
**架构。** 前端直接与 Supabase Auth 通信(电子邮件/密码、
验证电子邮件、密码重置) — 后端绝不会看到密码。每个
受保护的后端请求都带有 `Authorization: Bearer `;`app/services/auth.py` 会根据 Supabase 验证该 token,并从
`user_profiles` 加载调用者的角色。这里特意没有设计
`backend/app/routers/auth.py` / `/login` / `/register` 后端端点 —
重新实现 Supabase Auth 已经正确完成的工作意味着我们自己
处理密码,这没有任何好处。有关完整的图表,请参阅 `docs/ARCHITECTURE.md`。
**角色**集中在一个地方,而不是作为字符串文字散落在各处:
`backend/app/models/roles.py`(`Role` enum)和 `frontend/src/constants/roles.js`
(手动保持同步 — 只有三个值,因此这不需要
代码生成)。每个 `require_role(...)` 调用和每个前端角色检查
都引用这些常量。
**迁移顺序**(`docs/migrations/`,在 Supabase SQL
编辑器中各按顺序运行一次):
1. `001_add_incident_timeline.sql` — 添加 `incidents.timeline` 和
`incidents.contributing_factors`。
2. `002_add_user_profiles.sql` — 创建 `user_profiles`、RLS 策略、
`on_auth_user_created` 触发器,**并为触发器之前存在的任何
`auth.users` 行回填个人资料**。此文件中的每一条语句
都是幂等的 — 重新运行它(例如在添加列之后,或者只是为了
仔细检查)始终是安全的,并且绝不会创建重复项。
一个全新的 Supabase 项目只需要 `docs/supabase_schema.sql`(其中
已经包含了上述所有内容) — `docs/migrations/` 中带编号的迁移文件用于将*现有*数据库更新到最新状态。
**自我修复的个人资料。** 迁移 002 中的触发器涵盖了未来的每一次注册,
而同一迁移中的回填涵盖了触发器存在之前的每个账户。
作为第三层,`app/services/auth.py` 中的 `get_current_user` 将在遇到
没有 profile 行的已验证用户时立即创建缺失的 profile(通过幂等的
`upsert`,在并发请求下是安全的) — 因此,即使在前两层没有预料到的
边缘情况下,这类错误(`403 No profile
found`)也不会再次发生。为此,永远不需要手动进行 SQL `insert`。
**启动验证。** 在启动时,后端(`app/services/startup_checks.py`)
会查询它依赖的确切表/列(`incidents.timeline`、
`incidents.contributing_factors`、`detections`、`user_profiles`),如果缺少任何表/列,则拒绝
启动,并准确记录要运行哪个迁移文件,而不是
让它以后在用户碰巧首先访问的任何 endpoint 上表现为令人困惑的运行时错误。如果你的后端无法启动,**请阅读终端输出**
— 错误会指出要运行的确切文件。
**引导你的第一个管理员。** 每次注册默认为 `viewer`
(最小权限)。这不是一种权宜之计 — 任何基于角色的系统都需要一种
方法来指定其第一个管理员,因为一开始没有人是管理员。通过
应用程序注册一次,然后运行:
```
update user_profiles set role = 'admin' where email = 'you@example.com';
```
之后,通过应用程序本身提升其他所有人
(`PATCH /profile/users/{id}/role`) — 不再需要手动进行 SQL 操作。
**故障排除**
| 症状 | 原因 | 解决方法 |
|---|---|---|
| 后端无法启动,错误提示缺少表/列 | 尚未运行迁移 | 阅读启动错误中的确切文件名,并在 Supabase SQL 编辑器中运行它 |
| 之前可用的账户出现 `403 No profile found` | 罕见 — `get_current_user` 中的自我修复应该可以防止这种情况,但如果 RLS 或权限更改阻止了它,你会看到带有特定消息的 500 错误 | 重新运行 `002_add_user_profiles.sql`(幂等,安全) |
| Analyze/Upload 页面在没有错误的情况下将你重定向到 `/` | 已修复 — `ProtectedRoute` 现在会显示特定的 profile 加载错误,而不是静默重定向 | 如果你仍然看到静默重定向,说明你使用的是旧版前端构建 |
| 会话中途出现 `401` | 会话已过期或在别处被撤销 | 前端现在会自动登出并重定向到 `/login`(请参阅 `frontend/src/services/api.js` 响应拦截器) |
| 电子邮件验证 / 重置链接不起作用 | 重定向 URL 未加入允许列表 | Supabase → Authentication → URL Configuration → 添加你的前端源 |
深海军蓝底色(`#0B1120`),用于严重程度的警示红(`#DC2626`)和琥珀色(`#F59E0B`),以及借鉴自热成像/夜视
成像的标志性青色(`#2DD4BF`) — 这是一种明显属于 RescueLens 而非通用的“紧急红色”的强调色。显示字体为 Space Grotesk,正文为 Inter,数据读数使用 JetBrains Mono。有关完整的 token 集,请参阅 `frontend/tailwind.config.js`。
## API 参考
除健康检查外,以下所有路由都需要 `Authorization: Bearer `。
一旦你登录,前端会自动附加此内容。
| 方法 | 路径 | 所需角色 | 描述 |
|---|---|---|---|
| POST | `/upload` | admin, responder | 仅将原始图像上传到存储 |
| POST | `/analyze` | admin, responder | 完整流水线:upload → Gemini → 风险评分 → 保存 |
| GET | `/history?limit=50` | any authenticated | 列出已保存的事故,最新优先 |
| GET | `/incident/{id}` | any authenticated | 单个事故详情 |
| DELETE | `/incident/{id}` | admin | 删除事故 |
| GET | `/incident/{id}/report.pdf` | any authenticated | 将事故下载为 PDF |
| GET | `/profile/me` | any authenticated | 当前用户的 profile |
| PATCH | `/profile/me` | any authenticated | 更新自己的姓名/电话/部门/组织 |
| GET | `/profile/users` | admin | 列出所有用户 |
| PATCH | `/profile/users/{id}/role` | admin | 更改另一个用户的角色 |
有关完整的流水线图和设计原理,请参阅 `docs/ARCHITECTURE.md`。
标签:AV绕过, FastAPI, Gemini AI, React, Supabase, Syscalls, 图像识别, 库, 应急响应, 测试用例, 灾害管理, 自定义脚本, 逆向工具