Inserts an inbound wire email. Idempotent on the unique SES messageId —
a replay returns the existing row instead of inserting a duplicate.
OptionalbankIds?: string[]OptionalcreatedAt?: DbTimestampCriteriaOptionalids?: string[]OptionalmessageIds?: string[]SES message ids. Used by the inbox to resolve a page of S3 objects.
OptionalorderBy?: DbOrderByCriterion<Optionalpage?: numberDefaults to 1
OptionalpageSize?: numberDefaults to 50
Optionalq?: stringFree-text filter: case-insensitive substring across the parsed wire number, IMAD/OMAD, sender name, SES message id, and raw body.
OptionalreceivedAt?: DbTimestampCriteriaOptionalstatuses?: ("IGNORED" | "RECEIVED" | "RECONCILED" | "UNMATCHED" | "UNPARSED")[]Optionaltypes?: ("CREDIT" | "DEBIT")[]OptionalwireNumbers?: string[]Exact match on the parsed wire sequence number. This is the key a synced
bank_transaction carries in its statement description ("Wire 100692787
…"), so it is how a transaction finds the notification email about the
same movement. Distinct from q, which substring-matches the same field
among five others — a reconciliation lookup must not match a wire number
that merely appears inside some other email's body.
status is the only writable column, and only the two outcomes of an
actual posting attempt can be written: RECONCILED (a bank_transaction
now covers this wire) and UNMATCHED (we tried to resolve the account and
could not). A wire we never attempted — wrong bank, a debit, no account
line — keeps whatever create gave it, because "not tried" and "tried and
failed" are different operator queues and collapsing them buries the second
in the first. The other three statuses are create's to set from the parse
outcome, so they are excluded at the type level rather than by a runtime
check.
Reads + writes the
wire_emailtable. The SES wire-email lambda callscreate; the admin-dashboard callsget/search. No customer scoping — wire emails are bank-level operator records.