跳至主要内容

Reference Data 設計指南

文檔版本: v1.3.0 最後更新: 2026-08-17 適用對象: 開發團隊、AI Agent、使用 app-tenant-server 範本的團隊

本文檔說明 Reference Data(參考資料)的設計原則與實作方式,確保團隊遵循一致的模式。

實作依 capability/Feature/reference implementation 分層:

  • Feature 僅保留中性的 ReferenceDataProviderReferenceDataRecordReferenceDataItem 契約,不認識 entity、repository 或 URL。
  • controller/referencedataentity/referencedatarepository/referencedatasecurity/referencedataservice/referencedata 是可重塑的附屬 reference domain。
  • app-tenant-server 作者化 tenant-scoped reference data;app-tenantless-server 作者化 application-scoped reference data。兩者可保持相同 Feature 名稱與操作介面, 但內容與演進彼此獨立。

目錄

  1. 概述
  2. Enum vs Entity vs CodeData 選擇策略
  3. 基礎類別
  4. 統一 API 設計
  5. 新增 Reference Data 類型
  6. 命名慣例
  7. 檢查清單
  8. 現有實作參考
  9. 常見問題 (FAQ)

1. 概述

什麼是 Reference Data?

Reference Data 是系統中相對穩定、用於分類或標準化的資料,通常作為下拉選單選項或業務規則的依據。

Master Data vs Reference Data

特性Master DataReference Data
變動頻率中等(業務成長時增加)低(很少變動)
維護者業務人員開發團隊或系統管理員
範例客戶、產品、供應商幣別、國家、狀態碼
資料量大(數千至數百萬筆)小(通常 < 100 筆)
業務邏輯可能有(如狀態機)

架構概覽

