Skip to content

feat: paste a LinkedIn profile on a position and run the JD match analysis in one flow (G#9) - #10

Closed
psdjungpulzze wants to merge 5 commits into
mainfrom
goal/paste-a-linkedin-profile-and-run-jd-match-analysis-in-one-st-c9a87631
Closed

psdjungpulzze wants to merge 5 commits into
mainfrom
goal/paste-a-linkedin-profile-and-run-jd-match-analysis-in-one-st-c9a87631

Conversation

@psdjungpulzze

Copy link
Copy Markdown
Contributor

Summary

G#9: from a position, a recruiter pastes LinkedIn profile text (or uploads the LinkedIn PDF export), checks the profile AI drafts, and one click saves the candidate, adds them to the position and starts the match analysis. Implements init.docx §4.1/§4.2 (FR-SRC-02) and §5 Matching (FR-MAT-02/03/06).

Changes

  • POST positions/[positionId]/candidates/intake: pasted text or PDF, source always LinkedIn, profile link stored as text and never fetched (§4.1, C4). Request parsing moved to a shared helper used by both intake routes.
  • POST positions/[positionId]/candidates/confirm: normal confirm (duplicate resolution kept), add as sourced, and "can the analysis start?" in one transaction. It does not call the model. No analysis is offered after a merge or without a confirmed success profile, and the response says why.
  • Paste page at /positions/<id>/candidates/paste, a "Confirm, add to position and analyze" button on the review step, and an analysis page that starts the first analysis on arrival (never replaces an existing one).
  • Docs: api-contracts, implementation-notes #62, tasks T-2-19.

Design principles (§1.1)

Recruiter decides; AI runs only after the recruiter's confirm click (the analysis needs an approved profile, so that click is the request); profile and analysis stay drafts; score is reference only; no resume facts changed; protected fields stay redacted by the existing planMatchAnalysis.

Testing

  • tsc, full web Vitest run (2115 passed, 0 failed), permission matrix and route classification
  • Component tests for the paste form, the confirm step and the auto-started analysis
  • confirm-and-add.db.test.ts (6 cases) written but NOT run: no local Postgres/Redis
  • Lint, Playwright and axe on the new page not run
  • English strings only (Korean catalogs are still a skeleton, ADR-015)

Generated with AI assistance

Co-Authored-By: Interactor Build peter@interactor.com

…ofiles

Brief 4.1/4.2. POST positions/[positionId]/candidates/intake takes pasted text
or a LinkedIn PDF export, forces source=linkedin, stores the profile link as
text only (never fetched) and reuses the existing draft and extraction jobs.
The request parsing moves to a shared helper used by both intake routes.

Generated with AI assistance

Co-Authored-By: Interactor Build <peter@interactor.com>
…plan the analysis in one action

Brief 4.2, 5.1. POST positions/[positionId]/candidates/confirm runs the normal
confirm (duplicate resolution kept), adds the candidate as sourced and reports
whether the analysis can start, in one transaction. It does not call the model;
no analysis is offered after a merge or without a confirmed success profile.

Generated with AI assistance

Co-Authored-By: Interactor Build <peter@interactor.com>
…flow

Brief 4.1, 5.1. A paste page on the position, the review step with one
"Confirm, add to position and analyze" click, and an analysis page that starts
the first analysis on arrival. The profile link is stored, never fetched.

Generated with AI assistance

Co-Authored-By: Interactor Build <peter@interactor.com>
Generated with AI assistance

Co-Authored-By: Interactor Build <peter@interactor.com>
The shared fixture tripped the real duplicate check across tests in CI; the
duplicate and merge tests now share one profile on purpose.

Generated with AI assistance

Co-Authored-By: Interactor Build <peter@interactor.com>
@sunghan0919

Copy link
Copy Markdown
Collaborator

Closing in favor of #9, on the product owner's decision (2026-10-15). Both implement G#9; #9 matches the requirement agreed afterwards: recruiters upload up to 10 resumes / LinkedIn PDFs at once from the position page, and confirming each draft adds it to the position and requests the match analysis. The branch is kept, not deleted.

Generated with AI assistance

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.

2 participants