Skip to content

feat(api): bulk-create endpoints for 7 indirect-scoped entities (P3-H2)#88

Merged
CryptoJones merged 1 commit into
masterfrom
feat/bulk-indirect-scope
May 18, 2026
Merged

feat(api): bulk-create endpoints for 7 indirect-scoped entities (P3-H2)#88
CryptoJones merged 1 commit into
masterfrom
feat/bulk-indirect-scope

Conversation

@CryptoJones
Copy link
Copy Markdown
Owner

Follow-up to #81 (P3-H). Extends bulk-create to the 7 entities scoped through a parent FK.

Summary

  • POST /v1/job/bulk (customer-scoped via jobCustId)
  • POST /v1/invoice/bulk (customer-scoped via invCustId)
  • POST /v1/customerpayment/bulk (customer-scoped via cpayCustId)
  • POST /v1/invoicejob/bulk (job-scoped via injbJobId)
  • POST /v1/productentry/bulk (job-scoped via pentJobId)
  • POST /v1/purchaseorderheader/bulk (vendor-scoped via pohPovId)
  • POST /v1/purchaseorderline/bulk (header-scoped via polpoh)
  • New makeBulkCreateIndirect factory parameterizes over the parent FK + the auth-helper that resolves it.
  • Together with P3-H, the bulk surface now covers all 13 soft-deletable entities.

Test plan

  • tests/api/bulk-indirect-scope.test.js (49 cases): auth contract, outer-field/empty/501-cap/unknown-field/missing-parent-FK 400s, route mounting.
  • Full suite: 469 pass / 4 skip (was 420/4).
  • Lint clean.

This code proudly made in Nebraska. GO BIG RED! 🌽 https://xkcd.com/2347/

Follow-up to P3-H. The bulk surface was previously limited to the 5
entities with a direct *CompId column. This PR extends it to the
remaining 7 soft-deletable entities, whose auth scope is resolved
*through* a parent FK rather than carried directly:

Customer-scoped (parent → Customer.custCompId):
  - POST /v1/job/bulk             jobCustId
  - POST /v1/invoice/bulk         invCustId
  - POST /v1/customerpayment/bulk cpayCustId

Job-scoped (parent → Job → Customer.custCompId):
  - POST /v1/invoicejob/bulk      injbJobId
  - POST /v1/productentry/bulk    pentJobId

Vendor/header-scoped:
  - POST /v1/purchaseorderheader/bulk  pohPovId → vendor.povCompId
  - POST /v1/purchaseorderline/bulk    polpoh   → header → vendor

Mechanics:
- New factory `makeBulkCreateIndirect` in
  `app/controllers/_bulk-helpers.js` parameterizes over
  `parentFkField` + `resolveParentCompanyId(parentId)`. The 7
  controllers gain ~10 LOC each instead of ~120.
- Per-entry validation: parent FK is REQUIRED on every entry.
  For non-master keys the resolved parent company must equal the
  caller's company (else 403 with the offending index); master
  keys aren't pinned to a company so any resolved parent is fine.
- Same 500-entry cap and transactional all-or-nothing insert as
  the direct family.

Together with P3-H, the bulk surface now covers all 13 soft-
deletable entities.

Tests
- `tests/api/bulk-indirect-scope.test.js`: 49 cases (7 entities x
  7 assertions). Auth contract, outer-field 400s, empty/501-cap
  400s, unknown-field 400, missing-parent-FK 400, route mounting.
- Full suite: 469 pass / 4 skip (was 420/4 — +49 net new tests).
- Lint clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CryptoJones CryptoJones merged commit cd17c2f into master May 18, 2026
3 checks passed
@CryptoJones CryptoJones deleted the feat/bulk-indirect-scope branch May 18, 2026 05:25
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