İçeriğe geç

/adjustments

docs/src/snippets/modules.test.ts
// import { flatCredit, minimumCommit, volumeTrueUp } from "pricemeter/adjustments";
// Period close: $100 minimum commitment, $30 spent → charge the $70 shortfall.
const plan = minimumCommit({
account: "acme",
minimumMicroUsd: 100_000_000,
spentMicroUsd: 30_000_000, // e.g. sqliteAdapter.spent({ account, from, to })
period: "2026-09",
at: Date.parse("2026-10-01T00:00:00Z"),
});
// plan.ledger → [{ op: "charge", amount: 70000000, refType: "period", refId: "minimum_commit:acme:2026-09" }]
await metering.commit(plan); // { ok: true } — and again on a retried cron: still one row
flatCredit({ account: "acme", amountMicroUsd: 10_000_000, refType: "coupon", refId: "WELCOME10:acme", at });
// → one charge of −10000000

pricemeter/adjustments bir Plan döndüren saf fonksiyonlardır; planı metering.commit(plan) ile yazarsın (A92). Ne zaman çalışacakları (cron, dönem kapanışı) uygulamanın kararıdır. Modül testindeki dikişi “plan kalemi üretmek”tir.

API Plan refId
minimumCommit({ account, minimumMicroUsd, spentMicroUsd, period, at, refType? }) Açık varsa tek charge (eksik = asgari − harcanan); yoksa boş plan minimum_commit:{account}:{period} (A103), refType varsayılan "period"
flatCredit({ account, amountMicroUsd, refType, refId, at }) Tek negatif charge (kupon benzeri kredi, B27) senin verdiğin
volumeTrueUp({ account, meter, dims?, rate, quantity, chargedMicroUsd, refType, refId, at }) Dönemin tamamı bittiği kademeden fiyatlanır, farkı charge + usage satırı (quantity: 0, detail.adjustment: true) senin verdiğin
docs/src/snippets/modules.test.ts
const rate = defineRate({ model: "volume", tiers: [{ from: 0, unitPriceMicroUsd: 10_000 }, { from: 1_000, unitPriceMicroUsd: 8_000 }] });
// 900 then 200 units were charged at the tier each landed in: 9,000,000 + 1,600,000
volumeTrueUp({ account: "acme", meter: "api", rate, quantity: 1_100, chargedMicroUsd: 10_600_000, refType: "period", refId: "true_up:api:2026-09", at });
// → ledger [{ op: "charge", amount: -1800000 }], usage [{ quantity: 0, amount: -1800000, detail: { adjustment: true, … } }]

volumeTrueUp, adjustmentTiming: "none" ile kullanılır: dönem içinde her gözlem düştüğü kademeden ödenir, dönem sonunda bir kez düzeltilir (B6). Dönem toplamı tek gözlem değildir, bu yüzden perObservation kırpması uygulanmaz. on_crossing ile aynı düzeltme anında, gözlemle birlikte yapılır (hacim düzeltmesi).

Harcanan tutarı sen verirsin: ör. sqliteAdapter.spent({ account, from, to }) dönem penceresindeki charge + capture toplamını döner.

Bir plan sadece iki listedir; elle kurabilirsin:

docs/src/snippets/modules.test.ts
// Without /adjustments: it is just a Plan. What matters is the stable refId.
const shortfall = 100_000_000 - 30_000_000;
const byHand: Plan = {
ledger: shortfall > 0 ? [{ op: "charge", account: "acme", amount: shortfall as never, refType: "period", refId: "minimum_commit:acme:2026-09", at }] : [],
usage: [],
};
await metering.commit(byHand);

Önemli olan tek şey kararlı bir refId: aynı dönemi iki kez kapatan bir cron’un ikinci planı commit’te no-op olmalı. refId’ye hesabı da koy: ledger tekilliği (op, refType, refId) üzerinden hesaplar arası geneldir, hesapsız bir refId ikinci hesabın kalemini sessizce düşürür.