# Fami VIP 设置接口对接文档

## 1. 接口范围

本文档只描述 Fami VIP 设置相关接口、请求参数和返回字段。

## 2. 设置字段

| VIP 等级 | 设置项 | `benefit_code` | 接口字段 | 无记录默认值 |
| --- | --- | --- | --- | --- |
| VIP6 | 隐藏个人数据 | `hide_profile_data` | `hide_profile_data_enabled` | `false` |
| VIP6 | 榜单隐身 | `leaderboard_invisible` | `leaderboard_invisible_enabled` | `false` |
| VIP7 | 匿名访问主页 | `anonymous_profile_visit` | `anonymous_profile_visit_enabled` | `false` |
| VIP8 | 进房全服通知 | `room_entry_notice` | `room_entry_notice_enabled` | `true` |
| VIP9 | 上线全服通知 | `online_global_notice` | `online_global_notice_enabled` | `true` |

`updated_at_ms = 0` 表示用户尚未修改，当前返回的是默认值。

## 3. 公共请求约定

### 3.1 请求头

```http
Authorization: Bearer {access_token}
X-App-Code: fami
Content-Type: application/json
```

### 3.2 统一响应结构

```json
{
  "code": "OK",
  "message": "OK",
  "data": {},
  "request_id": "req_xxx"
}
```

接口成功条件为 `code == "OK"`。

## 4. 查询当前用户设置

### 4.1 请求

```http
GET /api/v1/vip/settings
```

请求体：无。

### 4.2 成功响应

```json
{
  "code": "OK",
  "message": "OK",
  "data": {
    "settings": {
      "app_code": "fami",
      "user_id": 10001,
      "room_entry_notice_enabled": true,
      "online_global_notice_enabled": true,
      "hide_profile_data_enabled": false,
      "anonymous_profile_visit_enabled": false,
      "leaderboard_invisible_enabled": false,
      "updated_at_ms": 0
    },
    "evaluated_at_ms": 1784563200000
  },
  "request_id": "req_vip_settings_get"
}
```

## 5. 修改当前用户设置

### 5.1 请求

```http
PATCH /api/v1/vip/settings
```

请求体支持以下可选字段：

```json
{
  "room_entry_notice_enabled": true,
  "online_global_notice_enabled": true,
  "hide_profile_data_enabled": false,
  "anonymous_profile_visit_enabled": false,
  "leaderboard_invisible_enabled": false
}
```

PATCH 规则：

- 每次请求至少传一个设置字段。
- 未传字段保持原值。
- 显式传 `false` 表示关闭该设置。
- 不支持修改其他用户的设置。

单字段请求示例：

```json
{
  "hide_profile_data_enabled": true
}
```

### 5.2 成功响应

修改成功后返回完整设置对象：

```json
{
  "code": "OK",
  "message": "OK",
  "data": {
    "settings": {
      "app_code": "fami",
      "user_id": 10001,
      "room_entry_notice_enabled": true,
      "online_global_notice_enabled": true,
      "hide_profile_data_enabled": true,
      "anonymous_profile_visit_enabled": false,
      "leaderboard_invisible_enabled": false,
      "updated_at_ms": 1784563200123
    },
    "server_time_ms": 1784563200150
  },
  "request_id": "req_vip_settings_patch"
}
```

## 6. VIP 用户信息接口返回设置

### 6.1 请求

```http
GET /api/v1/vip/me
```

设置字段路径：

```text
data.state.user_settings
```

精简响应示例：

```json
{
  "code": "OK",
  "data": {
    "state": {
      "effective_vip": {
        "level": 8,
        "name": "VIP8",
        "active": true
      },
      "effective_benefits": [
        {
          "benefit_code": "room_entry_notice",
          "status": "active"
        }
      ],
      "user_settings": {
        "app_code": "fami",
        "user_id": 10001,
        "room_entry_notice_enabled": true,
        "online_global_notice_enabled": true,
        "hide_profile_data_enabled": false,
        "anonymous_profile_visit_enabled": false,
        "leaderboard_invisible_enabled": false,
        "updated_at_ms": 0
      }
    }
  },
  "request_id": "req_vip_me"
}
```

真实响应还包含 `paid_vip`、`equipped_trial_card`、`effective_source`、`evaluated_at_ms` 和 `program_config` 等字段。

## 7. 当前用户聚合信息返回设置

### 7.1 请求

```http
GET /api/v1/users/me/overview
```

设置字段路径：

```text
data.vip.user_settings
```

精简响应示例：

```json
{
  "code": "OK",
  "data": {
    "profile": {
      "user_id": "10001",
      "username": "Nina"
    },
    "vip": {
      "level": 8,
      "name": "VIP8",
      "active": true,
      "started_at_ms": 1780000000000,
      "expires_at_ms": 1782592000000,
      "user_settings": {
        "app_code": "fami",
        "user_id": 10001,
        "room_entry_notice_enabled": true,
        "online_global_notice_enabled": true,
        "hide_profile_data_enabled": false,
        "anonymous_profile_visit_enabled": false,
        "leaderboard_invisible_enabled": false,
        "updated_at_ms": 0
      }
    }
  },
  "request_id": "req_user_overview"
}
```

补充约定：

- `data.vip.unavailable == true` 表示本次 VIP 上游查询降级。
- 他人公开资料接口 `GET /api/v1/users/by-id/{user_id}/profile` 不返回 `user_settings`。

## 8. 错误响应

| HTTP 状态码 | `code` | 说明 |
| --- | --- | --- |
| 400 | `INVALID_ARGUMENT` | 请求体为空、字段名错误或字段类型错误。 |
| 401 | `UNAUTHORIZED` | Access Token 无效或已过期。 |
| 403 | `FORBIDDEN` | 无权跨 App 或修改其他用户设置。 |
| 502 | `UPSTREAM_ERROR` | VIP/Wallet 上游服务异常。 |

错误处理应以稳定的 `code` 为准，不依赖 `message` 文案。
