Helvetra/backend

GitHub: Helvetra/backend

基于 FastAPI 构建的隐私优先瑞士翻译 API,支持瑞士德语方言及多语种翻译,同时面向消费者和 B2B 提供分层服务与计量计费。

Stars: 2 | Forks: 0

# Helvetra Backend 为 [Helvetra](https://helvetra.ch)(一款隐私优先的瑞士翻译应用)提供支持的翻译 API。 该后端服务于两个层面: - **消费者 API** (`/api/v1/*`):供 Web 应用和 iOS 应用使用。 - **B2B 公共 API** (`/api/public/v1/*`):通过 API key 进行身份验证,按字符通过 Stripe 计量器进行计费,文档详见 [helvetra.ch/api/public/v1/docs](https://helvetra.ch/api/public/v1/docs)。 ## 功能 ### 翻译 - 由瑞士 AI 提供支持的翻译 API(通过 Infomaniak 使用 Apertus-70B) - 支持的语言:德语、法语、意大利语、英语、罗曼什语和瑞士德语(包含苏黎世、伯尔尼、巴塞尔、卢塞恩、圣加仑和瓦莱州方言) - 自动检测源语言 - 语体正式程度切换(du/Sie, tu/vous, tu/Lei) - 深度防御 Prompt 注入:使用分隔符包裹用户输入、system prompt 隔离、长度比例限制、尾部注释剥离(EN/DE/FR/IT) - 基于等级的单次请求和单周期字符限制 ### Auth - 邮箱 + 密码注册,结合 bcrypt 加密 + 常用密码拒绝机制 - 作用域限定于 `/api/v1/auth` 的 HttpOnly+Secure+SameSite=Strict refresh-token cookie - 通过 PyJWT 使用 HS256 签名的 access token(15 分钟有效期) - 每次执行 `/refresh` 时轮换 refresh-token - 在基于 cookie 认证且会更改状态的 endpoint 上提供 CSRF 保护(双重提交 cookie + `X-CSRF-Token` header) - 针对(邮箱,IP)的登录锁定,以防止针对账户锁定的 DoS 攻击 - 带有多语言模板(EN/DE/FR/IT)的邮箱验证 - Sign in with Apple(通过 PyJWT + Apple JWKS 使用 RS256) - Apple StoreKit 2 订阅验证 —— 目前已启用 kill-switch,等待针对 App Store Root CA 链的重写 ### 支付 - **Web(消费者)**:Stripe Checkout 用于包月/包年订阅 + Customer Portal 用于自助管理 - **Web(B2B)**:Stripe 计量计费,使用 lookup-key 解析价格,提供 14 天的 Starter 试用,在每次翻译时内联发送计量事件 - **iOS**:StoreKit 2(验证器重写待定 —— 见上文) ### 运维 - 在 Redis 中进行速率限制(基于 IP 的全局限制 + 基于 endpoint 的认证限制 + 基于(邮箱,IP)的锁定) - 通过原子 Redis Lua 脚本进行匿名使用情况追踪 - 当月度配额达到 80% 和 100% 时发送 B2B 用量警报邮件 - Stripe webhook 签名验证 + 幂等性去重(Apple webhook 也通过 `notificationUUID` 进行去重) - 针对 auth 事件(登录尝试、账户删除、触发速率限制)的审计日志 ## 技术栈 - **框架:** Python 3.11+ / FastAPI - **数据库:** PostgreSQL 15 + SQLAlchemy + Alembic - **缓存:** Redis 7 - **AI:** Apertus-70B(通过 Infomaniak AI) - **Auth:** PyJWT (HS256 + RS256) + Sign in with Apple + Apple StoreKit 2(受控状态) - **支付:** Stripe(Web,消费者 + B2B 计量)+ Apple StoreKit 2(iOS,受控状态) ## 设置 ``` # Clone and configure cp .env.example .env # Edit .env — at minimum set JWT_SECRET_KEY, ENCRYPTION_KEY, APERTUS_API_KEY, # DATABASE_URL, REDIS_URL. App refuses to boot in prod without secrets # meeting minimum length requirements. # Run with Docker (Postgres + Redis + backend) docker-compose up # Or run locally pip install -e ".[dev]" alembic upgrade head uvicorn app.main:app --reload # API: http://localhost:8000 # Consumer docs: http://localhost:8000/docs (debug-only) # B2B public docs: http://localhost:8000/api/public/v1/docs ``` ## API 层面 ### 消费者 API(JWT 或会话 cookie) | 方法 | 路径 | 描述 | |--------|------|-------------| | POST | `/api/v1/auth/register` | 创建账户 + 发送验证邮件 | | POST | `/api/v1/auth/login` | 邮箱/密码登录(cookie 或 body 中的 refresh token) | | POST | `/api/v1/auth/refresh` | 轮换 refresh token,生成新的 access token | | POST | `/api/v1/auth/logout` | 吊销 refresh token + 清除 cookie | | POST | `/api/v1/auth/verify-email` | 使用邮件链接中的 token 验证邮箱 | | POST | `/api/v1/auth/resend-verification` | 重新发送验证邮件(受速率限制) | | POST | `/api/v1/auth/apple` | Sign in with Apple(identity-token 交换) | | GET | `/api/v1/auth/me` | 当前已认证的用户 | | DELETE | `/api/v1/auth/account` | 删除账户 + 取消活跃订阅 | | POST | `/api/v1/translate` | 翻译文本(匿名或已认证) | | POST | `/api/v1/feedback` | 提交翻译反馈(按 IP 进行速率限制) | | GET | `/api/v1/languages` | 列出支持的语言和方言 | | GET | `/api/v1/subscription` | 消费者订阅状态 | | GET | `/api/v1/subscription/b2b` | B2B 订阅状态 | | GET | `/api/v1/subscription/b2b/usage-history` | 过去 12 个月的使用周期记录 | | GET | `/api/v1/subscription/limits` | 当前用户的等级限制 | | GET | `/api/v1/subscription/anonymous-usage` | 每周匿名使用状态 | | POST | `/api/v1/payments/create-gateway` | 启动消费者 Stripe checkout | | POST | `/api/v1/payments/create-b2b-gateway` | 启动 B2B Stripe checkout | | POST | `/api/v1/payments/b2b-portal` | 打开 Stripe Customer Portal 会话 | | POST | `/api/v1/api-keys` | 创建 B2B API key(仅提供一次明文复制) | | GET | `/api/v1/api-keys` | 列出调用者的 API key | | POST | `/api/v1/api-keys/{id}/rotate` | 轮换 API key(仅返回一次新明文) | | DELETE | `/api/v1/api-keys/{id}` | 吊销 API key | | POST | `/api/v1/webhooks/stripe` | Stripe webhook 接收器 | | POST | `/api/v1/webhooks/apple` | Apple App Store Server Notifications v2 接收器 | | GET | `/api/health` | 健康检查 | ### B2B 公共 API(API key) | 方法 | 路径 | 描述 | |--------|------|-------------| | POST | `/api/public/v1/translate` | 翻译文本(`X-API-Key` 认证,通过 Stripe 计量器计费) | | GET | `/api/public/v1/languages` | 列出支持的语言 | | GET | `/api/public/v1/usage` | 当前周期的使用情况 | | GET | `/api/public/v1/docs` | Swagger UI | | GET | `/api/public/v1/redoc` | ReDoc | | GET | `/api/public/v1/openapi.json` | OpenAPI schema(已筛选为公共路由) | ## 支持的语言 | 代码 | 语言 | |------|----------| | de | 德语 | | gsw | 瑞士德语(包含地区方言) | | fr | 法语 | | it | 意大利语 | | en | 英语 | | rm | 罗曼什语 | ## 项目结构 ``` app/ ├── main.py # Application entry point + startup secret validation ├── config.py # Environment configuration (Pydantic Settings) ├── api/ │ ├── routes/ # FastAPI route handlers │ ├── public_docs.py # Filtered OpenAPI schema for the B2B API │ └── dependencies.py # Auth dependencies, get_client_ip, etc. ├── schemas/ # Pydantic request/response models ├── services/ # Business logic (auth, csrf, translation, stripe, …) ├── models/ # SQLAlchemy models ├── core/ │ ├── database.py # Async engine + session │ ├── middleware.py # IP rate-limit middleware │ └── tiers.py # Tier definitions (consumer + B2B) └── data/ # Static data (common-passwords list) alembic/ # Database migrations tests/ # pytest suite ``` ## 许可证 MIT
标签:AI翻译, Apple登录, AV绕过, Docker, FastAPI, Stripe支付, 后端开发, 安全防御评估, 搜索引擎查询, 测试用例, 翻译API, 请求拦截, 逆向工具