The billing date and period an instant falls in, in the billing timezone. Both come from one instant, so a sweep running across local midnight cannot pair a date with the other day's period.
Charge one month at its invoice's amount and account, only once SES accepted
the invoice email. One idempotency key per month: a FAILED charge frees it
until RECURRING_FEE_RETRY_LIMIT, a CANCELLED one holds the month.
OptionalbillingDate?: stringYYYY-MM-DD in the billing timezone; today when started by hand.
Charge again: one attempt past the retry limit on an escalated month, with
charge's other checks and locks. Any other month is refused first.
OptionalbillingDate?: stringYYYY-MM-DD in the billing timezone; today when omitted.
Stop billing the customer entirely. Drops the key rather than writing a json null, because every read tests key presence.
Returns the config it removed: that amount survives nowhere else, and the caller needs it for the audit entry it records.
Enroll one candidate at the amount and account its list row holds, read under the customer row lock. Refuses a start date whose month, or a later one, holds a live manual PLATFORM charge, which the sweep would bill again.
OptionalbillingStartDate?: stringThe suggested date when absent.
OptionalcurrentPeriodKey?: stringThe month enrolling happens in; a first attempt must be for it.
One per enroll attempt: only a retry with it is answered as enrolled.
The month the caller's candidate list was read for.
The customer's fee configuration, or null when they are not billed one.
This customer's recorded fee changes, newest first.
Reads the shared admin activity feed rather than a table of the feature's
own, filtered by objectId and the customer.recurringFee.* types. Joins
the actor so the surface can name a person instead of a user id.
Recurring-fee charges, most recent first.
Reads fee_transfer directly rather than any table of the feature's own.
Selection and the period both come from data.recurringFee, which the
sweep stamps on every charge it makes, so the set is enumerable as a whole
rather than one customer at a time.
customerId is optional: omit it to enumerate every recurring fee taken,
and pair it with periodKey to pull a single month across the platform.
A period with no row here was never charged — the customer could not pay,
or is not yet due. That absence is the same signal listDue reads.
NOTE: the cross-customer form has no index behind it. fee_transfer is
indexed by account and by idempotency key, neither of which this predicate
uses, so an unscoped call scans. Fine for an operator report; add a jsonb
expression index on (data -> 'recurringFee' ->> 'periodKey') before
putting it on a hot path.
Customers to charge for periodKey: an ACTIVE fee on an ACTIVE customer
with no PROCESSING, COMPLETED or CANCELLED charge for the month, not waived
and not escalated.
The absent charge is the claim, so the feature needs no cursor and no
table of its own. A customer who slips through this query twice still
cannot be billed twice: see recurringFeeIdempotencyKey.
A customer whose charge went FAILED stays due: the nightly sweep charges
again until RECURRING_FEE_RETRY_LIMIT, then escalates the month to ops.
A CANCELLED charge holds the month until ops resolve it on chain.
A customer with a billingStartDate is due once billingDate, the date the
sweep runs on, has reached the start date's day of the month (see
isAnchorDayReached), so its invoice is issued and charged on that day.
charge applies the same rule. A fee with no start date is due from the
first sweep of the month.
Active customers with no recurring fee who paid a manual PLATFORM fee in the
period before periodKey. The suggested start is a month after their latest
live manual charge, which listDue cannot see. Scans fee_transfer unindexed.
Every PLATFORM fee taken from these customers since since, in any
status, newest first. Lets an operator see what a customer has actually
paid before choosing their monthly amount.
Set (or re-price) the fee. Validates the nominated source account exists and belongs to this customer — jsonb carries no check constraint, so the invariants are enforced here, on the one path that writes the key.
Preserves the current status, read under the customer row lock, so
re-pricing a paused fee does not silently resume billing. billingStartDate
is required: every fee says which day of the month it bills on.
A new or moved start date is refused past a month with a live unpaid invoice, which the sweep would stop charging, or with a manual PLATFORM charge in its month or later. A re-price keeping the stored date skips both checks.
Pause or resume billing without discarding the configured amount.
Whether fee starts billing in a month after periodKey.
For the bust alone: the fee is read from Postgres, never a cache.