Skip to content

feat(cv-sections): add best-effort bulk-create endpoint for education/experience - #174

Merged
datvt243 merged 1 commit into
stagingfrom
161-bulk-import-endpoint
Sep 28, 2026
Merged

datvt243 merged 1 commit into
stagingfrom
161-bulk-import-endpoint

Conversation

@datvt243

Copy link
Copy Markdown
Owner

Summary

  • New POST /api/v1/education/bulk and POST /api/v1/experience/bulk (best-effort, up to 100 items per request), reusing createCrudController()'s new fnBulkCreate — per-item candidateId is forced from the authenticated user (IDOR-safe, matching every other write path), each item validated with the section's own Joi schema, each item created via the section's own service.handlerCreate.
  • Pairs with the stateless LinkedIn-export-parse flow (PDF/LinkedIn-export parsing endpoint for CV data import #141): parse -> review client-side -> bulk-save.
  • Bug found and fixed during implementation: utils/helper.ts's formatResponse() nulls out data whenever the response envelope's success is false. fnBulkCreate keeps the envelope success: true always so a partial failure doesn't silently drop results/summary from the response.
  • 5 new regression tests in BaseController.test.ts.

Commits

  • 8750bd0 feat(cv-sections): add best-effort bulk-create endpoint for education/experience

Test plan

  • npm test — 155 passed, 155 total (29/29 suites), independently re-run by the verifier subagent
  • npm run build — clean
  • agent-hub node add-bulk-import-cv-sections SEALED after independent verifier pass (evidence: agent-hub/evidence/implementer/2026-09-28/add-bulk-import-cv-sections-plan.md, agent-hub/evidence/verifier/2026-09-28/add-bulk-import-cv-sections-seal.md)

Closes #161.

🤖 Generated with Claude Code

…/experience

Closes #161. Pairs with the stateless LinkedIn-export-parse flow (#141):
parse -> review client-side -> bulk-save many entries in one request
instead of one create call per entry.

- src/candidate_profile/BaseController.ts: new fnBulkCreate on
  createCrudController() (reused, not a dedicated bulk-only path) and a
  MAX_BULK_ITEMS=100 cap. Forces candidateId from the authenticated
  req.user._id onto every array item before validation, never trusting a
  client-supplied value nested inside items[] (verifyToken only forces
  req.body.candidateId at the top level) - same IDOR-safe pattern as every
  other write path, applied per item. Validates each item with the
  section's own Joi schema and calls the section's own
  service.handlerCreate per item; best-effort, one bad item never blocks
  the rest.
- Bug found and fixed during implementation: utils/helper.ts's
  formatResponse() nulls out `data` whenever the response envelope's
  `success` is false. A naive envelope tied to summary.failed===0 would
  have silently dropped results/summary on every partial failure - the
  one case the response most needs to report. fnBulkCreate keeps the
  envelope success:true always; real per-item pass/fail lives in
  results[]/summary instead.
- src/candidate_profile/education/education.controller.ts,
  src/candidate_profile/experience/experience.controller.ts: export the
  new fnBulkCreate alongside fnCreate/fnUpdate.
- src/routers/api/v1/education.route.ts,
  src/routers/api/v1/experience.route.ts: new POST /bulk route + swagger
  docs. Scope limited to education/experience, matching what the
  LinkedIn-export parser currently produces.
- src/locales/en.ts, src/locales/vi.ts: 2 new common.* i18n keys
  (bulkNoItems, bulkTooManyItems) for the new 400 rejection paths.
- src/__tests__/candidate_profile/BaseController.test.ts: 5 new tests -
  reject missing/non-array items, reject >100 items, candidateId force
  (IDOR-safe), partial-failure results/summary, all-success summary.
- agent-hub: seal node add-bulk-import-cv-sections (implementer +
  independent verifier subagent pass).

npm test: 155 passed, 155 total (29/29 suites, independently re-run by
the verifier subagent from scratch). npm run build: clean.

Node: add-bulk-import-cv-sections (SEALED)
Evidence: agent-hub/evidence/implementer/2026-09-28/add-bulk-import-cv-sections-plan.md,
agent-hub/evidence/verifier/2026-09-28/add-bulk-import-cv-sections-seal.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@datvt243
datvt243 merged commit 9aee1a1 into staging Sep 28, 2026
3 checks passed
@datvt243
datvt243 deleted the 161-bulk-import-endpoint branch September 28, 2026 17:05
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