import type { Account, AccountInput, Consumption, ConsumptionAmount, Entitlement, EntitlementGrant, EntitlementType, Payment, PaymentInput, PaymentStatus, Receipt } from './domain.js'; /** * Filter for listing entitlements. All fields are optional and AND together. */ export interface ListEntitlementsFilter { /** Only entitlements with status in this list. Default: ['active']. */ readonly status?: readonly Entitlement['status'][]; /** Only entitlements whose scope could cover this (service, tool) pair. */ readonly service?: string; readonly tool?: string; /** Only entitlements of these types. */ readonly types?: readonly EntitlementType[]; } export interface CheckAndConsumeInput { readonly entitlementId: string; readonly accountId: string; readonly service: string; readonly toolName: string; readonly idempotencyKey: string; readonly amount: ConsumptionAmount; /** Current time, injected so adapters can be deterministic in tests. Defaults to `now()`. */ readonly now?: string; } export type CheckAndConsumeResult = { readonly kind: 'consumed'; readonly entitlement: Entitlement; readonly consumption: Consumption; } | { /** A consumption with this idempotency key already exists — replay. */ readonly kind: 'replay'; readonly consumption: Consumption; } | { /** * The entitlement was consumed, expired, revoked, or otherwise no longer * valid between selection and the atomic check. Caller may retry against * a different candidate. */ readonly kind: 'no_longer_valid'; readonly reason: string; }; /** * The contract every entitlement store must satisfy. * * The critical primitive is `checkAndConsume`. Implementations MUST perform * the read, the decrement/state-change, and the consumption insert as a * single atomic operation. Idempotency-key collision on the consumption row * is what defends against double-spend on replays. */ export interface EntitlementStore { upsertAccount(input: AccountInput): Promise; getAccount(accountId: string): Promise; getAccountByAgentId(agentId: string): Promise; listEntitlements(accountId: string, filter?: ListEntitlementsFilter): Promise; getEntitlement(id: string): Promise; grant(grant: EntitlementGrant): Promise; revoke(entitlementId: string): Promise; expire(entitlementId: string): Promise; checkAndConsume(input: CheckAndConsumeInput): Promise; findConsumption(idempotencyKey: string): Promise; listConsumptions(accountId: string, since?: string): Promise; createPayment(input: PaymentInput): Promise; updatePaymentStatus(paymentId: string, status: PaymentStatus, fields?: { providerIntentId?: string; providerRef?: string; }): Promise; getPayment(paymentId: string): Promise; findPaymentByIdempotencyKey(key: string): Promise; /** * Look up a payment by the provider's intent identifier (e.g. * Stripe `pi_...`). Used as a fallback by the inbound Stripe * webhook receiver when `metadata.stipend_payment_id` is absent on * a PaymentIntent created out-of-band — see Phase 7.5 follow-up in * SESSION_NOTES. * * Adapters that index `provider_intent_id` should make the lookup * O(1); others may scan, but a single-field index is recommended. */ findPaymentByProviderIntentId(providerIntentId: string): Promise; saveReceipt(receipt: Receipt): Promise; getReceipt(id: string): Promise; } //# sourceMappingURL=store.d.ts.map