Get instrument by ID or reference ID
It can be further narrowed down by type, customer ID and entity ID.
Bust every cached page — consumer or admin — that a write touching
customerIds could have affected.
The collection tag is always cleared alongside, because an unscoped admin page carries only that tag and no customer id can reach it.
keys deletes exact entries in addition to the tag surgery, passing the
key arguments — this cache hashes and prefixes them. It exists because
invalidateTag resolves keys through the FT index, which does not exist in
memory mode (valkeyClient: null); there the tag bust is a total no-op, and
an exact-key delete is the only thing that keeps read-after-write honest.
Services that folded get onto search pass that get's arguments.
These deletes only reach this instance's own key space, because the key space is partitioned per surface. That is sufficient, and a writer must not try to name the other surface's key:
get entry is itself tagged (by customer
id, or by the collection tag when unscoped), so the tag bust above already
evicts it from the shared L2 and publishes the peer eviction.OptionalanyFieldLike?: stringUnscoped partial match over every instrumentData value — reaches
fields no type map lists (account numbers, bank names), at the cost of a
scan. Admin-only; this is what the admin surface used to expose under the
name partialText.
OptionalcreatedAt?: DbTimestampCriteriaOptionalcustomerIds?: string[]Optionaldeleted?: booleanOptionalentityIds?: string[]Optionalids?: string[]OptionalnameLike?: stringPartial match over the requested types' name-ish fields. Requires types.
OptionalnominisWalletScreenRequestIds?: string[]OptionalorderBy?: DbOrderByCriterion<Optionalpage?: numberDefaults to 1
OptionalpageSize?: number | nullDefaults to 10. null for no limit
OptionalpartialText?: stringPartial match over referenceId plus each requested type's searchable
fields. Requires types. Same filter, same meaning as the consumer
surface's — see internal/search.ts.
OptionalproviderIds?: string[]Provider-side account identifier. The blacklist is keyed on this, so
block / unblock read their affected rows through here rather than
running a bespoke query.
Optionalproviders?: (OptionalquilttConnectionIds?: string[]OptionalreferenceIdLike?: stringOptionalreferenceIds?: string[]Optionalstatuses?: ("ACTIVE" | "BLOCKED" | "DELETED" | "PENDING_VERIFICATION")[]Optionaltx?: PgAsyncTransaction<NodePgQueryResultHKT, EmptyRelations>Optionaltypes?: (OptionalupdatedAt?: DbTimestampCriteriaProtectedsearchTags to write on a page, derived from the scope the query searched — never from the customers present in the result.
That distinction is load-bearing. An entry tagged with the customer ids in
the page carries no tags when the page is empty, so nothing can ever bust
it and a later create leaves it stale for the full L2 TTL. Tagging by
scope means an empty page still carries the tag for what it searched.
An unscoped read falls back to the collection tag, since no customer-id tag can reach a row whose owner did not exist when the entry was written.
StaticdeserializeThe inverse of serializePaymentInstrument: rehydrates the Date
fields. The spread preserves the type discriminant, so the ten-member
union survives the round trip.
StaticserializeA search row → its JSON-safe form. Safe to call without a cache instance.
Cross-customer queries and instrument type-agnostic admin actions