┌─────────────────────────────────────────────────────────────────────┐
│ ReferenceDataController │
│ /api/v1/references/* │
├─────────────────────────────────────────────────────────────────────┤
│ Enum 類型 │ Entity 類型 │ CodeData 類型 │
│ (程式碼定義) │ (有額外欄位) │ (通用代碼資料) │
│ ──────────── │ ──────────── │ ──────────── │
│ • Currency │ • Unit │ • payment-methods │
│ • Country │ → BaseReferenceData │ • delivery-time-slots │
│ • ProductStatus │ • ProductCategory │ • gift-wrapping-options│
│ • OrderStatus │ → TenantAware... │ • card-templates │
│ │ │ → 共用 CodeData Entity │
│ 唯讀 │ 有額外欄位 │ 只有基本欄位,支援 CRUD │
└─────────────────────────────────────────────────────────────────────┘

類型分類

類型說明可寫適用場景
Enum程式碼定義,可有邏輯判斷狀態機、國際標準代碼
Entity有額外欄位的獨立 Entity需要擴充欄位(如 Unit.symbol)
CodeData通用代碼資料,只有基本欄位簡單下拉選單(付款方式、配送時段)

2. Enum vs Entity vs CodeData 選擇策略

決策流程圖

需要新增 Reference Data 類型


┌──────────────┐
│ 程式碼中是否 │ ──是──▶ 使用 Enum
│ 需要判斷邏輯?│ (可帶額外屬性)
│ (if/switch) │
└──────┬───────┘
│否

┌──────────────┐
│ 是否有額外 │ ──是──▶ 使用 Entity
│ 欄位需要 │ (BaseReferenceData 或
│ 後台維護? │ TenantAwareReferenceData)
└──────┬───────┘
│否

┌──────────────┐
│ 是否需要在 │ ──是──▶ 使用 CodeData ★
│ 系統運行中 │ (只需在 CodeDataType 註冊)
│ 由業務人員 │
│ 新增/修改? │
└──────┬───────┘
│否

使用 Enum(簡單版)

選擇矩陣

情境推薦方式範例
國際標準代碼EnumCurrency (ISO 4217), Country (ISO 3166)
狀態機邏輯Enum + 方法OrderStatus(含 isTerminal, isActive)
有額外欄位、全域共用Entity (BaseReferenceData)Unit(計量單位,有 symbol)
有額外欄位、租戶隔離Entity (TenantAwareReferenceData)ProductCategory(可擴充欄位)
只需 code/name、全域CodeData(全域)payment-methods、payment-terms
只需 code/name、租戶隔離CodeData(多租戶)delivery-time-slots、card-templates
純顯示用途、不需邏輯Enum(簡單版)Gender(性別)

3. 基礎類別

3.1 BaseReferenceData(全域共用)

用途:所有租戶共用的 Reference Data

檔案位置entity/referencedata/BaseReferenceData.java

@MappedSuperclass
public abstract class BaseReferenceData extends AuditableBase {

@Id
@Column(length = 36)
@NotBlank
private String code; // 業務代碼(主鍵)

@Column(length = 100, nullable = false)
@NotBlank
private String name; // 顯示名稱

@Column(length = 500)
private String description; // 說明

@Column(name = "sort_order")
private Integer sortOrder = 0; // 排序(預設 0)

@Column(nullable = false)
private Boolean active = true; // 啟用狀態
}

特點

  • 使用 code 作為主鍵(業務有意義的代碼)
  • 適合:計量單位、支付方式等全域資料

3.2 TenantAwareReferenceData(多租戶隔離)

用途:各租戶獨立維護的 Reference Data

檔案位置entity/referencedata/TenantAwareReferenceData.java

@MappedSuperclass
public abstract class TenantAwareReferenceData
extends AuditableTenantEntity
implements ReferenceDataRecord {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
@JdbcTypeCode(SqlTypes.VARCHAR)
@Column(length = 36, nullable = false, updatable = false)
private UUID id; // UUID surrogate 主鍵

@Column(length = 36, nullable = false)
@NotBlank
private String code; // 業務代碼

@Column(length = 100, nullable = false)
@NotBlank
private String name; // 顯示名稱

@Column(length = 500)
private String description; // 說明

@Column(name = "sort_order")
private Integer sortOrder = 0; // 排序

@Column(nullable = false)
private Boolean active = true; // 啟用狀態

// tenantId 繼承自 TenantAwareEntity
}

特點

  • 使用 UUID id 作為主鍵
  • code 為業務識別碼,配合 tenantId 形成唯一約束
  • 適合:商品分類、自訂標籤等租戶專屬資料

必須設定的唯一約束

@Entity
@Table(name = "product_category",
uniqueConstraints = {
@UniqueConstraint(
name = "uk_product_category_tenant_code",
columnNames = {"tenant_id", "code"}
)
})
public class ProductCategory extends TenantAwareReferenceData {
// 繼承所有欄位,可擴充額外欄位
}

3.3 CodeData(通用代碼資料)

用途:不需要額外欄位的簡單 Reference Data,避免為每種類型建立獨立 Entity

檔案位置entity/referencedata/CodeData.java

@Entity
@Table(name = "code_data",
uniqueConstraints = {
@UniqueConstraint(
name = "uk_code_data_type_tenant_code",
columnNames = {"type", "tenant_id", "code"}
)
})
public class CodeData extends AuditableBase {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
@JdbcTypeCode(SqlTypes.VARCHAR)
@Column(length = 36, nullable = false, updatable = false)
private UUID id;

@Column(length = 50, nullable = false)
private String type; // 類型(如 "payment-methods")

@Column(name = "tenant_id", length = 36)
private String tenantId; // null = 全域,非 null = 租戶專屬

@Column(length = 36, nullable = false)
private String code; // 業務代碼

@Column(length = 100, nullable = false)
private String name; // 顯示名稱

@Column(length = 500)
private String description; // 說明

@Column(name = "sort_order")
private Integer sortOrder = 0; // 排序

@Column(nullable = false)
private Boolean active = true; // 啟用狀態
}

特點

  • 使用 type 欄位區分不同類型的代碼資料
  • tenantId 為 null 表示全域類型,非 null 表示租戶專屬
  • 所有簡單類型共用同一張表,無需為每種類型建立 Entity
  • 透過 CodeDataType Enum 定義可用的類型

CodeDataType 定義

// service/referencedata/CodeDataType.java
public enum CodeDataType {
// 全域類型
PAYMENT_METHODS("payment-methods", "付款方式", false),
PAYMENT_TERMS("payment-terms", "付款條件", false),

// 多租戶類型
DELIVERY_TIME_SLOTS("delivery-time-slots", "配送時段", true),
GIFT_WRAPPING_OPTIONS("gift-wrapping-options", "禮品包裝", true),
CARD_TEMPLATES("card-templates", "卡片範本", true),
ORDER_SOURCES("order-sources", "訂單來源", true);

private final String code;
private final String label;
private final boolean tenantAware; // true = 多租戶隔離
}

何時使用 CodeData

  • 只需要 code + name(+ description)的簡單下拉選單
  • 不需要在程式碼中判斷邏輯(不需要 if/switch)
  • 可能需要業務人員在系統運行中新增/修改

3.4 enum 的 wire 值與字典 code

enum 的 wire 值(出現在 API payload 的字串)由全域 mapper 設定決定,不逐個標 @JsonValue;字典的 code 由同一規則導出,兩者同源。宣告慣例、集中註冊點與機械閘門見 server 模組的 .claude/rules/26-enum-conventions.md

表述值(例)由誰決定
Java 常數名PENDING_CONFIRMATIONenum 宣告
wire 值 / 字典 codepending_confirmationLowercaseEnumJsonMapperCustomizer
顯示名稱待確認getLabel() 或 NLS(見 ADR-015)
DB 欄位值PENDING_CONFIRMATION@Enumerated(STRING)

外部標準代碼(ISO 4217 幣別、ISO 3166 國別)須維持大寫,屬明列例外。


4. 統一 API 設計

4.1 ReferenceDataController

檔案位置controller/referencedata/ReferenceDataController.java

提供統一的 API 端點,前端可一次取得多種 Reference Data:

查詢端點(所有類型)

端點說明回應
GET /api/v1/references/types取得所有可用類型["currencies", "countries", ...]
GET /api/v1/references/{type}取得單一類型列表[{code, name, ...}, ...]
GET /api/v1/references/{type}/{code}取得單一項目{code, name, ...}
GET /api/v1/references?types=a,b,c批次取得多種類型{a: [...], b: [...], c: [...]}

CodeData CRUD 端點(僅 CodeData 類型)

端點說明權限
POST /api/v1/references/{type}新增 CodeData 項目REFERENCE_DATA_W
PUT /api/v1/references/{type}/{code}更新 CodeData 項目REFERENCE_DATA_W
DELETE /api/v1/references/{type}/{code}刪除 CodeData 項目REFERENCE_DATA_D

注意:Enum 和 Entity 類型不支援 CRUD,嘗試寫入會回傳 500 錯誤。

4.2 統一回應格式(ReferenceDataItem)

檔案位置dto/ReferenceDataItem.java

所有 Reference Data 回傳統一格式:

@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ReferenceDataItem {
private String code; // 必填:業務代碼
private String name; // 必填:顯示名稱
private String description; // 選填:說明
private Integer sortOrder; // 選填:排序
private Map<String, Object> extra; // 選填:額外屬性
}

回應範例

{
"code": "TWD",
"name": "新台幣",
"extra": {
"symbol": "NT$",
"decimalPlaces": 0
}
}

4.3 前端使用範例

// 應用程式初始化時,一次取得所有需要的 Reference Data
const response = await api.get('/api/v1/references', {
params: { types: 'currencies,countries,units,product-categories' }
});

// 存入 store 供下拉選單使用
store.setReferenceData(response.data);

// 使用時
<Select options={store.currencies.map(c => ({ value: c.code, label: c.name }))} />

5. 新增 Reference Data 類型

5.1 新增 Enum 類型

步驟

  1. 建立 Enum 類別
// entity/sales/PaymentMethod.java
public enum PaymentMethod {
CASH("現金"),
CREDIT_CARD("信用卡"),
BANK_TRANSFER("銀行轉帳"),
LINE_PAY("LINE Pay");

private final String label;

PaymentMethod(String label) {
this.label = label;
}

public String getLabel() {
return label;
}
}

只宣告推導不出來的東西(顯示文字)。不要手寫 code:

// ❌ 第一個參數是常數名的機械轉換,零資訊且可打錯
CASH("cash", "現金"),

CACH("cash", ...) 這類錯誤編譯照過、測試照過,前端拿到錯的值——沒有任何機制檢查那個 字串跟常數名對得上。

  1. 在業務領域的 config 註冊

code + 顯示名稱的字典不必各開一支 provider class,在該領域自己的 @Configuration 以一個 @Bean 註冊即可:

// service/sales/SalesReferenceDataConfig.java
@Configuration
public class SalesReferenceDataConfig {

@Bean
public ReferenceDataProvider paymentMethodReferenceData() {
return EnumReferenceDataProvider.of(
"payment-methods", PaymentMethod.values(), PaymentMethod::getLabel);
}
}

EnumReferenceDataProvider.of()code 由常數名導出小寫,與 enum 的 wire 值同源—— 前端拿 order.status 對照字典的 code 才對得上。

Controller 會透過 Spring 收集所有 ReferenceDataProvider,不需要修改中央 registry。 type() 必須在所有 Provider 間唯一,且顯式宣告、不由 class 名推導——type() 即 URL 路徑片段,是 wire 契約;class 名是內部命名。推導會讓 rename enum 變成無聲的端點改名。

  1. 何時仍要寫專屬 provider

extra、狀態機或需要 repository 查詢時,內容是業務知識而非樣板,仍寫自己的 class:

@Component
public class OrderStatusReferenceDataProvider implements ReferenceDataProvider {

@Override
public String type() {
return "order-statuses";
}

@Override
public List<ReferenceDataItem> items() {
// 曝露 extra.allowedNextStatuses(狀態機的允許流轉)、isTerminal、isActive
...
}
}

config 放在業務領域套件內(如 service/sales/),不放 service/referencedata/: 該領域被 prune 時,它貢獻的字典一起消失。

5.2 新增 Entity 類型(全域)

步驟

  1. 建立 Entity 類別
// entity/referencedata/PaymentTerm.java
@Entity
@Table(name = "payment_term")
public class PaymentTerm extends BaseReferenceData {

@Column(name = "days_until_due")
private Integer daysUntilDue; // 額外欄位:到期天數
}
  1. 建立 Repository
// repository/referencedata/PaymentTermRepository.java
@Repository
@RequiredArgsConstructor
public class PaymentTermRepository {

private final EntityManager entityManager;

public List<PaymentTerm> findAllActive() {
return entityManager.createQuery("""
SELECT p FROM PaymentTerm p
WHERE p.active = true
ORDER BY p.sortOrder, p.name
""", PaymentTerm.class)
.getResultList();
}
}
  1. 建立 Provider
@Component
@RequiredArgsConstructor
public class PaymentTermReferenceDataProvider
implements ReferenceDataProvider {

private final PaymentTermRepository paymentTermRepository;

@Override
public String type() {
return "payment-terms";
}

@Override
public List<ReferenceDataItem> items() {
return paymentTermRepository.findAllActive().stream()
.map(item -> ReferenceDataItem.from(item, Map.of(
"daysUntilDue", item.getDaysUntilDue())))
.toList();
}
}
  1. 建立初始資料(選填)
// src/main/resources/data/PaymentTerm.json
[
{
"code": "IMMEDIATE",
"name": "即期付款",
"daysUntilDue": 0,
"sortOrder": 1,
"active": true
},
{
"code": "NET30",
"name": "月結 30 天",
"daysUntilDue": 30,
"sortOrder": 2,
"active": true
}
]

5.3 新增 Entity 類型(多租戶)

步驟

  1. 建立 Entity 類別
// entity/sales/ProductTag.java
@Entity
@Table(name = "product_tag",
uniqueConstraints = {
@UniqueConstraint(
name = "uk_product_tag_tenant_code",
columnNames = {"tenant_id", "code"}
)
})
public class ProductTag extends TenantAwareReferenceData {

@Column(length = 7)
private String color; // 額外欄位:標籤顏色(如 #FF5733)
}
  1. 建立 Repository
// repository/sales/ProductTagRepository.java
@Repository
@RequiredArgsConstructor
public class ProductTagRepository {

private final EntityManager entityManager;

public List<ProductTag> findAllActive() {
return entityManager.createQuery("""
SELECT t FROM ProductTag t
WHERE t.active = true
ORDER BY t.sortOrder, t.name
""", ProductTag.class)
.getResultList();
}
}

Hibernate @TenantId 會依目前 Session 自動隔離這個查詢,不需在 JPQL 重複加入 tenantId。

  1. 建立 Provider
@Component
@RequiredArgsConstructor
public class ProductTagReferenceDataProvider
implements ReferenceDataProvider {

private final ProductTagRepository productTagRepository;

@Override
public String type() {
return "product-tags";
}

@Override
public List<ReferenceDataItem> items() {
return productTagRepository.findAllActive().stream()
.map(item -> ReferenceDataItem.from(item, Map.of(
"color",
item.getColor() != null ? item.getColor() : "")))
.toList();
}
}

5.4 新增 CodeData 類型(推薦)

最簡單的方式:只需在 CodeDataType 新增一行即可。

步驟

  1. CodeDataType Enum 新增常數
// service/referencedata/CodeDataType.java
public enum CodeDataType {
// ... 現有類型

// 新增類型
OCCASION_TYPES("occasion-types", "場合類型", true); // true = 多租戶

// 或全域類型
SHIPPING_METHODS("shipping-methods", "運送方式", false); // false = 全域
}
  1. 完成!

Controller 會自動註冊新類型,無需其他修改。

使用 API 管理資料

# 新增項目
curl -X POST /api/v1/references/occasion-types \
-H "Content-Type: application/json" \
-d '{"code": "WEDDING", "name": "婚禮", "sortOrder": 1}'

# 查詢
curl /api/v1/references/occasion-types

# 更新
curl -X PUT /api/v1/references/occasion-types/WEDDING \
-d '{"name": "婚禮慶典", "sortOrder": 2}'

# 刪除
curl -X DELETE /api/v1/references/occasion-types/WEDDING

與 Entity 類型的比較

項目Entity 類型CodeData 類型
新增類型步驟3 個核心類別(Entity + Repository + Provider)1 步(CodeDataType 加一行)
額外欄位✅ 支援❌ 不支援
獨立資料表✅ 每種類型一張表❌ 所有類型共用 code_data
適用場景需要擴充欄位只需 code + name

6. 命名慣例

6.1 欄位命名

欄位說明範例
code業務代碼,用於程式判斷"TWD", "BOUQUET", "PENDING"
name顯示名稱,用於 UI"新台幣", "花束", "待處理"
description詳細說明"各式鮮花花束,適合送禮"
sortOrder排序順序(數字越小越前面)1, 2, 10
active是否啟用true, false
extra額外屬性(API 回應用){"symbol": "NT$"}

6.2 API 路徑命名

規則範例
使用複數形式/references/currencies(非 /currency
使用 kebab-case/product-categories(非 /productCategories
與類型名稱對應Provider type() 與 URL path 一致

6.3 程式碼命名

項目規則範例
Entity 類別PascalCase 單數ProductCategory, Unit
Enum 類別PascalCase 單數Currency, OrderStatus
Enum 值UPPER_SNAKE_CASEPENDING_CONFIRMATION, IN_PRODUCTION
RepositoryEntity + RepositoryProductCategoryRepository
JSON 資料檔PascalCase.jsonProductCategory.json, Unit.json
Provider typekebab-case 複數"product-categories", "order-statuses"

7. 檢查清單

新增 Enum 類型

  • 建立 Enum 類別(只宣告 getLabel()不手寫 code、不標 @JsonValue
  • 在該業務領域的 @ConfigurationEnumReferenceDataProvider.of(...) 註冊一個 @Bean
  • type() 顯式宣告、kebab-case 複數、在所有 provider 間唯一
  • extra 或狀態機時,改寫專屬 provider 而非集中註冊
  • 更新 API Specification
  • 執行測試確認 API 正常

新增 Entity 類型(全域)

  • 建立 Entity 類別,繼承 BaseReferenceData
  • 建立 Repository,含 findAllActive() 方法
  • 建立專屬 ReferenceDataProvider(需注入 Repository,不適用集中註冊)
  • 建立 JSON 初始資料檔(如需要)
  • 建立或擴充對應的 SeedContributor(如需要)
  • 更新 API Specification
  • 執行測試確認 API 正常

新增 Entity 類型(多租戶)

  • 建立 Entity 類別,繼承 TenantAwareReferenceData
  • 設定 @TableuniqueConstraints(tenant_id + code)
  • 不重複宣告租戶 @Filter;隔離由繼承鏈上的 @TenantId 提供
  • 建立 EntityManager Repository,含領域需要的查詢方法
  • 建立專屬 ReferenceDataProvider(需注入 Repository,不適用集中註冊)
  • 建立 JSON 初始資料檔(如需要)
  • 建立或擴充對應的 SeedContributor,並在租戶 context 內建立交易(如需要)
  • 更新 API Specification
  • 執行測試確認 API 正常

新增 CodeData 類型(最簡單)

  • CodeDataType Enum 新增常數(指定 code、label、tenantAware)
  • 完成!Controller 會自動註冊

8. 現有實作參考

8.1 Enum 類型

類型檔案位置額外屬性
Currencyservice/referencedata/Currency.javasymbol, decimalPlaces
Countryservice/referencedata/Country.javaalpha3, englishName
ProductStatusentity/sales/ProductStatus.java-
OrderStatusentity/order/OrderStatus.javaisTerminal, isActive

8.2 Entity 類型

類型檔案位置基類額外欄位
Unitentity/referencedata/Unit.javaBaseReferenceDatasymbol, unitType
ProductCategoryentity/sales/ProductCategory.javaTenantAwareReferenceData-

8.3 CodeData 類型

類型全域/多租戶說明
payment-methods全域付款方式
payment-terms全域付款條件
delivery-time-slots多租戶配送時段
gift-wrapping-options多租戶禮品包裝
card-templates多租戶卡片範本
order-sources多租戶訂單來源

相關檔案

  • entity/referencedata/CodeData.java - Entity 類別
  • service/referencedata/CodeDataType.java - 應用型別定義
  • repository/referencedata/CodeDataRepository.java - Repository

8.4 測試資料位置

檔案位置
Unit.jsonsrc/main/resources/data/Unit.json
ProductCategory.jsonsrc/main/resources/data/ProductCategory.json
units.json (共用測試資料)../shared/test-data/units.json
product-categories.json (共用測試資料)../shared/test-data/product-categories.json

9. 常見問題 (FAQ)

Q1: 何時該用 Enum 的 name() vs 自訂 code

A: 建議統一使用 name() 作為 code,除非:

  • 需要與外部系統對接(如 ISO 代碼)
  • 歷史資料已使用不同的 code 格式
// 推薦:使用 name() 作為 code
public String getCode() {
return name();
}

// 例外:外部標準代碼
public enum Currency {
TWD("TWD", "新台幣", ...), // code 與 name() 相同
// ...
}

Q2: Reference Data 應該快取嗎?

A: 建議在以下層級快取:

層級方式適用場景
前端Store/State一次取得,整個 session 使用
後端Spring CacheEntity 類型,減少 DB 查詢
不快取-多租戶 Entity(因租戶隔離)
// 後端快取範例
@Cacheable("units")
public List<Unit> findAllActive() {
return unitRepository.findByActiveTrue();
}

Q3: 如何處理已停用但被參照的 Reference Data?

A: 使用軟刪除(active = false),不要物理刪除:

// Provider 的列表查詢只返回啟用項目
List<Unit> findAllActive();

// 但仍可透過 code 查詢(含停用的),用於顯示歷史資料
Optional<Unit> findByCode(String code);

Q4: 多租戶 Reference Data 的初始資料如何處理?

A: 兩種策略:

  1. 範本資料:新租戶建立時,自動複製一組預設資料
  2. 空白開始:新租戶沒有預設資料,由業務人員自行建立

目前專案使用策略 1(見 DataInitializer)。

Q5: 如何在其他 Entity 中參照 Reference Data?

A: 依據關聯類型選擇:

// Enum 類型:直接使用 Enum
@Enumerated(EnumType.STRING)
@Column(length = 20)
private OrderStatus status;

// Entity 類型(全域):使用 code
@Column(name = "unit_code", length = 36)
private String unitCode;

// Entity 類型(多租戶):使用 code(同租戶內唯一)
@Column(name = "category_code", length = 36)
private String categoryCode;

參考資料

相關文檔

相關程式碼

相關程式碼位於 app-tenant-server 參考實作:

  • entity/referencedata/BaseReferenceData.java - 全域 Reference Data 基類
  • entity/referencedata/TenantAwareReferenceData.java - 多租戶 Reference Data 基類
  • controller/referencedata/ReferenceDataController.java - Reference Data API Controller
  • feature/referencedata/ReferenceDataItem.java - 中性投影契約

API Specification

  • bruno/references/ - Reference Data API Specification

文檔維護者: Development Team + AI Assistant 最後審閱: 2025-12-29