# 权限、错误与限制

> scope 一览表、带稳定错误码的错误格式（RFC 9457）、速率限制。

URL: https://developers.vimine.network/zh-hans/guides/scopes-and-errors/

## 权限（scope）

客户端在登记时申请权限；会员在授权同意页面上看到这些权限。

| Scope | 对象 | 内容 |
|---|---|---|
| `profile:read` | 会员 | `GET /v1/me`——姓名、电子邮箱、联系方式、出生信息、税号（如有），以及当事人的身份识别方式（`codicefiscale_check`） |
| `profile:write` | 会员 | `PATCH /v1/me`——电话、性别，以及身份识别信息：出生日期、出生地和出生国、税号（可选，可以之后再补充；会重新校验） |
| `membership:read` | 会员 | `GET /v1/me/membership`、`/events`、`/statuto`、`/card` |
| `membership:request` | 会员 | `POST /v1/me/membership`——入会申请 |
| `statuto:accept` | 会员 | `POST /v1/me/membership/statuto/accept` |
| `network:manage` | 会员 | 会员对加入网络的同意（即将推出） |
| `memberships:read` | 客户端 | `GET /v1/memberships/{id}/status` |
| `verify:read` | 客户端 | 超出匿名配额的会员卡核验 |
| `identity:signup` | 客户端 | `POST /v1/signup`——代表会员创建账户（[服务器集成](https://developers.vimine.network/zh-hans/guides/server/#从您的系统为会员办理入会)） |
| `enroll:write` | 客户端 | `POST /v1/enroll`——提交入会申请，有无税号均可（[指南](https://developers.vimine.network/zh-hans/guides/members-without-cf/)） |
| `events:read` | 会员 | `GET /v1/events`、`/v1/events/{slug}`、`/eligibility`——包括仅限会员的活动（[指南](https://developers.vimine.network/zh-hans/guides/events/)） |
| `registrations:read` | 会员、客户端 | `GET /v1/me/registrations`（会员）；`GET /v1/events/{slug}/registrations`（客户端，不含个人数据） |
| `registrations:write` | 会员、客户端 | `POST /v1/events/{slug}/registrations` 和 `DELETE /v1/me/registrations/{id}`（会员）；`POST …/registrations/guest`（客户端） |
| `checkins:write` | 客户端 | `POST /v1/checkins`——凭会员卡或报名办理入场登记 |
| `webhooks:manage` | 客户端 | 即将推出 |

公开客户端或原生客户端只能申请会员权限；“客户端”权限需要机密客户端。尚未入会的人只能授予入会相关的权限（`profile:*`、`membership:read`、`membership:request`、`statuto:accept`）。

## 错误

错误响应为 `application/problem+json`（RFC 9457）：

```json
{
  "type": "https://developers.vimine.network/errors/insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Missing scope: profile:write",
  "request_id": "…"
}
```

`code` 是稳定的：请以它作为分支依据。`errors[]` 随 `validation_failed` 和 `identification_required` 一起返回（`{ field, code }`）。`codicefiscale_mismatch` 记录——税号与当事人的出生信息不一致——还带有 `mismatches`、`hints` 和 `confirmable`：当 `confirmable` 为 `true` 时，当事人可以确认该税号，并带上 `codicefiscale_confirmed: true` 重复请求（参见[没有意大利税号的会员](https://developers.vimine.network/zh-hans/guides/members-without-cf/#不一致的税号与确认)）。OAuth 端点（`/v1/oauth/token`、`/revoke`）以 OAuth 格式返回（`{ error, error_description }`）。

| `code` | 含义 |
|---|---|
| `missing_token`、`invalid_token`、`token_expired` | 401——请重新登录（SDK 会自动刷新并重试） |
| `insufficient_scope` | 403——令牌缺少该权限 |
| `api_disabled` | 403——协会未开通 API，或不接受申请 |
| `plan_limit` | 403——协会的套餐已容纳不下更多会员（显示表单前请先检查 `aps.accepting_requests`） |
| `not_available` | 403——协会目前不接受申请：尚未接受平台协议或尚未登记章程、尚未准备就绪，或只接纳受邀请的人（[内测](#内测)）；`detail` 会说明是哪种情况。在 `POST /v1/signup` 上：内测期间账户只能凭邀请创建 |
| `not_found` | 404——其他协会的资源也返回此错误 |
| `validation_failed` | 422——参见 `errors[]`（`required`、`invalid`、`invalid_codicefiscale`、带 `confirmable` 的 `codicefiscale_mismatch`…） |
| `identification_required` | 在 `POST /v1/me/membership` 上为 422，在 `POST /v1/enroll/confirm` 上为 409——当事人尚未识别身份：需要税号，或出生日期、出生地和出生国；`errors[]` 列出缺少的内容 |
| `statuto_outdated`、`statuto_required` | 422——指明现行章程的版本（`detail`） |
| `rate_limited` | 429——请等待 `Retry-After` |
| `unavailable` | 503——请稍后重试 |

OAuth：`invalid_grant`（授权码或刷新令牌无效、已过期或被重复使用）、`invalid_client`、`invalid_scope`、`unauthorized_client`（客户端等待开通）、`access_denied`（会员已取消）。

在 SDK 中，以上所有错误都是带有相同 `code` 的 [`VimineError`](https://developers.vimine.network/zh-hans/sdk/errors/)。

## 内测

Vimine 正处于内测阶段：个人和协会都**凭邀请**加入。对客户端而言，这意味着：

- `POST /v1/signup` 返回 `403 not_available`，不创建任何内容，除非 Vimine 已为您的协会开放公开入会；
- 只接纳受邀请者的协会，其公开资料中带有 `aps.invitation_only: true` 和 `aps.accepting_requests: false`（[`association(slug)`](https://developers.vimine.network/zh-hans/sdk/public/)）；`POST /v1/enroll` 和 `POST /v1/me/membership` 返回 `403 not_available`。受到邀请的人通过邮件中收到的链接入会；
- [沙盒](https://developers.vimine.network/zh-hans/guides/sandbox/)保持开放：测试客户端照常工作。

显示入会表单之前，请先检查 `aps.accepting_requests`——内测期间如此，其他情况也一样；`<vimine-events>` 和 `<vimine-enroll>` 已经这样做了。

## 限制

- 按 IP 地址计：敏感端点（会员卡核验、税号、令牌）每分钟 60 次请求，其余端点每分钟 120 次；响应中带有 `RateLimit-*` 和 `Retry-After`。
- `POST /v1/me/membership` 接受 `Idempotency-Key`：24 小时内使用相同的键会返回相同的响应（SDK 会为每次调用生成一个）。
- 经过认证的响应为 `Cache-Control: no-store`。
- 每个响应都带有 `request_id`：报告问题时请注明它。
