miacono/maia
GitHub: miacono/maia
一个面向自然灾害应急响应的开源 API 平台,提供救援队伍管理、装备调度、事件记录与不可篡改审计日志,帮助运营中心协调和追踪救援行动。
Stars: 0 | Forks: 0
# MAIA
[](https://github.com/your-org/maia/actions/workflows/ci.yml)
[](https://codecov.io/gh/your-org/maia)
[](https://github.com/your-org/maia/actions)
[](https://www.gnu.org/licenses/agpl-3.0)
MAIA 是一个 API 优先的平台,用于协调自然灾害期间的应急响应行动。它为运营中心提供了相关工具,以便召集救援队伍和装备,将它们分配到活跃的突发事件中,通过实时的态势感知进行干预,并通过不可篡改、防篡改的日志审计每一次行动。
## 核心功能
- **团队管理** — 创建具有专业化技能的救援队伍(SAR、医疗、潜水救援等)
- **装备管理** — 对具有特定特征和操作状态的车辆与装备进行编目
- **事件管理** — 记录具有地理影响区域的不同严重程度的事件
- **任务分配** — 将救援队伍和装备关联到活跃的突发事件
- **实时地图** — 实时查看团队和车辆位置以及事件区域
- **不可篡改的审计日志** — 通过可验证的 SHA-256 哈希链追踪每一次操作
- **完整的 REST API** — 所有数据均可通过 API 访问,以支持任何前端
## 架构
```
┌─────────────────────────────────────────────┐
│ Client (Web / Mobile / Third party) │
└────────────────┬────────────────────────────┘
│ HTTPS / WSS
┌────────────────▼────────────────────────────┐
│ Reverse Proxy (Nginx/Caddy) │
│ TLS · Rate limiting · CORS · Headers │
└────────────────┬────────────────────────────┘
│
┌────────────────▼────────────────────────────┐
│ Application Server (FastAPI) │
│ │
│ REST API v1 · WebSocket · Auth/RBAC │
│ Teams · Equipment · Incidents · Audit │
└────────┬────────────────┬───────────────────┘
│ │
┌────────▼──────┐ ┌──────▼──────────────────┐
│ PostgreSQL │ │ Audit DB (write-only) │
│ + PostGIS │ │ Hash chain verified │
└───────────────┘ └─────────────────────────┘
```
**技术栈:** Python · FastAPI · SQLAlchemy 2 · PostgreSQL 16 + PostGIS 3.4 · Docker
## 快速开始
### 前置条件
- Docker Engine 24+
- Docker Compose v2+
- `make`(可选,用于简化命令)
### 本地开发
```
# Clone the repository
git clone https://github.com/your-org/disaster-response-platform.git
cd disaster-response-platform
# 复制并配置环境变量
cp backend/.env.example backend/.env
# 使用本地值编辑 backend/.env
# 启动 full stack
docker compose -f infrastructure/docker/docker-compose.yml up -d
# Apply database migrations
docker compose exec api alembic upgrade head
# API 可用地址:
# http://localhost:8000
# http://localhost:8000/docs (Swagger UI)
# http://localhost:8000/redoc (ReDoc)
```
### 验证一切是否就绪
```
# Health check
curl http://localhost:8000/health
# 获取 token(默认开发用户)
curl -X POST http://localhost:8000/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{"username": "operator@local.dev", "password": "changeme"}'
# 创建第一个 incident
curl -X POST http://localhost:8000/api/v1/incidents \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"title": "Industrial area flooding",
"severity": "HIGH",
"affected_area": {
"type": "Polygon",
"coordinates": [[[11.5,45.7],[11.6,45.7],[11.6,45.8],[11.5,45.7]]]
}
}'
```
## API 参考
完整的 API 文档由 FastAPI 自动生成:
| Endpoint | 描述 |
|---|---|
| `GET /docs` | 交互式 Swagger UI |
| `GET /redoc` | ReDoc(可读性强的文档) |
| `GET /api/v1/openapi.json` | OpenAPI 规范(JSON) |
### 主要接口
```
# Authentication
POST /api/v1/auth/token
POST /api/v1/auth/refresh
# Incidents
GET /api/v1/incidents # list with filters and pagination
POST /api/v1/incidents # create
GET /api/v1/incidents/{id} # detail
PATCH /api/v1/incidents/{id} # update
DELETE /api/v1/incidents/{id} # soft delete
POST /api/v1/incidents/{id}/assign # assign teams and equipment
# Teams
GET /api/v1/teams
POST /api/v1/teams
GET /api/v1/teams/{id}
PATCH /api/v1/teams/{id}
# Equipment
GET /api/v1/equipment
POST /api/v1/equipment
GET /api/v1/equipment/{id}
PATCH /api/v1/equipment/{id}
# Map
GET /api/v1/map/live # full GeoJSON snapshot
WS /api/v1/ws/map # real-time updates
# Audit
GET /api/v1/audit/{resource}/{id} # audit trail for a specific resource
GET /api/v1/audit/verify # verify hash chain integrity
```
### 角色与权限
| 角色 | 权限 |
|---|---|
| `OPERATOR` | 完整的读写权限 |
| `VIEWER` | 只读权限,包括实时地图 |
| `API_CLIENT` | 用于外部集成的基于 token 的访问(可配置权限范围) |
## 测试
该项目要求**最低测试覆盖率达到 95%** — 如果未达到该阈值,CI pipeline 将会停止。覆盖率采用 `branch = true` 进行测量(即每个条件的每个分支,而不仅仅是每一行代码)。
### 运行测试
```
# 所有测试(需要活跃的 PostGIS 数据库)
docker compose -f infrastructure/docker/docker-compose.test.yml up -d
pytest backend/tests/ --cov=app --cov-report=term-missing
# 仅 Unit tests(无外部依赖)
pytest backend/tests/unit/ -v
# 仅 Integration tests
pytest backend/tests/integration/ -v
# 仅 E2E tests(需要 full stack)
pytest backend/tests/e2e/ -v
# HTML coverage report
pytest --cov=app --cov-report=html
open htmlcov/index.html
```
### 测试结构
```
tests/
├── unit/ → isolated services, no external dependencies, fast
├── integration/ → real API endpoints with PostGIS, rolled-back transactions
└── e2e/ → complete business flows, full Docker stack
```
## CI/CD Pipeline
每次推送和 pull request 都会经过 GitHub Actions 上的自动化流水线。
**任何阶段都不能跳过** — 任何一个阶段失败都会阻止所有后续阶段。
```
push / PR
│
├── Lint & Format ruff · mypy · black · isort · hadolint
│
├── Unit Tests ─┐
│ ├─ parallel ─→ Coverage Gate (≥95%) → BLOCKS if below threshold
├── Integration ─┘
│
├── Build Image Git SHA tag · SBOM · SLSA provenance
│
├── Security Scan Trivy (CVE CRITICAL/HIGH = BLOCKS) · pip-audit · Semgrep
│
├── E2E Tests full Docker Compose stack
│
└── Deploy manual approval required → production
```
### 安全扫描 — 详情
| 工具 | 检查内容 | 失败时的行为 |
|---|---|---|
| **Trivy** | 镜像中 OS 软件包和 Python 依赖项的 CVE | 遇到 CRITICAL 和 HIGH 级别时阻断 |
| **pip-audit** | Python 依赖项 (requirements.txt) 的 CVE | 遇到任何 CVE 时阻断 |
| **Semgrep** | SAST:SQL 注入、JWT 问题、密钥泄露、不安全的模式 | 遇到任何发现时阻断 |
## 生产环境部署
### 必需的环境变量
```
# Database
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/disasterdb
AUDIT_DATABASE_URL=postgresql+asyncpg://audit_ro:pass@host:5432/disasterdb
# Authentication
JWT_SECRET_KEY= # generate with: openssl rand -hex 32
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=15
REFRESH_TOKEN_EXPIRE_DAYS=7
# Application
ENVIRONMENT=production
LOG_LEVEL=INFO
CORS_ORIGINS=https://your-frontend.example.com
# Security
RATE_LIMIT_PER_MINUTE=60
```
### 在生产环境中启动
```
# 拉取特定的 image(始终使用 SHA tag,切勿使用 latest)
docker pull ghcr.io/your-org/disaster-response-platform:abc1234
# 使用 production compose file 启动
IMAGE_TAG=abc1234 docker compose -f infrastructure/docker/docker-compose.prod.yml up -d
# Apply migrations
docker compose exec api alembic upgrade head
# 验证 audit log 完整性
curl https://your-api.example.com/api/v1/audit/verify
```
### 回滚
```
# 通过更改 tag 回退到之前的版本
IMAGE_TAG=previous-sha docker compose -f infrastructure/docker/docker-compose.prod.yml up -d
```
## 审计日志与不可篡改性
每一次写操作都会在与主操作**同一事务内**生成一条审计日志记录。这些记录通过 SHA-256 哈希链进行关联:每条记录都包含前一条记录的哈希值,从而使得任何篡改行为都能被检测到。
```
Record 1: hash("INCIDENT_CREATED" + payload_1 + "0000...") = "a3f9..."
Record 2: hash("TEAM_ASSIGNED" + payload_2 + "a3f9...") = "b72c..."
Record 3: hash("STATUS_UPDATED" + payload_3 + "b72c...") = "c18e..."
```
应用程序的数据库用户对 `audit_log` 表没有任何 `UPDATE`/`DELETE` 权限 — 这是在迁移过程中的 PostgreSQL grant 级别强制执行的。
要验证完整性:
```
curl -H "Authorization: Bearer " \
https://your-api.example.com/api/v1/audit/verify
# {"valid": true, "records_verified": 1547, "last_hash": "c18e..."}
```
## 安全
如果您发现了一个安全漏洞,**请不要创建公开的 issue**。
请通过
[GitHub Security Advisories](https://github.com/your-org/disaster-response-platform/security/advisories/new) 提交一份私有报告。
## 许可证
DisasterResponse Platform 基于
[GNU Affero General Public License v3.0](LICENSE) 发布。
完整的许可证文本可在 `LICENSE` 文件中找到。
## 路线图
- [ ] Keycloak 身份验证 (OIDC)
- [ ] 移动应用 (React Native) — API 使用者
- [ ] Web 仪表盘 (React + MapLibre GL)
- [ ] 支持离线优先及延迟同步
- [ ] 使用 mutmut 进行变异测试
- [ ] 与国家警报系统集成
- [ ] 导出已完成事件的 PDF 报告
- [ ] 面向独立运营中心的多租户架构
标签:REST API, 事件指挥系统, 团队调度, 实时地图, 应急救援, 网络测绘, 请求拦截, 逆向工具, 防篡改审计日志