Publishes product.vendor.*; null publishes nothing (scripts, tests).
Protected ReadonlycacheProtected ReadonlydbStaticinstanceThe process default: built from each dependency's own instance().
ProtectedbustAfter a committed write: the folded-get keys (a tag bust no-ops without
Valkey), then every page through the collection tag.
ProtectedcachedServes input's page from the cache, else runs query and caches it.
Create a new vendor. Inserts the product_vendor identity row AND its
baseline product_vendor_version snapshot in one transaction. The identity
row's NOT NULL current_version_id is pre-assigned from the version
table's identity sequence (nextval on product_vendor_version.id) so it
can be set before the version row exists; the deferrable FK validates at
commit. This makes a version-less vendor — the state
ProductRouteService.search's inner join silently drops — impossible.
New slugs are non-bank by default: bankId must be null unless the slug
is a BankVendor (dart/fib/greendot), enforced via
vendorBankIdMismatch. Returns DUPLICATE if the slug already
exists (including soft-deleted rows — external_id is globally unique).
Clear each customer's membership tag and each record tag wherever cached,
and always this namespace's collection tag. keys are exact deletes in this
instance's key space: the only bust a null client honours.
OptionalbankIds?: string[]OptionalcreatedAt?: DbTimestampCriteria<Instant>Optionalids?: Vendor[]OptionalorderBy?: DbOrderByCriterion<Optionalpage?: numberOptionalpageSize?: numberOptionalq?: stringCase-insensitive substring over externalId and name.
OptionalupdatedAt?: DbTimestampCriteria<Instant>ProtectedsearchTags for a page: the scope its query searched (each customer's membership
tag, else the collection tag), so an empty page is bustable too, plus the
records it projects and the fields that chose or ordered its rows.
Update vendor terms. Snapshots the post-update state into
product_vendor_version in the same transaction so the audit log has
a row per change. name and data fields are independently optional;
only the fields actually present in data are touched.
bankId agreement against the vendor slug is enforced — bank vendors
(dart, fib, greendot) require bankId to equal the slug; non-bank
vendors require bankId === null.
Admin-tier read + write over
product_vendor.create()inserts the identity row plus its baselineproduct_vendor_versionin one transaction, pointingcurrent_version_idat the new version;update()snaps a row intoproduct_vendor_versionand re-pointscurrent_version_idin the same transaction. The NOT NULLcurrent_version_idFK (deferrable, in migration20260710182509_add_product_vendor_current_version_id) makes a version-less vendor impossible by construction — the stateProductRouteService.search's inner join used to silently drop.