Skip to content

feat(api): Guarded Invoice PATCH Endpoint#80

Open
simplicityf wants to merge 3 commits intoLiquifact:mainfrom
simplicityf:feature/patch-invoice-controlled-fields
Open

feat(api): Guarded Invoice PATCH Endpoint#80
simplicityf wants to merge 3 commits intoLiquifact:mainfrom
simplicityf:feature/patch-invoice-controlled-fields

Conversation

@simplicityf
Copy link
Copy Markdown

What

Adds PATCH /api/invoices/:id with strict field-level access controls and status-aware edit permissions.

Why

Invoice records contain financially sensitive fields (amount, customer) that must become immutable once they enter the verification/funding pipeline. Without this guard, any authenticated caller could silently overwrite committed values or spoof system-managed fields like status and id.

How

A dedicated middleware (middleware/patchInvoice.js) owns all guard logic and is independently unit-tested:

  • Allowlist — only amount, customer, and notes are ever writable; all other keys are stripped before any write occurs.
  • Status lockamount and customer are rejected with 422 once the invoice status is verified, funded, settled, or cancelled; notes remains editable throughout.
  • Soft-delete guard — returns 409 if the invoice has been soft-deleted; caller must restore first.

Test coverage

42 tests, middleware/patchInvoice.js at 100% statement / branch / function / line coverage.

Security notes

Risk Mitigation
Mass assignment Strict MUTABLE_FIELDS allowlist; unknown keys discarded before write
Status spoofing status not in allowlist; only a dedicated transition endpoint can change it
Prototype pollution Object.prototype.hasOwnProperty.call guards throughout
Deleted record mutation 409 guard; restore required before update

Checklist

  • Route implemented and wired
  • Field guard middleware with JSDoc
  • 42 tests (integration + unit)
  • README updated
  • No new dependencies

Related Issue

Closes #24

Screenshot

0

@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Mar 26, 2026

@simplicityf Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@mikewheeleer
Copy link
Copy Markdown
Contributor

Resolve the conflicts & revert the changes in package-lock.json

@simplicityf
Copy link
Copy Markdown
Author

@mikewheeleer

@simplicityf
Copy link
Copy Markdown
Author

@mikewheeleer kindly review

@simplicityf
Copy link
Copy Markdown
Author

@mikewheeleer

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.

Add Invoice Update Endpoint with Field Controls

2 participants