jash1811/incident-response-platform
GitHub: jash1811/incident-response-platform
一个基于 Flask 和 Vue 3 的多租户事件响应平台,提供事件全生命周期管理、细粒度 RBAC 权限控制和完整审计追踪。
Stars: 0 | Forks: 0
<<<<<<< HEAD
# IncidentHub — 多租户事件响应平台
一个生产就绪的 MVP SaaS 平台,用于管理隔离租户的事件。使用 Flask(后端)和 Quasar/Vue 3(前端)构建。
## 项目概述
IncidentHub 允许组织(租户)跟踪、分配和解决事件,并提供完整的审计追踪。每个租户的数据是完全隔离的。基于角色的访问控制(RBAC)决定了每个用户能看到和做什么。
## 架构
```
incident-platform-backend/
├── backend/ # Flask REST API
│ ├── app/
│ │ ├── config/ # Environment-based config
│ │ ├── models/ # SQLAlchemy ORM models
│ │ ├── routes/ # Blueprint route handlers
│ │ ├── schemas/ # Marshmallow validation/serialization
│ │ ├── services/ # Business logic (activity logging, etc.)
│ │ ├── middleware/ # JWT tenant/role decorators
│ │ └── utils/ # Pagination, error helpers
│ ├── run.py
│ └── requirements.txt
│
└── frontend/ # Quasar (Vue 3) SPA
└── src/
├── boot/ # Axios setup + interceptors
├── components/ # Reusable UI components
├── css/ # Global SCSS
├── layouts/ # MainLayout (sidebar + navbar)
├── pages/ # Route-level page components
├── router/ # Vue Router + auth guards
├── services/ # API service layer
└── stores/ # Pinia state stores
```
## 数据库模式
### tenants
| 列名 | 类型 | 备注 |
|------------|--------------|--------------------|
| id | INT PK | |
| name | VARCHAR(255) | 唯一 |
| created_at | DATETIME | |
### users
| 列名 | 类型 | 备注 |
|---------------|-----------------------------|--------------------------|
| id | INT PK | |
| tenant_id | INT FK → tenants.id | 有索引 |
| name | VARCHAR(255) | |
| email | VARCHAR(255) | 每个租户内唯一 |
| password_hash | VARCHAR(255) | bcrypt |
| role | ENUM(admin, manager, user) | |
| created_at | DATETIME | |
### incidents
| 列名 | 类型 | 备注 |
|-------------|-----------------------------------------|------------------------------|
| id | INT PK | |
| tenant_id | INT FK → tenants.id | 有索引 |
| title | VARCHAR(500) | |
| description | TEXT | |
| status | ENUM(open, in_progress, resolved, closed) | |
| priority | ENUM(low, medium, high, critical) | |
| assigned_to | INT FK → users.id | 可为空 |
| created_by | INT FK → users.id | |
| version | INT | 乐观并发锁 |
| created_at | DATETIME | |
| updated_at | DATETIME | 修改时自动更新 |
### incident_comments
| 列名 | 类型 | 备注 |
|-------------|-------------------|---------|
| id | INT PK | |
| tenant_id | INT FK | 有索引 |
| incident_id | INT FK | 有索引 |
| user_id | INT FK | |
| comment | TEXT | |
| created_at | DATETIME | |
### activity_logs
| 列名 | 类型 | 备注 |
|-------------|--------------|--------------------------------|
| id | INT PK | |
| tenant_id | INT FK | 有索引 |
| incident_id | INT FK | 有索引 |
| action | VARCHAR(100) | 例如 "status_changed" |
| old_value | TEXT | 可为空 |
| new_value | TEXT | 可为空 |
| created_by | INT FK | |
| created_at | DATETIME | |
## 设置
### 前置条件
- Python 3.11+
- Node.js 18+
- MySQL 8+
- 已全局安装 `@quasar/cli`:`npm i -g @quasar/cli`
### 后端
```
cd backend
# Create virtual environment
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS/Linux
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env with your DB credentials and JWT secret
# Create MySQL database
mysql -u root -p -e "CREATE DATABASE incident_platform CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
# Run (auto-creates tables on first start)
python run.py
```
API 将在 `http://localhost:5000` 上可用。
Swagger 文档:`http://localhost:5000/api/docs/`
### 前端
```
cd frontend
# Install dependencies
npm install
# Start dev server (proxies /api to localhost:5000)
quasar dev
```
应用将在 `http://localhost:9000` 上打开。
### 首次设置
1. 打开应用并点击 **注册**
2. 输入您的组织名称、您的姓名、邮箱和密码
3. 这将创建一个新的租户和一个 **admin** 账户
4. 登录并使用 **用户管理** 来添加团队成员
## API 文档
完整的交互式文档可在 `/api/docs/` (Swagger UI) 获取。
### 认证
| 方法 | 端点 | 描述 |
|--------|----------------------|--------------------------------|
| POST | /api/auth/register | 创建租户 + admin 用户 |
| POST | /api/auth/login | 认证,接收 JWT |
### 用户(仅限 Admin 发起 POST 请求)
| 方法 | 端点 | 描述 |
|--------|-------------|--------------------------|
| GET | /api/users | 列出租户中的用户 |
| POST | /api/users | 在租户中创建用户 |
### 事件
| 方法 | 端点 | 描述 |
|--------|---------------------------------|------------------------------|
| GET | /api/incidents | 列表(筛选/搜索/分页)|
| POST | /api/incidents | 创建事件 |
| GET | /api/incidents/:id | 获取详情 |
| PUT | /api/incidents/:id | 更新(需要 version 字段) |
| PATCH | /api/incidents/:id/resolve | 解决事件 |
| PATCH | /api/incidents/:id/assign | 分配给用户 |
### 评论与活动
| 方法 | 端点 | 描述 |
|--------|-------------------------------------|----------------------|
| POST | /api/incidents/:id/comments | 添加评论 |
| GET | /api/incidents/:id/comments | 列出评论 |
| GET | /api/incidents/:id/activity | 活动时间线 |
### 仪表板
| 方法 | 端点 | 描述 |
|--------|-----------------------|----------------------|
| GET | /api/dashboard/stats | 统计数据 + 最近项目 |
## 租户隔离策略
每个数据库表都包含一个 `tenant_id` 列。JWT token 在登录时嵌入 `tenant_id` —— 该值在服务器端从已验证的 token 中提取,绝不从请求体或查询字符串中获取。
每个查询都被限定作用域:
```
Incident.query.filter_by(tenant_id=get_current_tenant_id())
```
`tenant_required` 中间件装饰器在任何路由处理程序运行之前验证 JWT 声明是否存在。跨租户访问在结构上是不可能的 —— 即使用户猜测到另一个租户的事件 ID,查询也会返回 404。
## 并发处理(乐观锁)
事件包含一个 `version` 整数列。每个修改请求(PUT、PATCH)都必须包含当前版本。服务器会检查:
```
if incident.version != data["version"]:
return handle_conflict("Stale data: ...")
```
成功时,`version` 会递增。这可以防止两个用户在互不知情的情况下覆盖彼此的更改。前端会收到 409 状态码,并提示用户刷新。
## 基于角色的访问控制 (RBAC)
| 操作 | Admin | Manager | User |
|---------------------------|-------|---------|------|
| 注册/登录 | ✓ | ✓ | ✓ |
| 查看分配给自己的事件 | ✓ | ✓ | ✓ |
| 查看租户的所有事件 | ✓ | ✓ | ✗ |
| 创建/更新事件 | ✓ | ✓ | ✗ |
| 分配/解决事件 | ✓ | ✓ | ✗ |
| 添加评论 | ✓ | ✓ | ✓ |
| 管理用户 | ✓ | ✗ | ✗ |
角色通过应用在路由级别的装饰器(`@admin_required`、`@manager_or_admin_required`)来强制执行。
## 可扩展性考量
- **分页**:所有列表端点均支持分页(默认 20/页,最大 100)
- **数据库索引**:在 `(tenant_id, status)`、`(email, tenant_id)` 以及所有 FK 列上建有复合索引
- **服务层**:业务逻辑与路由处理程序分离,以提高可测试性
- **模块化蓝图**:每个领域(auth、incidents、users、comments、dashboard)都是一个独立的 Flask Blueprint
- **连接池**:SQLAlchemy 引擎配置了 `pool_recycle` 和 `pool_pre_ping`
- **待办**:添加 Redis 缓存用于仪表板统计,添加 WebSocket 支持用于实时事件更新
## 权衡
| 决策 | 理由 |
|----------|-----------|
| Hash history 对比 HTML5 history | Hash 模式避免了 MVP 的服务器端路由配置 |
| 乐观锁对比悲观锁 | 更低的数据库开销;对于事件管理的更新频率是可以接受的 |
| 仅 JWT 认证(无刷新令牌) | 对 MVP 来说更简单;在投入生产前需添加刷新令牌 |
| 平台单数据库 | 运维更简单;行级隔离对于 MVP 规模已经足够 |
| Marshmallow 对比 Pydantic | 与 Flask 生态系统保持一致;更好的 SQLAlchemy 集成 |
## AI 使用声明
# AI 工具被用于加速样板代码生成和辅助文档编写。
核心架构、租户隔离策略、RBAC 设计、乐观并发实现以及后端流程决策均经过人工审查和修改。
# 事件响应平台
标签:Axios, CMS安全, CSV输出, Flask, JavaScript, JWT, Marshmallow, MVP, ORM, Pinia, Python, Quasar, RBAC, REST API, SaaS平台, SPA, SQLAlchemy, Syscall, Vue 3, Vue Router, Web开发, 事件响应平台, 事件管理, 事件追踪, 企业服务, 单页应用, 后端开发, 安全运营, 审计追踪, 工单分配, 工单系统, 扫描框架, 数据序列化, 数据隔离, 无后门, 状态管理, 秘密管理, 网络研究, 角色访问控制, 逆向工具