Skip to content

fix(schema): default invPaid to false so bulk-create doesn't trip NOT NULL#279

Merged
CryptoJones merged 1 commit into
masterfrom
fix/invoice-schema-invpaid-default
May 19, 2026
Merged

fix(schema): default invPaid to false so bulk-create doesn't trip NOT NULL#279
CryptoJones merged 1 commit into
masterfrom
fix/invoice-schema-invpaid-default

Conversation

@CryptoJones
Copy link
Copy Markdown
Owner

Summary

Same drift class as #265 (custState) and #277 (custCompanyName et al.), but with a twist: the single-create invoice controller already short-circuited a missing invPaid to false inline, so the bug only manifested in the bulk path (makeBulkCreateIndirect), which doesn't apply entity-specific defaults.

A bulk POST like

{ "invoices": [{ "invCustId": 5, "invDate": "2026-01-01", "invDueDate": "2026-02-01" }] }

passed the zod schema (invPaid was .optional()) and then tripped "null value in column invPaid violates not-null constraint" at the postgres INSERT — surfacing as a 500 instead of a clean accepted row.

What changed

Switched the schema to z.boolean().default(false). The validator now fills the value at the request boundary, so both paths (single + bulk) get invPaid: false for free. The single-create controller's explicit default-to-false line is now dead defense but stays harmless.

Test plan

  • npm run lint && npm test — 760 passing.
  • No new tests added; the existing bulk-create coverage and the invoice-controller tests both exercise the now-defaulted shape.

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

… NULL

Same drift class as #265 (custState) and #277 (custCompanyName et al.),
but with a twist: the single-create controller already filled in the
missing-invPaid case with \`if (payload.invPaid === undefined)
payload.invPaid = false;\`, so the bug only manifested in the bulk
path, which routes through \`makeBulkCreateIndirect\` and doesn't
have entity-specific defaults.

A bulk POST like
  { invoices: [{ invCustId: 5, invDate: "2026-01-01",
                 invDueDate: "2026-02-01" }] }
passed the schema (invPaid was \`.optional()\`), and then tripped
"null value in column invPaid violates not-null constraint" at the
postgres INSERT — surfacing as a 500 instead of a clean accepted
row.

Switching the schema to \`z.boolean().default(false)\` fills the
value at the validator boundary, so both paths now get
\`invPaid: false\` for free. The single-create controller's
explicit default becomes dead defense but stays harmless.

760 tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CryptoJones CryptoJones merged commit c9265d6 into master May 19, 2026
3 checks passed
@CryptoJones CryptoJones deleted the fix/invoice-schema-invpaid-default branch May 19, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant