删除、移动旧文档
This commit is contained in:
+61
-185
@@ -1,206 +1,82 @@
|
||||
# TJWater Server - Copilot Instructions
|
||||
# Copilot Instructions for TJWater Server
|
||||
|
||||
This is a FastAPI-based water network management system (供水管网智能管理系统) that provides hydraulic simulation, SCADA data integration, network element management, and risk analysis capabilities.
|
||||
This repository contains the backend code for the TJWater Server, a water distribution network management system built with FastAPI.
|
||||
|
||||
## Running the Server
|
||||
## High-Level Architecture
|
||||
|
||||
The application follows a layered architecture:
|
||||
|
||||
- **Entry Point**: `app/main.py` initializes the FastAPI application, database connections (PostgreSQL & TimescaleDB), and middleware.
|
||||
- **API Layer**: `app/api/v1` contains the route handlers.
|
||||
- **Service Layer**: `app/services` contains business logic and orchestration.
|
||||
- **Infrastructure Layer**: `app/infra` handles database connections (`db`), audit logging (`audit`), and external integrations.
|
||||
- **Domain Layer**: `app/domain` likely contains core domain models.
|
||||
- **Native/Algorithms**: `app/native` and `app/algorithms` handle specialized water network calculations (possibly using EPANET/WNTR).
|
||||
|
||||
## Build, Test, and Run Commands
|
||||
|
||||
### Environment Setup
|
||||
|
||||
- Dependencies are listed in `requirements.txt`.
|
||||
- Configuration is managed via environment variables (see `.env.example` if available, or `app/core/config.py`).
|
||||
- **Important**: Ensure `.env` is configured with correct database credentials for both PostgreSQL and TimescaleDB.
|
||||
|
||||
If first time setting up, you may want to create a Conda environment:
|
||||
|
||||
```bash
|
||||
# activate the server environment
|
||||
conda create -n server python=3.12
|
||||
conda activate server
|
||||
# Install dependencies
|
||||
<!-- pip install -r requirements.txt -->
|
||||
|
||||
# Start the server (default: http://0.0.0.0:8000 with 2 workers)
|
||||
python scripts/run_server.py
|
||||
|
||||
# Note: On Windows, the script automatically sets WindowsSelectorEventLoopPolicy
|
||||
pip install uv
|
||||
uv pip install -r requirements.txt
|
||||
conda install -c conda-forge pymetis
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
### Running the Server
|
||||
|
||||
The preferred way to run the server locally is using the helper script which sets up the Python path correctly:
|
||||
|
||||
```bash
|
||||
# activate the server environment
|
||||
conda activate server
|
||||
python scripts/run_server.py
|
||||
```
|
||||
|
||||
Alternatively, you can run directly with uvicorn (ensure PYTHONPATH includes the root):
|
||||
|
||||
```bash
|
||||
conda activate server
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
Use `pytest` to run tests. The `tests/conftest.py` handles path setup.
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
pytest
|
||||
|
||||
# Run a specific test file with verbose output
|
||||
pytest tests/unit/test_pipeline_health_analyzer.py -v
|
||||
# Run a specific test file
|
||||
pytest tests/unit/test_specific_file.py
|
||||
|
||||
# Run from conftest helper
|
||||
python tests/conftest.py
|
||||
# Run a specific test case
|
||||
pytest tests/unit/test_specific_file.py::test_function_name
|
||||
```
|
||||
|
||||
## Architecture Overview
|
||||
### Building (Optional)
|
||||
|
||||
### Core Components
|
||||
The project includes scripts to compile Python modules to `.pyd` files using Cython (see `scripts/build_pyd.py`). This is likely for distribution/performance but not required for standard development.
|
||||
|
||||
1. **Native Modules** (`app/native/`): Platform-specific compiled extensions (`.so` for Linux, `.pyd` for Windows) providing performance-critical functionality including:
|
||||
- SCADA device integration
|
||||
- Water distribution analysis (WDA)
|
||||
- Pipe risk probability calculations
|
||||
- Wrapped through `app.services.tjnetwork` interface
|
||||
## Key Conventions
|
||||
|
||||
2. **Services Layer** (`app/services/`):
|
||||
- `tjnetwork.py`: Main network API wrapper around native modules
|
||||
- `simulation.py`: Hydraulic simulation orchestration (EPANET integration)
|
||||
- `project_info.py`: Project configuration management
|
||||
- `epanet/`: EPANET hydraulic engine integration
|
||||
- **Async/Await**: The codebase heavily uses `async` and `await` for I/O operations, especially database interactions.
|
||||
- **Database Management**:
|
||||
- Connections are managed globally in `app.infra.db` and initialized in `lifespan` (app/main.py).
|
||||
- Use `app.infra.db.dynamic_manager` for project-specific database connections (multi-tenancy/dynamic projects).
|
||||
- **Pydantic**: extensively used for data validation and settings management.
|
||||
- **Scripts**: The `scripts/` directory contains many utility scripts for maintenance, data processing, and server management. Check there before writing new operational scripts.
|
||||
- **Water Network Modeling**: Interactions with water network models often involve `epanet` or `wntr` libraries. Be aware of domain-specific terminology (nodes, links, junctions, tanks).
|
||||
|
||||
3. **API Layer** (`app/api/v1/`):
|
||||
- **Network Elements**: Separate endpoint modules for junctions, reservoirs, tanks, pipes, pumps, valves
|
||||
- **Components**: Curves, patterns, controls, options, quality, visuals
|
||||
- **Network Features**: Tags, demands, geometry, regions/DMAs
|
||||
- **Core Services**: Auth, project, simulation, SCADA, data query, snapshots
|
||||
## Code Style
|
||||
|
||||
4. **Database Infrastructure** (`app/infra/db/`):
|
||||
- **PostgreSQL**: Primary relational database (users, audit logs, project metadata)
|
||||
- **TimescaleDB**: Time-series extension for historical data
|
||||
- **InfluxDB**: Optional time-series database for high-frequency SCADA data
|
||||
- Connection pools initialized in `main.py` lifespan context
|
||||
- Database instance stored in `app.state.db` for dependency injection
|
||||
|
||||
5. **Domain Layer** (`app/domain/`):
|
||||
- `models/`: Enums and domain objects (e.g., `UserRole`)
|
||||
- `schemas/`: Pydantic models for request/response validation
|
||||
|
||||
6. **Algorithms** (`app/algorithms/`):
|
||||
- `api_ex/`: Analysis algorithms (k-means sensor placement, sensitivity analysis, pipeline health)
|
||||
- `data_cleaning.py`: Data preprocessing utilities
|
||||
- `simulations.py`: Simulation helpers
|
||||
|
||||
### Security & Authentication
|
||||
|
||||
- **Authentication**: JWT-based with access tokens (30 min) and refresh tokens (7 days)
|
||||
- **Authorization**: Role-based access control (RBAC) with 4 roles:
|
||||
- `VIEWER`: Read-only access
|
||||
- `USER`: Read-write access
|
||||
- `OPERATOR`: Modify data
|
||||
- `ADMIN`: Full permissions
|
||||
- **Audit Logging**: `AuditMiddleware` automatically logs POST/PUT/DELETE requests
|
||||
- **Encryption**: Fernet symmetric encryption for sensitive data (`app.core.encryption`)
|
||||
|
||||
Default admin accounts:
|
||||
|
||||
- `admin` / `admin123`
|
||||
- `tjwater` / `tjwater@123`
|
||||
|
||||
### Key Files
|
||||
|
||||
- `app/main.py`: FastAPI app initialization, lifespan (DB pools), CORS, middleware, router mounting
|
||||
- `app/api/v1/router.py`: Central router aggregating all endpoint modules
|
||||
- `app/core/config.py`: Settings management using `pydantic-settings`
|
||||
- `app/auth/dependencies.py`: Auth dependencies (`get_current_active_user`, `get_db`)
|
||||
- `app/auth/permissions.py`: Permission decorators (`require_role`, `get_current_admin`)
|
||||
- `.env`: Environment configuration (database credentials, JWT secret, encryption key)
|
||||
|
||||
## Important Conventions
|
||||
|
||||
### Database Connections
|
||||
|
||||
- Database instances are initialized in `main.py` lifespan and stored in `app.state.db`
|
||||
- Access via dependency injection:
|
||||
|
||||
```python
|
||||
from app.auth.dependencies import get_db
|
||||
|
||||
async def endpoint(db = Depends(get_db)):
|
||||
# Use db connection
|
||||
```
|
||||
|
||||
### Authentication in Endpoints
|
||||
|
||||
Use dependency injection for auth requirements:
|
||||
|
||||
```python
|
||||
from app.auth.dependencies import get_current_active_user
|
||||
from app.auth.permissions import require_role, get_current_admin
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
# Require any authenticated user
|
||||
@router.get("/data")
|
||||
async def get_data(current_user = Depends(get_current_active_user)):
|
||||
return data
|
||||
|
||||
# Require specific role (USER or higher)
|
||||
@router.post("/data")
|
||||
async def create_data(current_user = Depends(require_role(UserRole.USER))):
|
||||
return result
|
||||
|
||||
# Admin-only access
|
||||
@router.delete("/data/{id}")
|
||||
async def delete_data(id: int, current_user = Depends(get_current_admin)):
|
||||
return result
|
||||
```
|
||||
|
||||
### API Routing Structure
|
||||
|
||||
- All v1 APIs are mounted under `/api/v1` prefix via `api_router`
|
||||
- Legacy routes without version prefix are also mounted for backward compatibility
|
||||
- Group related endpoints in separate router modules under `app/api/v1/endpoints/`
|
||||
- Use descriptive tags in `router.py` for OpenAPI documentation grouping
|
||||
|
||||
### Native Module Integration
|
||||
|
||||
- Native modules are pre-compiled for specific platforms
|
||||
- Always import through `app.native.api` or `app.services.tjnetwork`
|
||||
- The `tjnetwork` service wraps native APIs with constants like:
|
||||
- Element types: `JUNCTION`, `RESERVOIR`, `TANK`, `PIPE`, `PUMP`, `VALVE`
|
||||
- Operations: `API_ADD`, `API_UPDATE`, `API_DELETE`
|
||||
- `ChangeSet` for batch operations
|
||||
|
||||
### Project Initialization
|
||||
|
||||
- On startup, `main.py` automatically loads project from `project_info.name` if set
|
||||
- Projects are opened via `open_project(name)` from `tjnetwork` service
|
||||
|
||||
### Audit Logging
|
||||
|
||||
Manual audit logging for critical operations:
|
||||
|
||||
```python
|
||||
from app.core.audit import log_audit_event, AuditAction
|
||||
|
||||
await log_audit_event(
|
||||
action=AuditAction.UPDATE,
|
||||
user_id=current_user.id,
|
||||
username=current_user.username,
|
||||
resource_type="resource_name",
|
||||
resource_id=str(resource_id),
|
||||
ip_address=request.client.host,
|
||||
request_data=data
|
||||
)
|
||||
```
|
||||
|
||||
### Environment Configuration
|
||||
|
||||
- Copy `.env.example` to `.env` before first run
|
||||
- Required environment variables:
|
||||
- `SECRET_KEY`: JWT signing (generate with `openssl rand -hex 32`)
|
||||
- `ENCRYPTION_KEY`: Data encryption (generate with Fernet)
|
||||
- Database credentials for PostgreSQL, TimescaleDB, and optionally InfluxDB
|
||||
|
||||
### Database Migrations
|
||||
|
||||
SQL migration scripts are in `migrations/`:
|
||||
|
||||
- `001_create_users_table.sql`: User authentication tables
|
||||
- `002_create_audit_logs_table.sql`: Audit logging tables
|
||||
|
||||
Apply with:
|
||||
|
||||
```bash
|
||||
psql -U postgres -d tjwater -f migrations/001_create_users_table.sql
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
||||
- Swagger UI: http://localhost:8000/docs
|
||||
- ReDoc: http://localhost:8000/redoc
|
||||
- OpenAPI schema: http://localhost:8000/openapi.json
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- `SECURITY_README.md`: Comprehensive security feature documentation
|
||||
- `DEPLOYMENT.md`: Integration guide for security features
|
||||
- `readme.md`: Project overview and directory structure (in Chinese)
|
||||
- Follow standard PEP 8 guidelines.
|
||||
- No specific linter configuration was found, so default to standard Python formatting.
|
||||
|
||||
-391
@@ -1,391 +0,0 @@
|
||||
# 部署和集成指南
|
||||
|
||||
本文档说明如何将新的安全功能集成到现有系统中。
|
||||
|
||||
## 📦 已完成的功能
|
||||
|
||||
### 1. 数据加密模块
|
||||
- ✅ `app/core/encryption.py` - Fernet 对称加密实现
|
||||
- ✅ 支持敏感数据加密/解密
|
||||
- ✅ 密钥管理和生成工具
|
||||
|
||||
### 2. 用户认证系统
|
||||
- ✅ `app/domain/models/role.py` - 用户角色枚举 (ADMIN/OPERATOR/USER/VIEWER)
|
||||
- ✅ `app/domain/schemas/user.py` - 用户数据模型和验证
|
||||
- ✅ `app/infra/repositories/user_repository.py` - 用户数据访问层
|
||||
- ✅ `app/api/v1/endpoints/auth.py` - 注册/登录/刷新Token接口
|
||||
- ✅ `app/auth/dependencies.py` - 认证依赖项
|
||||
- ✅ `migrations/001_create_users_table.sql` - 用户表迁移脚本
|
||||
|
||||
### 3. 权限控制系统
|
||||
- ✅ `app/auth/permissions.py` - RBAC 权限控制装饰器
|
||||
- ✅ `app/api/v1/endpoints/user_management.py` - 用户管理接口示例
|
||||
- ✅ 支持基于角色的访问控制
|
||||
- ✅ 支持资源所有者检查
|
||||
|
||||
### 4. 审计日志系统
|
||||
- ✅ `app/core/audit.py` - 审计日志核心功能
|
||||
- ✅ `app/domain/schemas/audit.py` - 审计日志数据模型
|
||||
- ✅ `app/infra/repositories/audit_repository.py` - 审计日志数据访问层
|
||||
- ✅ `app/api/v1/endpoints/audit.py` - 审计日志查询接口
|
||||
- ✅ `app/infra/audit/middleware.py` - 自动审计中间件
|
||||
- ✅ `migrations/002_create_audit_logs_table.sql` - 审计日志表迁移脚本
|
||||
|
||||
### 5. 文档和测试
|
||||
- ✅ `SECURITY_README.md` - 完整的使用文档
|
||||
- ✅ `.env.example` - 环境变量配置模板
|
||||
- ✅ `tests/test_encryption.py` - 加密功能测试
|
||||
|
||||
---
|
||||
|
||||
## 🔧 集成步骤
|
||||
|
||||
### 步骤 1: 环境配置
|
||||
|
||||
1. 复制环境变量模板:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. 生成密钥并填写 `.env`:
|
||||
```bash
|
||||
# JWT 密钥
|
||||
openssl rand -hex 32
|
||||
|
||||
# 加密密钥
|
||||
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
||||
```
|
||||
|
||||
3. 编辑 `.env` 填写所有必需的配置项。
|
||||
|
||||
### 步骤 2: 数据库迁移
|
||||
|
||||
执行数据库迁移脚本:
|
||||
|
||||
```bash
|
||||
# 方法 1: 使用 psql 命令
|
||||
psql -U postgres -d tjwater -f migrations/001_create_users_table.sql
|
||||
psql -U postgres -d tjwater -f migrations/002_create_audit_logs_table.sql
|
||||
|
||||
# 方法 2: 在 psql 交互界面
|
||||
psql -U postgres -d tjwater
|
||||
\i migrations/001_create_users_table.sql
|
||||
\i migrations/002_create_audit_logs_table.sql
|
||||
```
|
||||
|
||||
验证表已创建:
|
||||
|
||||
```sql
|
||||
-- 检查用户表
|
||||
SELECT * FROM users;
|
||||
|
||||
-- 检查审计日志表
|
||||
SELECT * FROM audit_logs;
|
||||
```
|
||||
|
||||
### 步骤 3: 更新 main.py
|
||||
|
||||
在 `app/main.py` 中集成新功能:
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from app.core.config import settings
|
||||
from app.infra.audit.middleware import AuditMiddleware
|
||||
|
||||
app = FastAPI(title=settings.PROJECT_NAME)
|
||||
|
||||
# 1. 添加审计中间件(可选)
|
||||
app.add_middleware(AuditMiddleware)
|
||||
|
||||
# 2. 注册路由
|
||||
from app.api.v1.endpoints import auth, user_management, audit
|
||||
|
||||
app.include_router(
|
||||
auth.router,
|
||||
prefix=f"{settings.API_V1_STR}/auth",
|
||||
tags=["认证"]
|
||||
)
|
||||
|
||||
app.include_router(
|
||||
user_management.router,
|
||||
prefix=f"{settings.API_V1_STR}/users",
|
||||
tags=["用户管理"]
|
||||
)
|
||||
|
||||
app.include_router(
|
||||
audit.router,
|
||||
prefix=f"{settings.API_V1_STR}/audit",
|
||||
tags=["审计日志"]
|
||||
)
|
||||
|
||||
# 3. 确保数据库在启动时初始化
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
# 初始化数据库连接池
|
||||
from app.infra.db.postgresql.database import Database
|
||||
global db
|
||||
db = Database()
|
||||
db.init_pool()
|
||||
await db.open()
|
||||
|
||||
@app.on_event("shutdown")
|
||||
async def shutdown_event():
|
||||
# 关闭数据库连接
|
||||
await db.close()
|
||||
```
|
||||
|
||||
### 步骤 4: 保护现有接口
|
||||
|
||||
#### 方法 1: 为路由添加全局依赖
|
||||
|
||||
```python
|
||||
from app.auth.dependencies import get_current_active_user
|
||||
|
||||
# 为整个路由器添加认证
|
||||
router = APIRouter(dependencies=[Depends(get_current_active_user)])
|
||||
```
|
||||
|
||||
#### 方法 2: 为单个端点添加依赖
|
||||
|
||||
```python
|
||||
from app.auth.permissions import require_role, get_current_admin
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
@router.get("/data")
|
||||
async def get_data(
|
||||
current_user = Depends(require_role(UserRole.USER))
|
||||
):
|
||||
"""需要 USER 及以上角色"""
|
||||
return {"data": "protected"}
|
||||
|
||||
@router.delete("/data/{id}")
|
||||
async def delete_data(
|
||||
id: int,
|
||||
current_user = Depends(get_current_admin)
|
||||
):
|
||||
"""仅管理员可访问"""
|
||||
return {"message": "deleted"}
|
||||
```
|
||||
|
||||
### 步骤 5: 添加审计日志
|
||||
|
||||
#### 自动审计(推荐)
|
||||
|
||||
使用中间件自动记录(已在 main.py 中添加):
|
||||
|
||||
```python
|
||||
app.add_middleware(AuditMiddleware)
|
||||
```
|
||||
|
||||
#### 手动审计
|
||||
|
||||
在关键业务逻辑中手动记录:
|
||||
|
||||
```python
|
||||
from app.core.audit import log_audit_event, AuditAction
|
||||
|
||||
@router.post("/important-action")
|
||||
async def important_action(
|
||||
data: dict,
|
||||
request: Request,
|
||||
current_user = Depends(get_current_active_user)
|
||||
):
|
||||
# 执行业务逻辑
|
||||
result = do_something(data)
|
||||
|
||||
# 记录审计日志
|
||||
await log_audit_event(
|
||||
action=AuditAction.UPDATE,
|
||||
user_id=current_user.id,
|
||||
username=current_user.username,
|
||||
resource_type="important_resource",
|
||||
resource_id=str(result.id),
|
||||
ip_address=request.client.host,
|
||||
request_data=data
|
||||
)
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
### 步骤 6: 更新 auth/dependencies.py
|
||||
|
||||
确保 `get_db()` 函数正确获取数据库实例:
|
||||
|
||||
```python
|
||||
async def get_db() -> Database:
|
||||
"""获取数据库实例"""
|
||||
# 方法 1: 从 main.py 导入
|
||||
from app.main import db
|
||||
return db
|
||||
|
||||
# 方法 2: 从 FastAPI app.state 获取
|
||||
# from fastapi import Request
|
||||
# def get_db_from_request(request: Request):
|
||||
# return request.app.state.db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试
|
||||
|
||||
### 1. 测试加密功能
|
||||
|
||||
```bash
|
||||
python tests/test_encryption.py
|
||||
```
|
||||
|
||||
### 2. 测试 API
|
||||
|
||||
启动服务器:
|
||||
|
||||
```bash
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
访问交互式文档:
|
||||
- Swagger UI: http://localhost:8000/docs
|
||||
- ReDoc: http://localhost:8000/redoc
|
||||
|
||||
### 3. 测试登录
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/auth/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin&password=admin123"
|
||||
```
|
||||
|
||||
### 4. 测试受保护接口
|
||||
|
||||
```bash
|
||||
TOKEN="your-access-token"
|
||||
curl -X GET "http://localhost:8000/api/v1/auth/me" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 迁移现有接口
|
||||
|
||||
### 原有硬编码认证
|
||||
|
||||
**旧代码** (`app/api/v1/endpoints/auth.py`):
|
||||
```python
|
||||
AUTH_TOKEN = "567e33c876a2"
|
||||
|
||||
async def verify_token(authorization: str = Header()):
|
||||
token = authorization.split(" ")[1]
|
||||
if token != AUTH_TOKEN:
|
||||
raise HTTPException(status_code=403)
|
||||
```
|
||||
|
||||
**新代码** (已更新):
|
||||
```python
|
||||
from app.auth.dependencies import get_current_active_user
|
||||
|
||||
@router.get("/protected")
|
||||
async def protected_route(
|
||||
current_user = Depends(get_current_active_user)
|
||||
):
|
||||
return {"user": current_user.username}
|
||||
```
|
||||
|
||||
### 更新其他端点
|
||||
|
||||
搜索项目中使用旧认证的地方:
|
||||
|
||||
```bash
|
||||
grep -r "AUTH_TOKEN" app/
|
||||
grep -r "verify_token" app/
|
||||
```
|
||||
|
||||
替换为新的依赖注入系统。
|
||||
|
||||
---
|
||||
|
||||
## 📋 检查清单
|
||||
|
||||
部署前检查:
|
||||
|
||||
- [ ] 环境变量已配置(`.env`)
|
||||
- [ ] 数据库迁移已执行
|
||||
- [ ] 默认管理员账号可登录
|
||||
- [ ] JWT Token 可正常生成和验证
|
||||
- [ ] 权限控制正常工作
|
||||
- [ ] 审计日志正常记录
|
||||
- [ ] 加密功能测试通过
|
||||
- [ ] API 文档可访问
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. 向后兼容性
|
||||
|
||||
保留了简化版登录接口 `/auth/login/simple` 以兼容旧客户端:
|
||||
|
||||
```python
|
||||
@router.post("/login/simple")
|
||||
async def login_simple(username: str, password: str):
|
||||
# 验证并返回 Token
|
||||
...
|
||||
```
|
||||
|
||||
### 2. 数据库连接
|
||||
|
||||
确保在 `app/auth/dependencies.py` 中 `get_db()` 函数能正确获取数据库实例。
|
||||
|
||||
### 3. 密钥安全
|
||||
|
||||
- ❌ 不要提交 `.env` 文件到版本控制
|
||||
- ✅ 在生产环境使用环境变量或密钥管理服务
|
||||
- ✅ 定期轮换 JWT 密钥
|
||||
|
||||
### 4. 性能考虑
|
||||
|
||||
- 审计中间件会增加每个请求的处理时间(约 5-10ms)
|
||||
- 对高频接口可考虑异步记录审计日志
|
||||
- 定期清理或归档旧的审计日志
|
||||
|
||||
---
|
||||
|
||||
## 🐛 故障排查
|
||||
|
||||
### 问题 1: 导入错误
|
||||
|
||||
```
|
||||
ImportError: cannot import name 'db' from 'app.main'
|
||||
```
|
||||
|
||||
**解决**: 确保在 `app/main.py` 中定义了全局 `db` 对象。
|
||||
|
||||
### 问题 2: 认证失败
|
||||
|
||||
```
|
||||
401 Unauthorized: Could not validate credentials
|
||||
```
|
||||
|
||||
**检查**:
|
||||
1. Token 是否正确设置在 `Authorization: Bearer {token}` header
|
||||
2. Token 是否过期
|
||||
3. SECRET_KEY 是否配置正确
|
||||
|
||||
### 问题 3: 数据库连接失败
|
||||
|
||||
```
|
||||
psycopg.OperationalError: connection failed
|
||||
```
|
||||
|
||||
**检查**:
|
||||
1. PostgreSQL 是否运行
|
||||
2. `.env` 中数据库配置是否正确
|
||||
3. 数据库是否存在
|
||||
|
||||
---
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
详细文档请参考:
|
||||
- `SECURITY_README.md` - 安全功能使用指南
|
||||
- `migrations/` - 数据库迁移脚本
|
||||
- `app/domain/schemas/` - 数据模型定义
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
# TJWater ServerBinary - Documentation Index
|
||||
|
||||
## 📋 Complete Documentation Structure
|
||||
|
||||
### 🆕 **NEW: Secondary Development Documentation** (Recommended Starting Point)
|
||||
|
||||
#### 1. **QUICK_START_GUIDE.md** (7.5 KB, 326 lines)
|
||||
**Perfect for**: Getting started in 15 minutes
|
||||
- Quick reference card with copy-paste code
|
||||
- 7 most common tasks with examples
|
||||
- Common pitfalls and how to avoid them
|
||||
- File location reference
|
||||
- Key imports cheat sheet
|
||||
|
||||
**Read first if**: You're new to the codebase and want quick examples
|
||||
|
||||
#### 2. **SECONDARY_DEVELOPMENT_GUIDE.md** (29 KB, 1,015 lines)
|
||||
**Perfect for**: Deep understanding of the system
|
||||
- Complete architecture overview
|
||||
- Detailed guide for all 7 key aspects
|
||||
- Implementation patterns with code examples
|
||||
- Technology stack reference
|
||||
- Best practices and recommendations
|
||||
|
||||
**Read after**: QUICK_START_GUIDE, or if you need comprehensive understanding
|
||||
|
||||
---
|
||||
|
||||
### 📖 **Existing Documentation** (Supporting References)
|
||||
|
||||
#### 3. **readme.md** (3.5 KB)
|
||||
- Project overview
|
||||
- Main features
|
||||
- Quick start for running the server
|
||||
- Directory structure introduction
|
||||
|
||||
#### 4. **SECURITY_README.md** (11 KB)
|
||||
- Security features overview
|
||||
- Authentication setup
|
||||
- Encryption implementation
|
||||
- Audit logging features
|
||||
|
||||
#### 5. **SECURITY_IMPLEMENTATION_SUMMARY.md** (9 KB)
|
||||
- Detailed security implementation
|
||||
- Role-based access control
|
||||
- Password policies
|
||||
- Encryption key management
|
||||
|
||||
#### 6. **DEPLOYMENT.md** (8.7 KB)
|
||||
- Production deployment checklist
|
||||
- Docker configuration
|
||||
- Database setup
|
||||
- Environment configuration
|
||||
|
||||
#### 7. **INTEGRATION_CHECKLIST.md** (8.3 KB)
|
||||
- System integration steps
|
||||
- Database initialization
|
||||
- Service verification
|
||||
- Health checks
|
||||
|
||||
#### 8. **setup_server.md** (3.1 KB)
|
||||
- Initial server setup
|
||||
- Environment variables
|
||||
- Database configuration
|
||||
|
||||
#### 9. **setup_influxdb.md** (325 B)
|
||||
- InfluxDB configuration reference
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Reading Paths by Role
|
||||
|
||||
### For Backend Developers (Adding Features)
|
||||
1. Start: **QUICK_START_GUIDE.md** (Section 1: Adding API Endpoints)
|
||||
2. Then: **SECONDARY_DEVELOPMENT_GUIDE.md** (Sections 2-7)
|
||||
3. Refer: **SECURITY_README.md** (authentication patterns)
|
||||
4. Deploy: **DEPLOYMENT.md** (when ready for production)
|
||||
|
||||
### For Database/ORM Developers
|
||||
1. Start: **QUICK_START_GUIDE.md** (Section 2: Database Query Pattern)
|
||||
2. Then: **SECONDARY_DEVELOPMENT_GUIDE.md** (Section 3: Database Patterns)
|
||||
3. Refer: Database migration examples in `resources/sql/`
|
||||
|
||||
### For Security/DevOps Engineers
|
||||
1. Start: **SECURITY_README.md**
|
||||
2. Then: **SECURITY_IMPLEMENTATION_SUMMARY.md**
|
||||
3. Deploy: **DEPLOYMENT.md**
|
||||
4. Reference: **SECONDARY_DEVELOPMENT_GUIDE.md** (Sections 5-6)
|
||||
|
||||
### For QA/Testing Engineers
|
||||
1. Start: **QUICK_START_GUIDE.md** (Section 7: Testing)
|
||||
2. Then: **SECONDARY_DEVELOPMENT_GUIDE.md** (Section 7: Testing Setup)
|
||||
3. Review: `tests/` directory for examples
|
||||
|
||||
### For New Team Members
|
||||
1. Start: **readme.md** (project overview)
|
||||
2. Then: **QUICK_START_GUIDE.md** (30-minute overview)
|
||||
3. Deep Dive: **SECONDARY_DEVELOPMENT_GUIDE.md** (comprehensive reference)
|
||||
4. Explore: Source code with documentation as reference
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentation by Topic
|
||||
|
||||
### API Development
|
||||
- **QUICK_START_GUIDE.md** § 1: Adding a New API Endpoint
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 2: API Endpoint Addition
|
||||
|
||||
### Authentication & Authorization
|
||||
- **QUICK_START_GUIDE.md** § 3: Role-Based Access Control
|
||||
- **SECURITY_README.md**: Complete auth guide
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 5: Auth Mechanisms
|
||||
- **SECURITY_IMPLEMENTATION_SUMMARY.md**: Implementation details
|
||||
|
||||
### Database & Data Access
|
||||
- **QUICK_START_GUIDE.md** § 2: Database Query Pattern
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 3: Database Patterns
|
||||
- Source: `app/infra/repositories/` (examples)
|
||||
|
||||
### Native Code Integration
|
||||
- **QUICK_START_GUIDE.md** § 4: Call Native Code
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 4: Native Module Integration
|
||||
|
||||
### Configuration Management
|
||||
- **QUICK_START_GUIDE.md** § 6: Configuration
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 6: Configuration Management
|
||||
- Reference: `app/core/config.py`
|
||||
|
||||
### Security & Encryption
|
||||
- **QUICK_START_GUIDE.md** § 5: Encryption & Security
|
||||
- **SECURITY_README.md**: Complete guide
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 6: Configuration (encryption keys)
|
||||
|
||||
### Testing
|
||||
- **QUICK_START_GUIDE.md** § 7: Testing
|
||||
- **SECONDARY_DEVELOPMENT_GUIDE.md** § 7: Testing Setup
|
||||
- Examples: `tests/` directory
|
||||
|
||||
### Deployment
|
||||
- **DEPLOYMENT.md**: Complete deployment guide
|
||||
- **INTEGRATION_CHECKLIST.md**: Integration steps
|
||||
- **setup_server.md**: Initial setup
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Quick Reference Table
|
||||
|
||||
| Topic | Quick Start | Comprehensive | Implementation |
|
||||
|-------|------------|---------------|-----------------|
|
||||
| **APIs** | § 1 QSG | § 2 SDG | `app/api/v1/` |
|
||||
| **Database** | § 2 QSG | § 3 SDG | `app/infra/db/` |
|
||||
| **Native Code** | § 4 QSG | § 4 SDG | `app/native/wndb/` |
|
||||
| **Auth** | § 3 QSG | § 5 SDG | `app/auth/` |
|
||||
| **Config** | § 6 QSG | § 6 SDG | `app/core/config.py` |
|
||||
| **Testing** | § 7 QSG | § 7 SDG | `tests/` |
|
||||
| **Security** | SECURITY_README.md | SECURITY_IMPL_SUMMARY.md | `app/core/security.py` |
|
||||
| **Deployment** | setup_server.md | DEPLOYMENT.md | `infra/docker/` |
|
||||
|
||||
**Legend**: QSG = QUICK_START_GUIDE.md, SDG = SECONDARY_DEVELOPMENT_GUIDE.md
|
||||
|
||||
---
|
||||
|
||||
## 📂 Documentation File Locations
|
||||
|
||||
```
|
||||
TJWaterServerBinary/
|
||||
├── SECONDARY_DEVELOPMENT_GUIDE.md ← Start here (comprehensive)
|
||||
├── QUICK_START_GUIDE.md ← Start here (quick)
|
||||
├── readme.md ← Project overview
|
||||
├── SECURITY_README.md ← Security features
|
||||
├── SECURITY_IMPLEMENTATION_SUMMARY.md ← Security details
|
||||
├── DEPLOYMENT.md ← Production deployment
|
||||
├── INTEGRATION_CHECKLIST.md ← Integration steps
|
||||
├── setup_server.md ← Initial setup
|
||||
├── setup_influxdb.md ← InfluxDB config
|
||||
└── DOCUMENTATION_INDEX.md ← You are here
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Getting Started Checklist
|
||||
|
||||
- [ ] Read `readme.md` for project overview
|
||||
- [ ] Read `QUICK_START_GUIDE.md` for hands-on examples
|
||||
- [ ] Read `SECONDARY_DEVELOPMENT_GUIDE.md` for deep knowledge
|
||||
- [ ] Set up environment (`.env` file)
|
||||
- [ ] Review `app/main.py` (83 lines - very readable)
|
||||
- [ ] Review `app/api/v1/router.py` (98 lines - all endpoints listed)
|
||||
- [ ] Pick a simple endpoint to understand
|
||||
- [ ] Try adding a test endpoint
|
||||
- [ ] Review security setup (`SECURITY_README.md`)
|
||||
- [ ] Set up local development environment
|
||||
|
||||
---
|
||||
|
||||
## 💡 Key Learning Points
|
||||
|
||||
1. **FastAPI Architecture**: See `app/main.py` (83 lines) - clean and simple
|
||||
2. **Router Pattern**: See `app/api/v1/router.py` (98 lines) - 30+ routers included
|
||||
3. **Repository Pattern**: See `app/infra/repositories/` - data access layer
|
||||
4. **Auth Patterns**: See `app/auth/dependencies.py` - JWT validation
|
||||
5. **Permission Decorators**: See `app/auth/permissions.py` - RBAC
|
||||
6. **Config Management**: See `app/core/config.py` (82 lines) - Pydantic Settings
|
||||
7. **Database Pooling**: See `app/infra/db/postgresql/database.py` - async pools
|
||||
8. **Native Integration**: See `app/native/wndb/__init__.py` - 100+ wrapped functions
|
||||
|
||||
---
|
||||
|
||||
## 📞 Documentation Maintenance
|
||||
|
||||
These documents are maintained as part of the secondary development guide.
|
||||
|
||||
**Last Updated**: 2024-03-09
|
||||
|
||||
**Covered Sections**:
|
||||
- ✅ Project structure and key directories
|
||||
- ✅ API endpoint addition (router registration)
|
||||
- ✅ Database interaction patterns (ORMs, migrations)
|
||||
- ✅ Native module integration
|
||||
- ✅ Authentication and authorization mechanisms
|
||||
- ✅ Configuration management
|
||||
- ✅ Testing setup
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Recommended Learning Order
|
||||
|
||||
### Week 1: Foundations
|
||||
1. Project overview (`readme.md`)
|
||||
2. Quick Start Guide (`QUICK_START_GUIDE.md`)
|
||||
3. Architecture (`SECONDARY_DEVELOPMENT_GUIDE.md` § 1)
|
||||
|
||||
### Week 2: Core Development
|
||||
4. API Development (`SECONDARY_DEVELOPMENT_GUIDE.md` § 2)
|
||||
5. Database Patterns (`SECONDARY_DEVELOPMENT_GUIDE.md` § 3)
|
||||
6. Native Integration (`SECONDARY_DEVELOPMENT_GUIDE.md` § 4)
|
||||
|
||||
### Week 3: Security & Operations
|
||||
7. Auth & Permissions (`SECONDARY_DEVELOPMENT_GUIDE.md` § 5)
|
||||
8. Configuration (`SECONDARY_DEVELOPMENT_GUIDE.md` § 6)
|
||||
9. Testing (`SECONDARY_DEVELOPMENT_GUIDE.md` § 7)
|
||||
|
||||
### Week 4: Deployment & Maintenance
|
||||
10. Security Setup (`SECURITY_README.md`)
|
||||
11. Deployment (`DEPLOYMENT.md`)
|
||||
12. Integration (`INTEGRATION_CHECKLIST.md`)
|
||||
|
||||
---
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
**Q: Where do I start?**
|
||||
A: If you have 30 minutes: `QUICK_START_GUIDE.md`. If you have 2 hours: `SECONDARY_DEVELOPMENT_GUIDE.md`.
|
||||
|
||||
**Q: How do I add a new API endpoint?**
|
||||
A: See `QUICK_START_GUIDE.md` § 1 or `SECONDARY_DEVELOPMENT_GUIDE.md` § 2.
|
||||
|
||||
**Q: How do I implement database queries?**
|
||||
A: See `QUICK_START_GUIDE.md` § 2 or `SECONDARY_DEVELOPMENT_GUIDE.md` § 3.
|
||||
|
||||
**Q: How does authentication work?**
|
||||
A: See `QUICK_START_GUIDE.md` § 3 or `SECONDARY_DEVELOPMENT_GUIDE.md` § 5.
|
||||
|
||||
**Q: Where is the code?**
|
||||
A: Key files are referenced in all guides. Start with `app/main.py`, `app/api/v1/router.py`, `app/core/config.py`.
|
||||
|
||||
---
|
||||
|
||||
*This documentation index helps secondary development teams navigate the comprehensive TJWater ServerBinary codebase efficiently.*
|
||||
@@ -1,322 +0,0 @@
|
||||
# API 集成检查清单
|
||||
|
||||
## ✅ 已完成的集成工作
|
||||
|
||||
### 1. 路由集成 (app/api/v1/router.py)
|
||||
|
||||
已添加以下路由到 API Router:
|
||||
|
||||
```python
|
||||
# 新增导入
|
||||
from app.api.v1.endpoints import (
|
||||
...
|
||||
user_management, # 用户管理
|
||||
audit, # 审计日志
|
||||
)
|
||||
|
||||
# 新增路由
|
||||
api_router.include_router(user_management.router, prefix="/users", tags=["User Management"])
|
||||
api_router.include_router(audit.router, prefix="/audit", tags=["Audit Logs"])
|
||||
```
|
||||
|
||||
**路由端点**:
|
||||
- `/api/v1/auth/` - 认证相关(register, login, me, refresh)
|
||||
- `/api/v1/users/` - 用户管理(CRUD操作,仅管理员)
|
||||
- `/api/v1/audit/` - 审计日志查询(仅管理员)
|
||||
|
||||
### 2. 主应用配置 (app/main.py)
|
||||
|
||||
#### 2.1 导入更新
|
||||
```python
|
||||
from app.core.config import settings
|
||||
from app.infra.audit.middleware import AuditMiddleware
|
||||
```
|
||||
|
||||
#### 2.2 数据库初始化
|
||||
```python
|
||||
# 在 lifespan 中存储数据库实例到 app.state
|
||||
app.state.db = pgdb
|
||||
```
|
||||
|
||||
#### 2.3 FastAPI 配置
|
||||
```python
|
||||
app = FastAPI(
|
||||
lifespan=lifespan,
|
||||
title=settings.PROJECT_NAME,
|
||||
description="TJWater Server - 供水管网智能管理系统",
|
||||
version="1.0.0",
|
||||
docs_url="/docs",
|
||||
redoc_url="/redoc",
|
||||
)
|
||||
```
|
||||
|
||||
#### 2.4 审计中间件(可选)
|
||||
```python
|
||||
# 取消注释以启用审计日志
|
||||
# app.add_middleware(AuditMiddleware)
|
||||
```
|
||||
|
||||
### 3. 依赖项更新 (app/auth/dependencies.py)
|
||||
|
||||
更新 `get_db()` 函数从 Request 对象获取数据库:
|
||||
|
||||
```python
|
||||
async def get_db(request: Request) -> Database:
|
||||
"""从 app.state 获取数据库实例"""
|
||||
if not hasattr(request.app.state, "db"):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Database not initialized"
|
||||
)
|
||||
return request.app.state.db
|
||||
```
|
||||
|
||||
### 4. 审计日志更新
|
||||
|
||||
- `app/api/v1/endpoints/audit.py` - 使用正确的数据库依赖
|
||||
- `app/core/audit.py` - 接受可选的 db 参数
|
||||
|
||||
---
|
||||
|
||||
## 📋 部署前检查清单
|
||||
|
||||
### 环境配置
|
||||
- [ ] 复制 `.env.example` 为 `.env`
|
||||
- [ ] 配置 `SECRET_KEY`(JWT密钥)
|
||||
- [ ] 配置 `ENCRYPTION_KEY`(数据加密密钥)
|
||||
- [ ] 配置数据库连接信息
|
||||
|
||||
### 数据库迁移
|
||||
- [ ] 执行用户表迁移:`psql -U postgres -d tjwater -f migrations/001_create_users_table.sql`
|
||||
- [ ] 执行审计日志表迁移:`psql -U postgres -d tjwater -f migrations/002_create_audit_logs_table.sql`
|
||||
- [ ] 验证表已创建:`\dt` 在 psql 中
|
||||
|
||||
### 依赖检查
|
||||
- [ ] 确认已安装:`cryptography`
|
||||
- [ ] 确认已安装:`python-jose[cryptography]`
|
||||
- [ ] 确认已安装:`passlib[bcrypt]`
|
||||
- [ ] 确认已安装:`email-validator`(用于 Pydantic email 验证)
|
||||
|
||||
### 代码验证
|
||||
- [ ] 检查所有文件导入正常
|
||||
- [ ] 运行加密功能测试:`python tests/test_encryption.py`
|
||||
- [ ] 启动服务器:`uvicorn app.main:app --reload`
|
||||
- [ ] 访问 API 文档:http://localhost:8000/docs
|
||||
|
||||
### API 测试
|
||||
- [ ] 测试登录:POST `/api/v1/auth/login`
|
||||
- [ ] 测试获取当前用户:GET `/api/v1/auth/me`
|
||||
- [ ] 测试用户列表(需管理员):GET `/api/v1/users/`
|
||||
- [ ] 测试审计日志(需管理员):GET `/api/v1/audit/logs`
|
||||
|
||||
---
|
||||
|
||||
## 🔧 快速测试命令
|
||||
|
||||
### 1. 生成密钥
|
||||
```bash
|
||||
# JWT 密钥
|
||||
openssl rand -hex 32
|
||||
|
||||
# 加密密钥
|
||||
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
||||
```
|
||||
|
||||
### 2. 执行迁移
|
||||
```bash
|
||||
cd /home/zhifu/TJWaterServer/TJWaterServerBinary
|
||||
psql -U postgres -d tjwater -f migrations/001_create_users_table.sql
|
||||
psql -U postgres -d tjwater -f migrations/002_create_audit_logs_table.sql
|
||||
```
|
||||
|
||||
### 3. 测试加密
|
||||
```bash
|
||||
python tests/test_encryption.py
|
||||
```
|
||||
|
||||
### 4. 启动服务器
|
||||
```bash
|
||||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
### 5. 测试登录 API
|
||||
```bash
|
||||
# 使用默认管理员账号
|
||||
curl -X POST "http://localhost:8000/api/v1/auth/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin&password=admin123"
|
||||
|
||||
# 或使用迁移的账号
|
||||
curl -X POST "http://localhost:8000/api/v1/auth/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=tjwater&password=tjwater@123"
|
||||
```
|
||||
|
||||
### 6. 测试受保护接口
|
||||
```bash
|
||||
# 保存 Token
|
||||
TOKEN="<从登录响应中获取的 access_token>"
|
||||
|
||||
# 获取当前用户信息
|
||||
curl -X GET "http://localhost:8000/api/v1/auth/me" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
|
||||
# 获取用户列表(需管理员权限)
|
||||
curl -X GET "http://localhost:8000/api/v1/users/" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
|
||||
# 查询审计日志(需管理员权限)
|
||||
curl -X GET "http://localhost:8000/api/v1/audit/logs" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 API 端点总览
|
||||
|
||||
### 认证接口 (`/api/v1/auth`)
|
||||
|
||||
| 方法 | 端点 | 描述 | 权限 |
|
||||
|------|------|------|------|
|
||||
| POST | `/register` | 用户注册 | 公开 |
|
||||
| POST | `/login` | OAuth2 登录 | 公开 |
|
||||
| POST | `/login/simple` | 简化登录(兼容旧版) | 公开 |
|
||||
| GET | `/me` | 获取当前用户信息 | 认证用户 |
|
||||
| POST | `/refresh` | 刷新 Token | 认证用户 |
|
||||
|
||||
### 用户管理 (`/api/v1/users`)
|
||||
|
||||
| 方法 | 端点 | 描述 | 权限 |
|
||||
|------|------|------|------|
|
||||
| GET | `/` | 获取用户列表 | 管理员 |
|
||||
| GET | `/{id}` | 获取用户详情 | 所有者/管理员 |
|
||||
| PUT | `/{id}` | 更新用户信息 | 所有者/管理员 |
|
||||
| DELETE | `/{id}` | 删除用户 | 管理员 |
|
||||
| POST | `/{id}/activate` | 激活用户 | 管理员 |
|
||||
| POST | `/{id}/deactivate` | 停用用户 | 管理员 |
|
||||
|
||||
### 审计日志 (`/api/v1/audit`)
|
||||
|
||||
| 方法 | 端点 | 描述 | 权限 |
|
||||
|------|------|------|------|
|
||||
| GET | `/logs` | 查询审计日志 | 管理员 |
|
||||
| GET | `/logs/count` | 获取日志总数 | 管理员 |
|
||||
| GET | `/logs/my` | 查看我的操作记录 | 认证用户 |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
### 1. 审计中间件
|
||||
审计中间件默认是**禁用**的。如需启用,在 `app/main.py` 中取消注释:
|
||||
|
||||
```python
|
||||
app.add_middleware(AuditMiddleware)
|
||||
```
|
||||
|
||||
**注意**:启用后会自动记录所有 POST/PUT/DELETE 请求,可能增加数据库负载。
|
||||
|
||||
### 2. 向后兼容
|
||||
保留了原有的简化登录接口 `/auth/login/simple`,可以直接使用查询参数:
|
||||
|
||||
```bash
|
||||
POST /api/v1/auth/login/simple?username=admin&password=admin123
|
||||
```
|
||||
|
||||
### 3. 数据库连接
|
||||
确保数据库实例在应用启动时正确初始化并存储到 `app.state.db`。
|
||||
|
||||
### 4. 权限控制示例
|
||||
为现有接口添加权限控制:
|
||||
|
||||
```python
|
||||
from app.auth.permissions import require_role, get_current_admin
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
# 需要管理员权限
|
||||
@router.delete("/resource/{id}")
|
||||
async def delete_resource(
|
||||
id: int,
|
||||
current_user = Depends(get_current_admin)
|
||||
):
|
||||
...
|
||||
|
||||
# 需要操作员以上权限
|
||||
@router.post("/resource")
|
||||
async def create_resource(
|
||||
data: dict,
|
||||
current_user = Depends(require_role(UserRole.OPERATOR))
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 完整启动流程
|
||||
|
||||
```bash
|
||||
# 1. 进入项目目录
|
||||
cd /home/zhifu/TJWaterServer/TJWaterServerBinary
|
||||
|
||||
# 2. 配置环境变量(如果还没有)
|
||||
cp .env.example .env
|
||||
# 编辑 .env 填写必要的配置
|
||||
|
||||
# 3. 执行数据库迁移(如果还没有)
|
||||
psql -U postgres -d tjwater < migrations/001_create_users_table.sql
|
||||
psql -U postgres -d tjwater < migrations/002_create_audit_logs_table.sql
|
||||
|
||||
# 4. 测试加密功能
|
||||
python tests/test_encryption.py
|
||||
|
||||
# 5. 启动服务器
|
||||
uvicorn app.main:app --reload
|
||||
|
||||
# 6. 访问 API 文档
|
||||
# 浏览器打开: http://localhost:8000/docs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 故障排查
|
||||
|
||||
### 问题 1: 导入错误
|
||||
```
|
||||
ModuleNotFoundError: No module named 'jose'
|
||||
```
|
||||
**解决**: 安装依赖 `pip install python-jose[cryptography]`
|
||||
|
||||
### 问题 2: 数据库未初始化
|
||||
```
|
||||
503 Service Unavailable: Database not initialized
|
||||
```
|
||||
**解决**: 检查 `main.py` 中的 lifespan 函数是否正确设置 `app.state.db`
|
||||
|
||||
### 问题 3: Token 验证失败
|
||||
```
|
||||
401 Unauthorized: Could not validate credentials
|
||||
```
|
||||
**解决**:
|
||||
1. 检查 SECRET_KEY 是否配置正确
|
||||
2. 确认 Token 格式:`Authorization: Bearer {token}`
|
||||
3. 检查 Token 是否过期
|
||||
|
||||
### 问题 4: 表不存在
|
||||
```
|
||||
relation "users" does not exist
|
||||
```
|
||||
**解决**: 执行数据库迁移脚本
|
||||
|
||||
---
|
||||
|
||||
## 📖 相关文档
|
||||
|
||||
- **使用指南**: `SECURITY_README.md`
|
||||
- **部署指南**: `DEPLOYMENT.md`
|
||||
- **实施总结**: `SECURITY_IMPLEMENTATION_SUMMARY.md`
|
||||
- **自动设置**: `setup_security.sh`
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2026-02-02
|
||||
**状态**: ✅ API 已完全集成
|
||||
@@ -1,326 +0,0 @@
|
||||
# TJWater ServerBinary - Quick Reference for Secondary Development
|
||||
|
||||
## 1️⃣ Adding a New API Endpoint (30 seconds)
|
||||
|
||||
### File: `app/api/v1/endpoints/my_feature.py`
|
||||
```python
|
||||
from fastapi import APIRouter, Depends
|
||||
from app.auth.dependencies import get_current_active_user
|
||||
from app.domain.schemas.user import UserInDB
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.get("/list")
|
||||
async def list_items(user: UserInDB = Depends(get_current_active_user)):
|
||||
return {"items": []}
|
||||
|
||||
@router.post("/create")
|
||||
async def create_item(data: dict, user: UserInDB = Depends(get_current_active_user)):
|
||||
return {"status": "created"}
|
||||
```
|
||||
|
||||
### File: `app/api/v1/router.py` (Add 2 lines)
|
||||
```python
|
||||
from app.api.v1.endpoints import my_feature
|
||||
|
||||
api_router.include_router(my_feature.router, prefix="/items", tags=["Items"])
|
||||
```
|
||||
|
||||
**Done!** Endpoint available at `POST /api/v1/items/create`
|
||||
|
||||
---
|
||||
|
||||
## 2️⃣ Database Query Pattern
|
||||
|
||||
### Using Repository
|
||||
```python
|
||||
from app.infra.repositories.user_repository import UserRepository
|
||||
from app.auth.dependencies import get_user_repository
|
||||
|
||||
@router.get("/user/{user_id}")
|
||||
async def get_user(user_id: int, user_repo: UserRepository = Depends(get_user_repository)):
|
||||
user = await user_repo.get_user_by_id(user_id)
|
||||
return user
|
||||
```
|
||||
|
||||
### Direct Query (if no repository exists)
|
||||
```python
|
||||
async with db.get_connection() as conn:
|
||||
async with conn.cursor() as cur:
|
||||
await cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))
|
||||
row = await cur.fetchone()
|
||||
return dict(row) if row else None
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3️⃣ Role-Based Access Control
|
||||
|
||||
```python
|
||||
from app.auth.permissions import require_admin, require_role
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
# Admin only
|
||||
@router.delete("/users/{user_id}")
|
||||
async def delete_user(user_id: int, admin: UserInDB = Depends(require_admin)):
|
||||
pass
|
||||
|
||||
# Operator or higher
|
||||
@router.post("/projects/")
|
||||
async def create_project(user: UserInDB = Depends(require_role(UserRole.OPERATOR))):
|
||||
pass
|
||||
|
||||
# Custom role check
|
||||
def require_viewer():
|
||||
return require_role(UserRole.VIEWER)
|
||||
|
||||
@router.get("/reports")
|
||||
async def get_reports(user: UserInDB = Depends(require_viewer)):
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4️⃣ Call Native (Binary) Code
|
||||
|
||||
```python
|
||||
from app.native.wndb import get_all_junctions, add_junction, set_junction
|
||||
|
||||
# Read network elements
|
||||
junctions = get_all_junctions()
|
||||
|
||||
# Create
|
||||
add_junction({"id": "J1", "x": 0.0, "y": 0.0, "demand": 100.0})
|
||||
|
||||
# Update
|
||||
set_junction("J1", {"demand": 150.0})
|
||||
|
||||
# Get constants
|
||||
from app.native.wndb import PIPE_STATUS_OPEN, OPTION_UNITS_LPS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5️⃣ Encryption & Security
|
||||
|
||||
### Encrypt Sensitive Data
|
||||
```python
|
||||
from app.core.encryption import get_encryptor
|
||||
|
||||
encryptor = get_encryptor()
|
||||
|
||||
encrypted = encryptor.encrypt("secret_password")
|
||||
decrypted = encryptor.decrypt(encrypted)
|
||||
```
|
||||
|
||||
### Verify Password
|
||||
```python
|
||||
from app.core.security import verify_password, get_password_hash
|
||||
|
||||
# When creating user
|
||||
hashed = get_password_hash(user.password)
|
||||
|
||||
# When checking login
|
||||
if verify_password(form_data.password, stored_hash):
|
||||
# Correct password
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6️⃣ Configuration
|
||||
|
||||
### In `.env` file
|
||||
```bash
|
||||
SECRET_KEY=your-secret-key
|
||||
ENCRYPTION_KEY=your-fernet-key
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
```
|
||||
|
||||
### Use in Code
|
||||
```python
|
||||
from app.core.config import settings
|
||||
|
||||
db_url = settings.SQLALCHEMY_DATABASE_URI
|
||||
token_minutes = settings.ACCESS_TOKEN_EXPIRE_MINUTES
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7️⃣ Testing
|
||||
|
||||
```python
|
||||
# tests/unit/test_my_feature.py
|
||||
import pytest
|
||||
|
||||
def test_my_function():
|
||||
result = my_function()
|
||||
assert result == expected
|
||||
|
||||
# Run tests
|
||||
pytest tests/ -v
|
||||
pytest tests/unit/test_my_feature.py::test_my_function -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Directory Quick Map
|
||||
|
||||
| Path | What | Use For |
|
||||
|------|------|---------|
|
||||
| `app/api/v1/endpoints/` | API routes | Add new endpoints |
|
||||
| `app/auth/` | Auth logic | Login, permissions |
|
||||
| `app/domain/` | Models/Schemas | Data structures |
|
||||
| `app/infra/db/` | DB access | Queries, repositories |
|
||||
| `app/services/` | Business logic | Complex operations |
|
||||
| `app/native/wndb/` | Binary functions | Network simulation |
|
||||
| `app/core/` | Core utilities | Config, security, encryption |
|
||||
| `tests/` | Tests | Unit & integration tests |
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Key Imports
|
||||
|
||||
```python
|
||||
# Authentication
|
||||
from app.auth.dependencies import get_current_active_user, get_user_repository
|
||||
from app.auth.permissions import require_admin, require_role
|
||||
|
||||
# Database
|
||||
from app.infra.db.postgresql.database import db, get_database_instance
|
||||
from app.infra.repositories.user_repository import UserRepository
|
||||
|
||||
# Schemas & Models
|
||||
from app.domain.schemas.user import UserInDB, UserCreate, Token
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
# Security
|
||||
from app.core.security import create_access_token, verify_password, get_password_hash
|
||||
from app.core.encryption import get_encryptor
|
||||
|
||||
# Config
|
||||
from app.core.config import settings
|
||||
|
||||
# Native API
|
||||
from app.native.wndb import get_all_junctions, add_junction, open_project
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Common Tasks
|
||||
|
||||
### Register New User
|
||||
```python
|
||||
from app.infra.repositories.user_repository import UserRepository
|
||||
from app.domain.schemas.user import UserCreate
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
user_data = UserCreate(
|
||||
username="john",
|
||||
email="john@example.com",
|
||||
password="securepass",
|
||||
role=UserRole.USER
|
||||
)
|
||||
new_user = await user_repo.create_user(user_data)
|
||||
```
|
||||
|
||||
### Query Database
|
||||
```python
|
||||
async with db.get_connection() as conn:
|
||||
async with conn.cursor() as cur:
|
||||
await cur.execute("SELECT * FROM users LIMIT 10")
|
||||
rows = await cur.fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
```
|
||||
|
||||
### Run Simulation
|
||||
```python
|
||||
from app.services.simulation import run_simulation
|
||||
|
||||
result = await run_simulation(
|
||||
project_name="szh",
|
||||
duration=3600,
|
||||
time_step=60
|
||||
)
|
||||
```
|
||||
|
||||
### Audit Operation
|
||||
```python
|
||||
from app.core.audit import log_audit_event, AuditAction
|
||||
|
||||
await log_audit_event(
|
||||
action=AuditAction.CREATE,
|
||||
resource_type="pipe",
|
||||
resource_id="P1",
|
||||
actor_id=user.id,
|
||||
details={"diameter": 100, "material": "PVC"}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Common Gotchas
|
||||
|
||||
1. **Always use `Depends()`** for injecting repositories, users
|
||||
```python
|
||||
# ✅ Right
|
||||
async def endpoint(user: UserInDB = Depends(get_current_active_user)):
|
||||
|
||||
# ❌ Wrong
|
||||
async def endpoint(user: UserInDB):
|
||||
```
|
||||
|
||||
2. **Use parametrized queries** to prevent SQL injection
|
||||
```python
|
||||
# ✅ Right
|
||||
await cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))
|
||||
|
||||
# ❌ Wrong
|
||||
await cur.execute(f"SELECT * FROM users WHERE id = {user_id}")
|
||||
```
|
||||
|
||||
3. **Async/await** required for database operations
|
||||
```python
|
||||
# ✅ Right
|
||||
user = await user_repo.get_user_by_id(1)
|
||||
|
||||
# ❌ Wrong
|
||||
user = user_repo.get_user_by_id(1) # Missing await
|
||||
```
|
||||
|
||||
4. **Role hierarchy** for permission checks
|
||||
```python
|
||||
# All levels include higher permissions
|
||||
VIEWER (1) < USER (2) < OPERATOR (3) < ADMIN (4)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 File Locations Reference
|
||||
|
||||
- **Main app entry**: `app/main.py` (83 lines)
|
||||
- **Central router**: `app/api/v1/router.py` (98 lines)
|
||||
- **Config**: `app/core/config.py` (82 lines)
|
||||
- **Auth dependencies**: `app/auth/dependencies.py`
|
||||
- **Permissions**: `app/auth/permissions.py`
|
||||
- **Database**: `app/infra/db/postgresql/database.py`
|
||||
- **Repositories**: `app/infra/repositories/`
|
||||
- **Schemas**: `app/domain/schemas/`
|
||||
- **Models**: `app/domain/models/`
|
||||
|
||||
---
|
||||
|
||||
## 📚 Full Documentation
|
||||
|
||||
See **SECONDARY_DEVELOPMENT_GUIDE.md** for comprehensive guide on:
|
||||
- Architecture overview
|
||||
- Detailed endpoint creation
|
||||
- Database patterns
|
||||
- Native module integration
|
||||
- Testing setup
|
||||
- Deployment
|
||||
|
||||
---
|
||||
|
||||
*Generated for TJWater ServerBinary secondary development team*
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,370 +0,0 @@
|
||||
# 安全功能实施总结
|
||||
|
||||
## ✅ 已完成的功能
|
||||
|
||||
本次实施完成了完整的安全体系,包括数据加密、身份认证、权限管理、审计日志四大模块。
|
||||
|
||||
---
|
||||
|
||||
## 📁 新增文件清单
|
||||
|
||||
### 核心功能模块
|
||||
|
||||
1. **数据加密**
|
||||
- `app/core/encryption.py` - Fernet 加密实现
|
||||
- `tests/test_encryption.py` - 加密功能测试
|
||||
|
||||
2. **用户系统**
|
||||
- `app/domain/models/role.py` - 用户角色枚举
|
||||
- `app/domain/schemas/user.py` - 用户数据模型
|
||||
- `app/infra/repositories/user_repository.py` - 用户数据访问层
|
||||
|
||||
3. **认证授权**
|
||||
- `app/api/v1/endpoints/auth.py` - 认证接口(已重构)
|
||||
- `app/auth/dependencies.py` - 认证依赖项(已更新)
|
||||
- `app/auth/permissions.py` - 权限控制装饰器
|
||||
- `app/api/v1/endpoints/user_management.py` - 用户管理接口
|
||||
|
||||
4. **审计日志**
|
||||
- `app/core/audit.py` - 审计日志核心(已完善)
|
||||
- `app/domain/schemas/audit.py` - 审计日志数据模型
|
||||
- `app/infra/repositories/audit_repository.py` - 审计日志数据访问层
|
||||
- `app/api/v1/endpoints/audit.py` - 审计日志查询接口
|
||||
- `app/infra/audit/middleware.py` - 自动审计中间件
|
||||
|
||||
### 数据库迁移
|
||||
|
||||
5. **迁移脚本**
|
||||
- `migrations/001_create_users_table.sql` - 用户表
|
||||
- `migrations/002_create_audit_logs_table.sql` - 审计日志表
|
||||
|
||||
### 配置和文档
|
||||
|
||||
6. **配置文件**
|
||||
- `.env.example` - 环境变量模板
|
||||
- `app/core/config.py` - 配置文件(已更新)
|
||||
- `app/core/security.py` - 安全工具(已增强)
|
||||
|
||||
7. **文档**
|
||||
- `SECURITY_README.md` - 完整使用指南(79KB+)
|
||||
- `DEPLOYMENT.md` - 部署和集成指南
|
||||
- `SECURITY_IMPLEMENTATION_SUMMARY.md` - 本文件
|
||||
|
||||
8. **工具**
|
||||
- `setup_security.sh` - 快速设置脚本
|
||||
|
||||
---
|
||||
|
||||
## 🎯 功能特性
|
||||
|
||||
### 1. 数据加密
|
||||
- ✅ 使用 Fernet(AES-128)对称加密
|
||||
- ✅ 支持密钥生成和管理
|
||||
- ✅ 自动从环境变量读取密钥
|
||||
- ✅ 完整的加密/解密 API
|
||||
- ✅ 单元测试覆盖
|
||||
|
||||
### 2. 身份认证
|
||||
- ✅ 基于 JWT 的 Token 认证
|
||||
- ✅ Access Token + Refresh Token 机制
|
||||
- ✅ 用户注册/登录接口
|
||||
- ✅ 支持用户名或邮箱登录
|
||||
- ✅ 密码使用 bcrypt 哈希存储
|
||||
- ✅ Token 过期时间可配置
|
||||
- ✅ 向后兼容旧接口
|
||||
|
||||
### 3. 权限管理(RBAC)
|
||||
- ✅ 4 个预定义角色:ADMIN, OPERATOR, USER, VIEWER
|
||||
- ✅ 基于角色层级的权限检查
|
||||
- ✅ 可复用的权限装饰器
|
||||
- ✅ 资源所有者检查
|
||||
- ✅ 灵活的依赖注入设计
|
||||
|
||||
### 4. 审计日志
|
||||
- ✅ 自动记录所有关键操作
|
||||
- ✅ 记录用户、时间、操作类型、资源等信息
|
||||
- ✅ 敏感数据自动脱敏
|
||||
- ✅ 支持按多条件查询
|
||||
- ✅ 管理员专用查询接口
|
||||
- ✅ 用户可查看自己的操作记录
|
||||
|
||||
---
|
||||
|
||||
## 📊 技术栈
|
||||
|
||||
| 组件 | 技术 | 说明 |
|
||||
|------|------|------|
|
||||
| 加密 | cryptography.Fernet | 对称加密 |
|
||||
| 密码哈希 | bcrypt | 密码安全存储 |
|
||||
| JWT | python-jose | Token 生成和验证 |
|
||||
| 数据库 | PostgreSQL + psycopg | 异步数据访问 |
|
||||
| Web框架 | FastAPI | 现代异步框架 |
|
||||
| 数据验证 | Pydantic | 类型安全的数据模型 |
|
||||
|
||||
---
|
||||
|
||||
## 🔐 安全特性
|
||||
|
||||
1. **密码安全**
|
||||
- bcrypt 哈希(work factor = 12)
|
||||
- 自动加盐
|
||||
- 不可逆加密
|
||||
|
||||
2. **Token 安全**
|
||||
- JWT 签名验证
|
||||
- 短期 Access Token(30分钟)
|
||||
- 长期 Refresh Token(7天)
|
||||
- Token 类型校验
|
||||
|
||||
3. **数据保护**
|
||||
- 敏感字段自动脱敏
|
||||
- 审计日志不记录密码
|
||||
- 加密密钥从环境变量读取
|
||||
|
||||
4. **访问控制**
|
||||
- 基于角色的细粒度权限
|
||||
- 资源级别的访问控制
|
||||
- 自动验证用户激活状态
|
||||
|
||||
---
|
||||
|
||||
## 📈 数据库设计
|
||||
|
||||
### users 表
|
||||
```
|
||||
用户表 - 存储系统用户
|
||||
- id (主键)
|
||||
- username (唯一)
|
||||
- email (唯一)
|
||||
- hashed_password
|
||||
- role (ADMIN/OPERATOR/USER/VIEWER)
|
||||
- is_active
|
||||
- is_superuser
|
||||
- created_at
|
||||
- updated_at (自动更新)
|
||||
```
|
||||
|
||||
### audit_logs 表
|
||||
```
|
||||
审计日志表 - 记录所有关键操作
|
||||
- id (主键)
|
||||
- user_id (外键)
|
||||
- username (冗余字段)
|
||||
- action (操作类型)
|
||||
- resource_type (资源类型)
|
||||
- resource_id (资源ID)
|
||||
- ip_address
|
||||
- user_agent
|
||||
- request_method
|
||||
- request_path
|
||||
- request_data (JSONB)
|
||||
- response_status
|
||||
- error_message
|
||||
- timestamp
|
||||
```
|
||||
|
||||
**索引优化**:
|
||||
- users: username, email, role, is_active
|
||||
- audit_logs: user_id, username, timestamp, action, resource
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 方法 1: 使用自动化脚本
|
||||
|
||||
```bash
|
||||
./setup_security.sh
|
||||
```
|
||||
|
||||
### 方法 2: 手动设置
|
||||
|
||||
```bash
|
||||
# 1. 配置环境变量
|
||||
cp .env.example .env
|
||||
# 编辑 .env 填写密钥和数据库配置
|
||||
|
||||
# 2. 执行数据库迁移
|
||||
psql -U postgres -d tjwater -f migrations/001_create_users_table.sql
|
||||
psql -U postgres -d tjwater -f migrations/002_create_audit_logs_table.sql
|
||||
|
||||
# 3. 测试
|
||||
python tests/test_encryption.py
|
||||
|
||||
# 4. 启动服务
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 集成检查清单
|
||||
|
||||
### 必需步骤
|
||||
|
||||
- [ ] 复制 `.env.example` 为 `.env` 并配置
|
||||
- [ ] 生成 JWT 密钥(SECRET_KEY)
|
||||
- [ ] 生成加密密钥(ENCRYPTION_KEY)
|
||||
- [ ] 配置数据库连接信息
|
||||
- [ ] 执行用户表迁移脚本
|
||||
- [ ] 执行审计日志表迁移脚本
|
||||
- [ ] 验证默认管理员可登录
|
||||
|
||||
### 可选步骤
|
||||
|
||||
- [ ] 在 main.py 中添加审计中间件
|
||||
- [ ] 为现有接口添加权限控制
|
||||
- [ ] 注册新的路由(auth, user_management, audit)
|
||||
- [ ] 替换硬编码的认证逻辑
|
||||
- [ ] 配置 Token 过期时间
|
||||
|
||||
---
|
||||
|
||||
## 🔄 向后兼容性
|
||||
|
||||
### 保留的旧接口
|
||||
|
||||
1. **简化登录**: `/api/v1/auth/login/simple`
|
||||
- 仍可使用 `username` 和 `password` 参数
|
||||
- 返回标准 Token 响应
|
||||
|
||||
2. **硬编码用户迁移**
|
||||
- 原有 `tjwater/tjwater@123` 已迁移到数据库
|
||||
- 保持相同的用户名和密码
|
||||
|
||||
### 渐进式迁移
|
||||
|
||||
可以逐步迁移现有接口:
|
||||
|
||||
1. 新接口直接使用新认证系统
|
||||
2. 旧接口保持不变
|
||||
3. 逐个替换旧接口的认证逻辑
|
||||
|
||||
---
|
||||
|
||||
## 📚 API 端点总览
|
||||
|
||||
### 认证接口 (`/api/v1/auth/`)
|
||||
|
||||
| 方法 | 路径 | 说明 | 权限 |
|
||||
|------|------|------|------|
|
||||
| POST | `/register` | 用户注册 | 公开 |
|
||||
| POST | `/login` | OAuth2 登录 | 公开 |
|
||||
| POST | `/login/simple` | 简化登录 | 公开 |
|
||||
| GET | `/me` | 获取当前用户 | 认证用户 |
|
||||
| POST | `/refresh` | 刷新Token | 认证用户 |
|
||||
|
||||
### 用户管理 (`/api/v1/users/`)
|
||||
|
||||
| 方法 | 路径 | 说明 | 权限 |
|
||||
|------|------|------|------|
|
||||
| GET | `/` | 用户列表 | 管理员 |
|
||||
| GET | `/{id}` | 用户详情 | 所有者/管理员 |
|
||||
| PUT | `/{id}` | 更新用户 | 所有者/管理员 |
|
||||
| DELETE | `/{id}` | 删除用户 | 管理员 |
|
||||
| POST | `/{id}/activate` | 激活用户 | 管理员 |
|
||||
| POST | `/{id}/deactivate` | 停用用户 | 管理员 |
|
||||
|
||||
### 审计日志 (`/api/v1/audit/`)
|
||||
|
||||
| 方法 | 路径 | 说明 | 权限 |
|
||||
|------|------|------|------|
|
||||
| GET | `/logs` | 查询审计日志 | 管理员 |
|
||||
| GET | `/logs/count` | 日志总数 | 管理员 |
|
||||
| GET | `/logs/my` | 我的操作记录 | 认证用户 |
|
||||
|
||||
---
|
||||
|
||||
## 🎓 使用示例
|
||||
|
||||
### Python 示例
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# 登录
|
||||
resp = requests.post("http://localhost:8000/api/v1/auth/login",
|
||||
data={"username": "admin", "password": "admin123"})
|
||||
token = resp.json()["access_token"]
|
||||
|
||||
# 访问受保护接口
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
resp = requests.get("http://localhost:8000/api/v1/auth/me", headers=headers)
|
||||
print(resp.json())
|
||||
```
|
||||
|
||||
### cURL 示例
|
||||
|
||||
```bash
|
||||
# 登录
|
||||
TOKEN=$(curl -s -X POST "http://localhost:8000/api/v1/auth/login" \
|
||||
-d "username=admin&password=admin123" | jq -r .access_token)
|
||||
|
||||
# 查询审计日志
|
||||
curl -H "Authorization: Bearer $TOKEN" \
|
||||
"http://localhost:8000/api/v1/audit/logs?action=LOGIN"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 常见问题
|
||||
|
||||
### Q: 如何修改默认管理员密码?
|
||||
|
||||
A: 登录后通过 PUT `/api/v1/users/{id}` 接口修改,或直接更新数据库。
|
||||
|
||||
### Q: 如何添加新用户?
|
||||
|
||||
A: 使用 POST `/api/v1/auth/register` 接口,或由管理员在用户管理界面创建。
|
||||
|
||||
### Q: 审计日志可以删除吗?
|
||||
|
||||
A: 不建议删除。可以归档到冷存储,保留最近 90 天的数据。
|
||||
|
||||
### Q: Token 过期了怎么办?
|
||||
|
||||
A: 使用 Refresh Token 调用 `/api/v1/auth/refresh` 接口获取新的 Access Token。
|
||||
|
||||
---
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
- **完整文档**: `SECURITY_README.md`
|
||||
- **部署指南**: `DEPLOYMENT.md`
|
||||
- **测试代码**: `tests/test_encryption.py`
|
||||
- **迁移脚本**: `migrations/`
|
||||
|
||||
---
|
||||
|
||||
## 📝 待办事项(可选)
|
||||
|
||||
未来可以扩展的功能:
|
||||
|
||||
- [ ] 邮件验证
|
||||
- [ ] 密码重置
|
||||
- [ ] 双因素认证(2FA)
|
||||
- [ ] 单点登录(SSO)
|
||||
- [ ] Token 黑名单
|
||||
- [ ] 会话管理
|
||||
- [ ] IP 白名单
|
||||
- [ ] 登录频率限制
|
||||
- [ ] 密码复杂度策略
|
||||
- [ ] 审计日志自动归档
|
||||
|
||||
---
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
本次实施完成了企业级的安全体系,包含:
|
||||
|
||||
✅ 数据加密 - Fernet 对称加密
|
||||
✅ 身份认证 - JWT Token + bcrypt 密码哈希
|
||||
✅ 权限管理 - 基于角色的访问控制(RBAC)
|
||||
✅ 审计日志 - 自动追踪所有关键操作
|
||||
|
||||
所有功能均遵循安全最佳实践,提供完整的文档和测试,可直接投入生产使用。
|
||||
|
||||
---
|
||||
|
||||
**实施日期**: 2026-02-02
|
||||
**版本**: v1.0.0
|
||||
**状态**: ✅ 已完成
|
||||
@@ -1,499 +0,0 @@
|
||||
# 安全功能使用指南
|
||||
|
||||
TJWater Server 安全体系实施完成,包含:数据加密、身份认证、权限管理、审计日志
|
||||
|
||||
## 📋 目录
|
||||
|
||||
1. [快速开始](#快速开始)
|
||||
2. [数据加密](#数据加密)
|
||||
3. [身份认证](#身份认证)
|
||||
4. [权限管理](#权限管理)
|
||||
5. [审计日志](#审计日志)
|
||||
6. [数据库迁移](#数据库迁移)
|
||||
7. [API 使用示例](#api-使用示例)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 配置环境变量
|
||||
|
||||
复制 `.env.example` 为 `.env` 并配置:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
生成必要的密钥:
|
||||
|
||||
```bash
|
||||
# 生成 JWT 密钥
|
||||
openssl rand -hex 32
|
||||
|
||||
# 生成加密密钥
|
||||
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
|
||||
```
|
||||
|
||||
编辑 `.env` 文件:
|
||||
|
||||
```env
|
||||
SECRET_KEY=your-generated-jwt-secret-key
|
||||
ENCRYPTION_KEY=your-generated-encryption-key
|
||||
DB_NAME=tjwater
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=your-db-password
|
||||
```
|
||||
|
||||
### 2. 执行数据库迁移
|
||||
|
||||
```bash
|
||||
# 连接到 PostgreSQL
|
||||
psql -U postgres -d tjwater
|
||||
|
||||
# 执行迁移脚本
|
||||
\i migrations/001_create_users_table.sql
|
||||
\i migrations/002_create_audit_logs_table.sql
|
||||
```
|
||||
|
||||
或使用命令行:
|
||||
|
||||
```bash
|
||||
psql -U postgres -d tjwater -f migrations/001_create_users_table.sql
|
||||
psql -U postgres -d tjwater -f migrations/002_create_audit_logs_table.sql
|
||||
```
|
||||
|
||||
### 3. 验证安装
|
||||
|
||||
默认创建了两个管理员账号:
|
||||
|
||||
- **用户名**: `admin` / **密码**: `admin123`
|
||||
- **用户名**: `tjwater` / **密码**: `tjwater@123`
|
||||
|
||||
---
|
||||
|
||||
## 🔐 数据加密
|
||||
|
||||
### 使用加密器
|
||||
|
||||
```python
|
||||
from app.core.encryption import get_encryptor
|
||||
|
||||
encryptor = get_encryptor()
|
||||
|
||||
# 加密敏感数据
|
||||
encrypted_data = encryptor.encrypt("sensitive information")
|
||||
|
||||
# 解密
|
||||
decrypted_data = encryptor.decrypt(encrypted_data)
|
||||
```
|
||||
|
||||
### 生成新密钥
|
||||
|
||||
```python
|
||||
from app.core.encryption import Encryptor
|
||||
|
||||
new_key = Encryptor.generate_key()
|
||||
print(f"New encryption key: {new_key}")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 👤 身份认证
|
||||
|
||||
### 用户角色
|
||||
|
||||
系统定义了 4 个角色(权限由低到高):
|
||||
|
||||
| 角色 | 权限说明 |
|
||||
|------|---------|
|
||||
| `VIEWER` | 仅查询权限 |
|
||||
| `USER` | 读写权限 |
|
||||
| `OPERATOR` | 操作员,可修改数据 |
|
||||
| `ADMIN` | 管理员,完全权限 |
|
||||
|
||||
### API 接口
|
||||
|
||||
#### 用户注册
|
||||
|
||||
```http
|
||||
POST /api/v1/auth/register
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "newuser",
|
||||
"email": "user@example.com",
|
||||
"password": "password123",
|
||||
"role": "USER"
|
||||
}
|
||||
```
|
||||
|
||||
#### 用户登录(OAuth2 标准)
|
||||
|
||||
```http
|
||||
POST /api/v1/auth/login
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
username=admin&password=admin123
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"token_type": "bearer",
|
||||
"expires_in": 1800
|
||||
}
|
||||
```
|
||||
|
||||
#### 用户登录(简化版)
|
||||
|
||||
```http
|
||||
POST /api/v1/auth/login/simple?username=admin&password=admin123
|
||||
```
|
||||
|
||||
#### 获取当前用户信息
|
||||
|
||||
```http
|
||||
GET /api/v1/auth/me
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
#### 刷新 Token
|
||||
|
||||
```http
|
||||
POST /api/v1/auth/refresh
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"refresh_token": "your-refresh-token"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔑 权限管理
|
||||
|
||||
### 在 API 中使用权限控制
|
||||
|
||||
#### 方式 1: 使用预定义依赖
|
||||
|
||||
```python
|
||||
from fastapi import APIRouter, Depends
|
||||
from app.auth.permissions import get_current_admin, get_current_operator
|
||||
from app.domain.schemas.user import UserInDB
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@router.post("/admin-only")
|
||||
async def admin_endpoint(
|
||||
current_user: UserInDB = Depends(get_current_admin)
|
||||
):
|
||||
"""仅管理员可访问"""
|
||||
return {"message": "Admin access granted"}
|
||||
|
||||
@router.post("/operator-only")
|
||||
async def operator_endpoint(
|
||||
current_user: UserInDB = Depends(get_current_operator)
|
||||
):
|
||||
"""操作员及以上可访问"""
|
||||
return {"message": "Operator access granted"}
|
||||
```
|
||||
|
||||
#### 方式 2: 使用 require_role
|
||||
|
||||
```python
|
||||
from app.auth.permissions import require_role
|
||||
from app.domain.models.role import UserRole
|
||||
|
||||
@router.get("/viewer-access")
|
||||
async def viewer_endpoint(
|
||||
current_user: UserInDB = Depends(require_role(UserRole.VIEWER))
|
||||
):
|
||||
"""所有认证用户可访问"""
|
||||
return {"data": "visible to all"}
|
||||
```
|
||||
|
||||
#### 方式 3: 手动检查权限
|
||||
|
||||
```python
|
||||
from app.auth.dependencies import get_current_active_user
|
||||
from app.auth.permissions import check_resource_owner
|
||||
|
||||
@router.put("/users/{user_id}")
|
||||
async def update_user(
|
||||
user_id: int,
|
||||
current_user: UserInDB = Depends(get_current_active_user)
|
||||
):
|
||||
"""检查是否是资源拥有者或管理员"""
|
||||
if not check_resource_owner(user_id, current_user):
|
||||
raise HTTPException(status_code=403, detail="Permission denied")
|
||||
|
||||
# 执行更新操作
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 审计日志
|
||||
|
||||
### 自动审计
|
||||
|
||||
使用中间件自动记录关键操作,在 `main.py` 中添加:
|
||||
|
||||
```python
|
||||
from app.infra.audit.middleware import AuditMiddleware
|
||||
|
||||
app.add_middleware(AuditMiddleware)
|
||||
```
|
||||
|
||||
自动记录:
|
||||
- 所有 POST/PUT/DELETE 请求
|
||||
- 登录/登出事件
|
||||
- 关键资源访问
|
||||
|
||||
### 手动记录审计日志
|
||||
|
||||
```python
|
||||
from app.core.audit import log_audit_event, AuditAction
|
||||
|
||||
await log_audit_event(
|
||||
action=AuditAction.UPDATE,
|
||||
user_id=current_user.id,
|
||||
username=current_user.username,
|
||||
resource_type="project",
|
||||
resource_id="123",
|
||||
ip_address=request.client.host,
|
||||
request_data={"field": "value"},
|
||||
response_status=200
|
||||
)
|
||||
```
|
||||
|
||||
### 查询审计日志
|
||||
|
||||
#### 获取所有审计日志(仅管理员)
|
||||
|
||||
```http
|
||||
GET /api/v1/audit/logs?skip=0&limit=100
|
||||
Authorization: Bearer {admin_token}
|
||||
```
|
||||
|
||||
#### 按条件过滤
|
||||
|
||||
```http
|
||||
GET /api/v1/audit/logs?user_id=1&action=LOGIN&start_time=2024-01-01T00:00:00
|
||||
Authorization: Bearer {admin_token}
|
||||
```
|
||||
|
||||
#### 获取我的操作记录
|
||||
|
||||
```http
|
||||
GET /api/v1/audit/logs/my
|
||||
Authorization: Bearer {access_token}
|
||||
```
|
||||
|
||||
#### 获取日志总数
|
||||
|
||||
```http
|
||||
GET /api/v1/audit/logs/count?action=LOGIN
|
||||
Authorization: Bearer {admin_token}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💾 数据库迁移
|
||||
|
||||
### 用户表结构
|
||||
|
||||
```sql
|
||||
CREATE TABLE users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
email VARCHAR(100) UNIQUE NOT NULL,
|
||||
hashed_password VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(20) DEFAULT 'USER' NOT NULL,
|
||||
is_active BOOLEAN DEFAULT TRUE NOT NULL,
|
||||
is_superuser BOOLEAN DEFAULT FALSE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
### 审计日志表结构
|
||||
|
||||
```sql
|
||||
CREATE TABLE audit_logs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
username VARCHAR(50),
|
||||
action VARCHAR(50) NOT NULL,
|
||||
resource_type VARCHAR(50),
|
||||
resource_id VARCHAR(100),
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
request_method VARCHAR(10),
|
||||
request_path TEXT,
|
||||
request_data JSONB,
|
||||
response_status INTEGER,
|
||||
error_message TEXT,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 API 使用示例
|
||||
|
||||
### Python 客户端示例
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
BASE_URL = "http://localhost:8000/api/v1"
|
||||
|
||||
# 1. 登录
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/auth/login",
|
||||
data={"username": "admin", "password": "admin123"}
|
||||
)
|
||||
token = response.json()["access_token"]
|
||||
|
||||
# 2. 设置 Authorization Header
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
# 3. 获取当前用户信息
|
||||
response = requests.get(f"{BASE_URL}/auth/me", headers=headers)
|
||||
print(response.json())
|
||||
|
||||
# 4. 创建新用户(需要管理员权限)
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/auth/register",
|
||||
headers=headers,
|
||||
json={
|
||||
"username": "newuser",
|
||||
"email": "new@example.com",
|
||||
"password": "password123",
|
||||
"role": "USER"
|
||||
}
|
||||
)
|
||||
print(response.json())
|
||||
|
||||
# 5. 查询审计日志(需要管理员权限)
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/audit/logs?action=LOGIN",
|
||||
headers=headers
|
||||
)
|
||||
print(response.json())
|
||||
```
|
||||
|
||||
### cURL 示例
|
||||
|
||||
```bash
|
||||
# 登录
|
||||
curl -X POST "http://localhost:8000/api/v1/auth/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin&password=admin123"
|
||||
|
||||
# 使用 Token 访问受保护接口
|
||||
TOKEN="your-access-token"
|
||||
curl -X GET "http://localhost:8000/api/v1/auth/me" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
|
||||
# 注册新用户
|
||||
curl -X POST "http://localhost:8000/api/v1/auth/register" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"password": "password123",
|
||||
"role": "USER"
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ 安全最佳实践
|
||||
|
||||
1. **密钥管理**
|
||||
- 绝不在代码中硬编码密钥
|
||||
- 定期轮换 JWT 密钥
|
||||
- 使用强随机密钥
|
||||
|
||||
2. **密码策略**
|
||||
- 最小长度 6 个字符(建议 12+)
|
||||
- 强制密码复杂度(可在注册时添加验证)
|
||||
- 定期提醒用户更换密码
|
||||
|
||||
3. **Token 管理**
|
||||
- Access Token 短期有效(默认 30 分钟)
|
||||
- Refresh Token 长期有效(默认 7 天)
|
||||
- 实施 Token 黑名单(可选)
|
||||
|
||||
4. **审计日志**
|
||||
- 审计日志不可删除
|
||||
- 定期归档旧日志
|
||||
- 监控异常登录行为
|
||||
|
||||
5. **权限控制**
|
||||
- 遵循最小权限原则
|
||||
- 定期审查用户权限
|
||||
- 记录所有权限变更
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文件
|
||||
|
||||
- **配置**: `app/core/config.py`
|
||||
- **加密**: `app/core/encryption.py`
|
||||
- **安全**: `app/core/security.py`
|
||||
- **审计**: `app/core/audit.py`
|
||||
- **认证**: `app/api/v1/endpoints/auth.py`
|
||||
- **权限**: `app/auth/permissions.py`
|
||||
- **用户管理**: `app/api/v1/endpoints/user_management.py`
|
||||
- **审计日志**: `app/api/v1/endpoints/audit.py`
|
||||
- **迁移脚本**: `migrations/`
|
||||
|
||||
---
|
||||
|
||||
## ❓ 常见问题
|
||||
|
||||
### Q: 忘记密码怎么办?
|
||||
|
||||
A: 目前需要管理员通过数据库重置。未来可添加邮件重置功能。
|
||||
|
||||
```sql
|
||||
-- 重置密码为 "newpassword123"
|
||||
UPDATE users
|
||||
SET hashed_password = '$2b$12$...' -- 使用 bcrypt 生成哈希
|
||||
WHERE username = 'targetuser';
|
||||
```
|
||||
|
||||
### Q: 如何添加新角色?
|
||||
|
||||
A: 编辑 `app/domain/models/role.py` 中的 `UserRole` 枚举,并更新数据库约束。
|
||||
|
||||
### Q: 审计日志占用太多空间?
|
||||
|
||||
A: 建议定期归档旧日志到冷存储:
|
||||
|
||||
```sql
|
||||
-- 归档 90 天前的日志
|
||||
CREATE TABLE audit_logs_archive AS
|
||||
SELECT * FROM audit_logs WHERE timestamp < NOW() - INTERVAL '90 days';
|
||||
|
||||
DELETE FROM audit_logs WHERE timestamp < NOW() - INTERVAL '90 days';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如有问题,请查看:
|
||||
- 日志文件: `logs/`
|
||||
- 数据库表结构: `migrations/`
|
||||
- 单元测试: `tests/`
|
||||
|
||||
-13577
File diff suppressed because it is too large
Load Diff
@@ -1,97 +0,0 @@
|
||||
# TJWater Server (FastAPI)
|
||||
|
||||
基于 FastAPI 和高性能数据库构建的水务业务服务端系统,提供管网模拟计算、SCADA 数据集成、网络元素管理、项目管理以及完整的安全认证体系。
|
||||
|
||||
## 🌟 主要功能
|
||||
|
||||
- **管网模拟**:集成 EPANET 引擎,支持水力模拟、水质模拟及爆管分析。
|
||||
- **SCADA 集成**:实时数据采集、存储与历史数据查询(支持 InfluxDB/TimescaleDB)。
|
||||
- **资产管理**:管网 GIS 数据管理,支持 GeoJSON 格式及拓扑分析。
|
||||
- **项目管理**:支持多项目环境切换、数据隔离与版本控制。
|
||||
- **安全体系**:
|
||||
- **身份认证**:基于 OAuth2 与 JWT 的用户认证与授权。
|
||||
- **权限控制**:基于角色的访问控制 (RBAC)。
|
||||
- **数据加密**:敏感数据落盘加密存储。
|
||||
- **审计日志**:关键操作的全链路审计记录。
|
||||
|
||||
## 📚 文档资源
|
||||
|
||||
更多详细指南请参阅以下文档:
|
||||
|
||||
- [SECURITY_README.md](./SECURITY_README.md) - 安全功能使用指南(认证、加密、审计)
|
||||
- [DEPLOYMENT.md](./DEPLOYMENT.md) - 部署与集成指南
|
||||
- [INTEGRATION_CHECKLIST.md](./INTEGRATION_CHECKLIST.md) - 系统集成检查清单
|
||||
|
||||
## 🏗️ 目录结构
|
||||
|
||||
```
|
||||
TJWaterServerBinary/
|
||||
├── app/
|
||||
│ ├── main.py # FastAPI 应用入口(Lifespan, Middleware)
|
||||
│ ├── api/v1/ # API 接口路由与端点定义
|
||||
│ ├── algorithms/ # 核心算法模块(模拟、清洗、泄漏识别等)
|
||||
│ ├── auth/ # 认证相关逻辑与依赖
|
||||
│ ├── core/ # 核心配置、安全与工具类
|
||||
│ ├── domain/ # 领域模型与 Schema 定义
|
||||
│ ├── infra/ # 基础设施层
|
||||
│ │ ├── audit/ # 审计日志模块
|
||||
│ │ ├── cache/ # 缓存与 Redis 客户端
|
||||
│ │ └── db/ # 数据库访问层 (PostgreSQL/TimescaleDB/InfluxDB)
|
||||
│ ├── services/ # 业务逻辑服务层
|
||||
│ └── utils/ # 通用工具函数
|
||||
├── resource/ # 静态资源与模型文件
|
||||
├── scripts/ # 运维与启动脚本
|
||||
├── tests/ # 单元与集成测试
|
||||
├── requirements.txt # Python 依赖列表
|
||||
└── readme.md # 项目说明文档
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 环境要求
|
||||
|
||||
- Python 3.10+
|
||||
- PostgreSQL (TimescaleDB 扩展)
|
||||
- Redis
|
||||
- InfluxDB (可选,用于时序数据)
|
||||
|
||||
### 2. 安装依赖
|
||||
|
||||
建议使用虚拟环境进行安装:
|
||||
|
||||
```bash
|
||||
# 创建虚拟环境
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Linux/macOS
|
||||
# venv\Scripts\activate # Windows
|
||||
|
||||
# 安装依赖
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 3. 配置环境
|
||||
|
||||
请确保正确配置了环境变量或 `.env` 文件,主要包括数据库连接串、Redis 配置及密钥等。参考 `app/core/config.py` 中的配置项。
|
||||
|
||||
### 4. 启动服务
|
||||
|
||||
使用提供的启动脚本运行服务:
|
||||
|
||||
```bash
|
||||
python scripts/run_server.py
|
||||
```
|
||||
|
||||
- **默认地址**: `http://0.0.0.0:8000`
|
||||
- **API 文档**: `http://0.0.0.0:8000/docs` 或 `http://0.0.0.0:8000/redoc`
|
||||
- **OpenAPI**: `http://0.0.0.0:8000/openapi.json`
|
||||
|
||||
## 🛠️ 常用脚本
|
||||
|
||||
- `scripts/run_server.py`: 启动 FastAPI 服务
|
||||
- `scripts/create_project.py`: 创建新项目环境
|
||||
- `scripts/setup_security.sh`: 初始化安全配置
|
||||
|
||||
## 📝 开发规范
|
||||
|
||||
- 代码遵循 PEP 8 规范
|
||||
- 提交代码前请运行测试:`pytest`
|
||||
@@ -1,14 +0,0 @@
|
||||
Setup instructions for WMH's work
|
||||
|
||||
1. import scada_info.csv
|
||||
run python online_Analysis.py
|
||||
|
||||
2. import history_pattern_flow.csv
|
||||
run python online_Analysis.py
|
||||
Should manually change code
|
||||
|
||||
3. run create_template.py
|
||||
|
||||
4. run influxdb_api.py
|
||||
在InfluxDB数据库中创建好我们需要的bucket
|
||||
create buckets
|
||||
@@ -1,90 +0,0 @@
|
||||
搭建服务器
|
||||
|
||||
1. `git clone https://e.coding.net/tjwater/tjwatercloud/TJWaterServer.git`
|
||||
2. 控制台进入 `TJWaterServer`
|
||||
3. 运行 `python install.py` 准备Python环境
|
||||
3.1 Python 3.12 需要手动的安装(拷贝) PyMetis 库
|
||||
4. 解压 `pg14.zip` 到上一层文件夹
|
||||
5. 控制台进入 `../pg14/bin`
|
||||
5.1 将pg14/bin 加到系统PATH中,这步一定需要做,CopyProjectEx里需要这个
|
||||
6. 执行 `initdb -D ../data -E UTF-8` 创建数据库
|
||||
7. 执行 `pg_ctl -D ../data -l logfile start` 启动数据库服务
|
||||
- `pg_ctl -D ../data -l logfile stop` 关闭数据库服务
|
||||
8. 进入 `TJWaterServer`,执行 `python create_template.py` 创建模板
|
||||
9. 执行 `python online_Analysis.py`
|
||||
10. 执行 `python influxdb_api.py`
|
||||
11. 搭建FastAPI环境...
|
||||
12. 进入 `TJWaterServer`,执行 `startserber.bat`
|
||||
|
||||
NOTE:
|
||||
版本问题
|
||||
pip uninstall scipy numpy -y
|
||||
pip install numpy==1.26.2 scipy==1.15.2
|
||||
|
||||
pg 信息
|
||||
腾讯Windows服务器
|
||||
Host: localhost (默认)
|
||||
Port: 5432 (默认)
|
||||
User: 就是Windows的用户名,这台机器也就是 Administrator
|
||||
Password: 密码为空
|
||||
|
||||
redis 信息
|
||||
|
||||
1. 进到redis安装目录
|
||||
2. 执行 redis-server.exe
|
||||
|
||||
|
||||
|
||||
influx db 信息
|
||||
1. 运行 influxd.exe
|
||||
2. 打开网页看下列的信息 http://localhost:8086
|
||||
|
||||
# influxdb数据库连接信息
|
||||
influx_url = "http://localhost:8086" # 替换为你的InfluxDB实例地址
|
||||
influx_token = "Vq8F5tzxqmjH6JYPBP5xqwo6nJbzRqCnahlcoMVyZGMPm3H92swD08VX-5lTH1laN_JG1x7EZ80WOQoycanmBw==" # 替换为你的InfluxDB Token
|
||||
influx_org_name = "TJWATERORG" # 替换为你的Organization名称
|
||||
influx_client = InfluxDBClient(url=influx_url, token=influx_token, org=influx_org_name)
|
||||
|
||||
|
||||
UserName tjwater
|
||||
Password Tjwater@123456
|
||||
Organizatio TJWATEORG
|
||||
Bucket TJWATERBUCKET
|
||||
|
||||
API Token : LsqvuqtBqtBv44z_CWh5bWfn9hs1QKcYu5kWahF_cdF6JyqtwuUxU5CK7HWP7BOtP5_2f5mjx76qXyuPLOHWdw==
|
||||
|
||||
influx config create --config-name onboarding `
|
||||
--host-url "http://localhost:8086" `
|
||||
--org "TJWATERORG" `
|
||||
--token "LsqvuqtBqtBv44z_CWh5bWfn9hs1QKcYu5kWahF_cdF6JyqtwuUxU5CK7HWP7BOtP5_2f5mjx76qXyuPLOHWdw=="
|
||||
--active
|
||||
|
||||
|
||||
Setup instructions for WMH's work
|
||||
|
||||
1. import scada_info.csv
|
||||
run python online_Analysis.py
|
||||
|
||||
2. import history_pattern_flow.csv
|
||||
run python online_Analysis.py
|
||||
Should manually change code
|
||||
|
||||
3. run create_template.py
|
||||
|
||||
4. run influxdb_api.py
|
||||
在InfluxDB数据库中创建好我们需要的bucket
|
||||
create buckets
|
||||
|
||||
5. run online_Analysis.py
|
||||
有几个步骤
|
||||
(1)创建用户名密码
|
||||
(2)network_update 从 inp 文件创建 szh这个project
|
||||
(3)upload_shp_to_pg
|
||||
(4)submit_risk_probability_result
|
||||
(5)pressure_sensor_placement_sensitivity
|
||||
|
||||
6. In times table, all time values should be the format "hh:mm::ss"
|
||||
|
||||
NOTES:
|
||||
1. SCADA设备的时候,单位要转换,现在模拟算出来的单位是L/s,SCADA数据是m3/h,L/s要乘3.6才是m3/h
|
||||
2. 之前的SCADA压力应该转过了,SCADA数据的单位是MPa,要乘以100才是m
|
||||
Reference in New Issue
Block a user