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 seeded BankVendor (dart/fib), enforced via
vendorBankIdMismatch. Returns DUPLICATE if the slug already
exists (including soft-deleted rows — external_id is globally unique).
OptionalbankIds?: string[]OptionalcreatedAt?: DbTimestampCriteria<Instant>Optionalids?: Vendor[]OptionalorderBy?: DbOrderByCriterion<Optionalpage?: numberOptionalpageSize?: numberOptionalq?: stringCase-insensitive substring over externalId and name.
OptionalupdatedAt?: DbTimestampCriteria<Instant>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, metcap) 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.