miacono/maia

GitHub: miacono/maia

一个面向自然灾害应急响应的开源 API 平台,提供救援队伍管理、装备调度、事件记录与不可篡改审计日志,帮助运营中心协调和追踪救援行动。

Stars: 0 | Forks: 0

# MAIA [![CI](https://github.com/your-org/maia/actions/workflows/ci.yml/badge.svg)](https://github.com/your-org/maia/actions/workflows/ci.yml) [![覆盖率](https://codecov.io/gh/your-org/maia/branch/main/graph/badge.svg)](https://codecov.io/gh/your-org/maia) [![安全扫描](https://github.com/your-org/maia/actions/workflows/ci.yml/badge.svg?event=push)](https://github.com/your-org/maia/actions) [![许可证: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](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, 事件指挥系统, 团队调度, 实时地图, 应急救援, 网络测绘, 请求拦截, 逆向工具, 防篡改审计日志