Skip to content

Commit 98d6b40

Browse files
committed
fix(webapp): stop rejecting card requests for customers with no identifier
A contact created by an integration can legitimately have neither an email nor an external id. The schema still rejected that shape, so Plain recorded an integration error for the whole request — the same failure this PR removes for a null external id. There is nothing to look up, so the route now answers every requested key with no data and Plain hides the cards. The route already handled it; only the refine stood in the way.
1 parent 78330f2 commit 98d6b40

2 files changed

Lines changed: 13 additions & 12 deletions

File tree

apps/webapp/app/utils/plainCustomerCards.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@ describe("PlainCustomerCardRequestSchema", () => {
4444
expect(PlainCustomerCardRequestSchema.safeParse(request()).success).toBe(true);
4545
});
4646

47-
it("still requires one of email or externalId", () => {
47+
// A contact created by an integration can have neither identifier. There's nothing to look up,
48+
// but rejecting it would make Plain record an integration error rather than hide the card.
49+
it("accepts a customer with neither email nor externalId", () => {
4850
const result = PlainCustomerCardRequestSchema.safeParse(
4951
request({ customer: { id: "c_1", email: null, externalId: null } })
5052
);
5153

52-
expect(result.success).toBe(false);
54+
expect(result.success).toBe(true);
5355
});
5456

5557
it("rejects a body with no card keys field", () => {

apps/webapp/app/utils/plainCustomerCards.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,15 @@ import { z } from "zod";
1111
*/
1212
export const PlainCustomerCardRequestSchema = z.object({
1313
cardKeys: z.array(z.string()),
14-
customer: z
15-
.object({
16-
id: z.string(),
17-
email: z.string().nullish(),
18-
externalId: z.string().nullish(),
19-
})
20-
.refine((data) => data.email || data.externalId, {
21-
message: "Either customer.email or customer.externalId must be provided",
22-
path: ["customer"],
23-
}),
14+
// A customer with neither an email nor an external id is valid input, not a malformed request:
15+
// a contact created by an integration can legitimately have neither. There's nothing to look up,
16+
// so the route answers every key with no data — rejecting it would make Plain record an
17+
// integration error, which is the failure this schema change exists to remove.
18+
customer: z.object({
19+
id: z.string(),
20+
email: z.string().nullish(),
21+
externalId: z.string().nullish(),
22+
}),
2423
thread: z
2524
.object({
2625
id: z.string(),

0 commit comments

Comments
 (0)