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, 图像识别, 库, 应急响应, 测试用例, 灾害管理, 自定义脚本, 逆向工具