# 0018 - Feature management

{% hint style="info" %}
对应的[官方页面地址](https://contributing.bitwarden.com/architecture/adr/feature-management)
{% endhint %}

| ID：  | ADR-0018   |
| ---- | ---------- |
| 状态：  | 完成         |
| 发表于： | 2023-02-01 |

## 背景和问题陈述​ <a href="#context-and-problem-statement" id="context-and-problem-statement"></a>

新功能不断被添加到平台中，同时也面临着更频繁地部署、减少孤立开发的压力。质量保证团队希望保持产品的质量，运营团队也希望保持可靠性和性能。功能通常可以在一段时间内以小块并行的方式交付，并且需要通过限制向特定受众发布和支持实验来控制其对系统的影响。

## 考虑的方案​ <a href="#considered-options" id="considered-options"></a>

* **直接添加/更改功能** -- 通过 SDLC 和代码审查进行更改，并在获得批准后合并到主线发布分支中。在开发其他功能的同时，根据需要解决问题和进行热修复。
* **在内部实现功能管理系统** -- 在代码中利用框架，并在我们自己的存储中存储功能标志和其他组件，以专有方式流式传输它们的更新，如果有的话（例如，仅在应用程序启动时加载配置）。
* **采用具有本地回退功能的功能管理系统** -- 实施服务提供商提供的功能，以获得更强大的功能管理能力，如实时流和用户/上下文定位。为希望测试或采用尚未完全支持的功能的自托管安装支持本地配置。

## 决策结果​ <a href="#decision-outcome" id="decision-outcome"></a>

选择的方案：**采用具有本地回退功能的功能管理系统**。

### 积极的后果​ <a href="#positive-consequences" id="positive-consequences"></a>

* 针对标记及其变体的强大功能集。
* 防止更改和有针对性的影响，同时加快整体交付速度（假设托管功能处于「off」状态）。
* 功能的上下文相关应用。
* 记录和追踪谁可以体验或试验某项功能。

### 消极的后果​ <a href="#negative-consequences" id="negative-consequences"></a>

* 选择服务提供商的成本。

### 计划​ <a href="#plan" id="plan"></a>

[服务器](https://github.com/bitwarden/server)代码库将为提供功能管理的服务提供商采用 .NET SDK。只有服务器端 SDK 将用于管理访问和成本，并且功能状态将在适当的情况下通过 API 响应元素传达给调用客户端。新功能将在服务提供商的平台内设置，对它们的更改将流式传输到运行中的应用程序。对提供商的访问将由内部控制。

为方便客户端在其他配置中使用功能状态，API 将进行扩展以提供配置值的集合。其中一些值已经被持久维护，并将与功能键混合在一起。客户端将在启动、登录、本地配置更新以及同步事件发生时刷新配置。

将使用受支持的客户端建立与 API 通信的上下文。服务提供商可根据需要将上述上下文用于特定目标。将为用户、组织和服务账户建立上下文，实体的唯一 ID 将作为关键字，并根据需要提供其他详细信息。必要时，上下文属性可标记为私有，以避免溢出到服务提供商，如果需要使用 PII，服务提供商将被添加到[子处理器列表](https://help.ppgg.in/security/who-are-bitwardens-subprocessors)中，并进行相应的通信。

编译时配置将尽可能转换为使用功能管理服务提供商。SDK 对服务提供商的访问将按环境进行划分；某些功能可能永远不会在所有环境中使用。

新功能的状态将默认是「off」状态。非布尔值的变化将允许自定义。在默认状态配置下，可通过服务提供商对功能状态进行离线访问（这也意味着在安装之外无需连接）。本地文件可以为自托管安装的功能加载选择项，这些安装将默认为离线模式。

软件开发生命周期将得到加强，以明确所有功能开发都应使用标志保护。

将考虑支持在代码库中使用 [OpenFeature](https://docs.openfeature.dev/docs/reference/intro/) 兼容接口。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.ppgg.in/architecture/adr/0018-feature-management.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
