BetaLenzon is in beta — the Free tier is 100% free while we're in beta (bring your own Anthropic key, public repos).See plans →
Lenzon

horizontwo/policyflow PR #114 — Fix KYC escalation with structured rep names — PR #114

horizontwo/policyflow · pull request #114 ·

Loading…

Transcript

PlainEnglish

Pull request one fourteen from horizontwo policyflow — fixing a KYC escalation bug with structured rep names. This change touches seven files with nearly five hundred additions, and it's all about making sure we send the right person's name to Masspay instead of accidentally sending the company name.

PlainEnglish

Here's what we're tackling. The two main goals are eliminating those free-text name splitting bugs — you know, when someone types John Smith Junior and it gets mangled — and defaulting the Business Bank Account Rep name from the contact the operator selects. We're also adding collision detection to warn when the rep name matches the business name, reordering the modal so contact selection happens before bank setup, and cleaning up a dead field. And we're keeping all the API and database identifier naming intact for backward compatibility.

PlainEnglish

So why does this PR exist? Masspay was escalating payees to extra KYC verification whenever the individual name fields received a company name instead of a person's name. The old flow had a Name on Account text box right below the prefilled Business Name field, at a step labeled for notifications only. Operators would naturally type the company name again. Worse, the field split names on whitespace, so John Smith Junior became last name Junior, and mononyms ended up with empty last names. The fix reorders the flow to prioritize contact selection — which gives us a real person to default from — and replaces that single text box with three structured fields.

Architecture

Let's trace the new flow. When the operator opens the vendor setup modal, Step One is now contact selection. Once they pick a contact, we seed the rep name fields from that contact's structured first, middle, and last name. Then Step Two is bank setup, where those rep name fields are editable but already populated. This reordering is key — the context is clear when the rep name appears, so operators understand it's defaulting from the contact they just chose.

Architecture

Here's the state change in the modal. We replaced the single nameOnAccount field with three structured rep name fields — first, middle, and last — plus a touched flag to track when the operator has made an edit. In the old code, we split the name on whitespace at submission time, which mangled anything with a suffix or a middle name. Now we use the three fields directly, trimmed but otherwise verbatim. No splitting, no guessing. Multi-word middle names stay intact.

Architecture

When the operator selects a contact, we default the rep name fields from the contact's structured name — but only if they haven't already edited the fields. The repNameTouched flag prevents us from silently clobbering an override when they switch between contacts. There's also a reset handler that lets them discard their edit and re-apply the contact's name if they change their mind. This gives operators control while still providing a helpful default in the common case.

Architecture

Here's the collision detection logic in the payee service. We normalize both the business name and the rep name — trim whitespace, collapse multiple spaces, lowercase — and compare them. If they match, we log a warning but don't block submission. This is the exact pattern that triggers Masspay KYC escalation, so the warning helps measure whether the contact defaulting is actually holding in practice. The non-blocking posture matches how we handle TIN warnings — we surface the issue but trust the operator's judgment.

Architecture

The API schema gets the same treatment. We removed the dead nameOnAccount field and replaced it with three structured fields — firstName, middleName, and lastName. The schema uses trim and min one to block whitespace-only names before they even reach the service layer. Middle name is optional, but first and last are required. The comment clarifies that signerEmail is for Masspay and the bank, not for Snapsheet notifications — that's handled separately via the contact.

PlainEnglish

After this PR lands, new vendor payee creation defaults the Business Bank Account Rep name from the selected Snapsheet contact's structured first, middle, and last name fields. The modal prioritizes contact selection before bank details, so the context is clear when the rep name appears. Operators can still override if the authorized rep isn't a listed contact, and the collision warning fires when the rep name matches the business name — the exact pattern that triggers Masspay KYC escalation. Existing payees can still be repaired via the ops tool, and the API maintains backward-compatible field naming.

CodeQuality

The agent found six gotchas. Most of them cluster in the low-impact, low-likelihood quadrant — acceptable risk. Item one is the highest impact: if an existing payee has a bank account but no contact, the user could get locked in Step One. The agent notes this scenario would have triggered the repair form instead, so the gate is sound in practice. Item two is about auto-select logic relying on hoisted initialization state — non-obvious control flow, but correct behavior. The rest are validation edge cases and cosmetic logging issues. Nothing blocking, but worth keeping an eye on.

PlainEnglish

So here's the takeaway. This is a focused compliance fix that defaults rep names from contacts, eliminating the KYC escalation trigger. The code is clean, the tests cover the core behavior, and the gotchas are all low severity. I'm recommending approve with a couple of follow-up notes. First, the commit message mentions end-to-end KYC improvement needs sandbox validation against Masspay's get user status requirements — confirm that's in progress. Second, the repair form kept a single free-text field instead of three fields; make sure that's the intended split. And third, consider whether the collision detection should catch edge cases like accented characters or name prefixes. Nice work — this is going to save a lot of manual intervention downstream.

How this was made

Lenzon read horizontwo/policyflow at pull request #114 and generated this walkthrough automatically. The narration above is the transcript of what it says.

Explain a pull request from your own repo

Point Lenzon at a repo or a pull request and get a narrated walkthrough like this one.

Try it
horizontwo/policyflow PR #114 — Fix KYC escalation with structured rep names — PR #114