Create a new bank. The slug (id) is the public-facing identifier and
must match ^[a-z][a-z0-9_-]{1,31}$ to keep it URL- and grep-friendly.
Returns BANK_ALREADY_EXISTS if a bank with the same slug is already
onboarded.
Search banks — always paginated, pageSize defaulting to 50, ordered by
name unless orderBy says otherwise. total is a count(*) OVER ()
window over the full filtered set and hasNext the limit(pageSize + 1)
sentinel, so the bank is a first-class entity selector alongside customers
/ organizations / identities. q is a free-text match over the bank name +
slug (externalId).
A caller that wants every match pages through with searchIterator, or
bounds the page to what it asked for ({ ids, pageSize: ids.length }).
There is deliberately no "omit the page size to get everything" mode: the
cap it hides is invisible at the call site and only bites once the table
outgrows the default.
OptionaldashboardDomains?: string[]OptionaldashboardEnabled?: booleanOptionalids?: string[]OptionalorderBy?: DbOrderByCriterion<Optionalpage?: number1-based page; defaults to 1.
OptionalpageSize?: numberOptionalq?: stringUpdate mutable fields on a bank. Pass null for nullable fields to
clear them. Omitting a field leaves it untouched. The slug (id) is
not editable — references across the system store the literal slug.
Admin-tier read + write over
bank. Operators onboard new partner banks here; the DB row set is now authoritative (the historical compile-timeBankIdliteral union is retained as a string alias for self-doc, not as a constraint).Bank-shaped vendors (
dart,fib) get special-case behavior across services — seeBankVendorindb/drizzle/schema/product_vendor.ts. New banks created here arrive without that pairing and stay non-bank from a route's perspective unless someone wires up a corresponding vendor entry separately.