port.js
1.54 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
/**
* `port.js` —— `asBillingPort`:把 `deduct` 收窄成 `BillingPort.charge`。
*
* llm/tts 在「续写 / 合成语音」时只需要「扣费,不足即中止」这一条能力,不该看到
* grant / paywall / products。本文件把 deduct 收窄成最小、稳定的 `BillingPort` 面,
* 供它们注入消费——llm/tts 不 import billing,billing 也不 import 它们(架构 §8)。
*
* @typedef {{ charge:(p:{user_id:string,amount:number,reason:string,ref_type?:string,ref_id?:string,idempotency_key:string})=>Promise<{balance_after:number}> }} BillingPort
*/
/**
* @param {object} deps
* @param {(p:any)=>Promise<{balance_after:number,ledger_id:string}>} deps.deduct
* @returns {BillingPort}
*/
export function asBillingPort({ deduct }) {
return {
/**
* 扣费。余额不足时 deduct 抛 `BillingError({ code:'INSUFFICIENT_BALANCE' })`,
* 原样上抛供调用方据此中止生成。返回面收窄为只含 `balance_after`。
* @param {object} p
* @param {string} p.user_id
* @param {number} p.amount
* @param {string} p.reason
* @param {string} [p.ref_type]
* @param {string} [p.ref_id]
* @param {string} p.idempotency_key
* @returns {Promise<{ balance_after:number }>}
*/
async charge({ user_id, amount, reason, ref_type, ref_id, idempotency_key }) {
const { balance_after } = await deduct({
user_id,
amount,
reason,
ref_type,
ref_id,
idempotency_key,
})
return { balance_after }
},
}
}