products.js
1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* `products.js` —— 产品目录读取(积分套餐 + 可购权益)。
*
* 产品目录,数据全来自 `billingRepo`(运营可改)。`save` 保存完整产品定义;调用方不传的
* 可选字段会按默认值或 null 入库,不做隐式局部 patch。
*
* @typedef {import('./repo/index.js').BillingRepo} BillingRepo
*/
import { BillingError, BillingErrorCode } from './errors.js'
/**
* @param {BillingRepo} billingRepo
*/
export function createProducts(billingRepo) {
return {
/** @returns {Promise<Product[]>} */
async list() {
return billingRepo.listProducts()
},
async listAll() {
return billingRepo.listAllProducts()
},
/**
* @param {string} productId
* @returns {Promise<Product|null>}
*/
async get(productId) {
const p = await billingRepo.findProduct(productId)
return p ?? null
},
/**
* @param {Record<string, any>} product
*/
async save(product) {
if (!product?.id) {
throw new BillingError({
code: BillingErrorCode.PRODUCT_NOT_FOUND,
message: '产品 id 不能为空',
retryable: false,
})
}
return billingRepo.saveProduct(product)
},
/**
* 取产品,缺失即抛(供需要强存在性的编排用,如 payment 下单)。
* @param {string} productId
* @returns {Promise<Product>}
*/
async require(productId) {
const p = await billingRepo.findProduct(productId)
if (!p) {
throw new BillingError({
code: BillingErrorCode.PRODUCT_NOT_FOUND,
message: `产品不存在: ${productId}`,
retryable: false,
})
}
return p
},
}
}