_private/qwestly-docs/Features/provisioned-accounts/recruiting-pilot-walkthrough.md

Recruiting Pilot — Feature Walkthrough & Lifecycle

What This Feature Does

The recruiting pilot introduces the concept of provisioned accounts — a pre-built mechanism that will let recruiters set up candidates ahead of time, before an official sourcing workflow exists.

The vision: A recruiter pre-provisions an account with everything they know (contact details, resume, interview notes, preferences). The candidate receives an email invite, clicks a link, creates a password (or signs in with Google/LinkedIn), and lands on a confirmation page where their profile, preferences, and Qwestly card are already available — no redundant onboarding.


End-to-End Lifecycle

Phase 1: Recruiter Provisions an Account

The recruiter navigates to a new Provisionsioned Accounts management page at /admin/provision. From here they can:

  • Create a new provisioned account — enter the candidate's name, email, LinkedIn URL, and upload a resume.
  • Add interview notes — freeform notes from initial conversations (screening calls, etc.). These are recruiter-only and not visible to the candidate.
  • Set preferences — function, level, location, remote preference, company stage, comp expectations, availability, etc. (some fields only show in this provision flow, not in standard onboarding).
  • Generate a Qwestly card — a one-click action that produces a candidate card from the collected data, which the candidate can review and edit after claiming.

All of this can be done before the candidate even knows they've been added. The recruiter can save in draft mode and come back later.

Key statuses for a provisioned account:

Status Meaning
Draft Created but no invite sent yet
Invited Claim email has been sent to the candidate
Claimed Candidate has claimed the account

Phase 2: Invite the Candidate

Once the recruiter has entered enough information, they click "Email Claim Link." This generates a secure claim link and sends it to the candidate via a templated email (through SendGrid). The link is time-limited (expires after 7 days). The recruiter can resend at any time while the account is in Draft or Invited status.

Notes:

  • David is creating the SendGrid email template. Once that's done, the claim email flow is complete.
  • The claim URL is tied to the deployment it was generated on (uses APP_BASE_URL or falls back to the Vercel branch URL). For testing, copy the link and open it in an incognito/private window — it won't work in the same browser session where you're already logged in. When sending to real candidates, generate the link from the production deployment.

If email isn't ready yet, the recruiter can copy the claim link and share it manually (e.g., via LinkedIn message or SMS).

Phase 3: Candidate Claims the Account

The candidate clicks the link in their email and arrives at a public claim page. Here's what happens:

  1. Token validation — the system checks that the link is valid and hasn't expired. If it's invalid or expired, the candidate sees a message asking them to contact their recruiter.
  2. Already claimed? — If the account was already claimed, the candidate sees a message pointing them to log in instead.
  3. Already logged in with a different account? — The candidate is told this page is for new accounts only, with options to log out or contact support.
  4. Claim form — The candidate sees their name and email (pre-filled, read-only) and chooses how to create their account:
    • Password: They create a password, submit, and are redirected to log in with that password.
    • Google / LinkedIn (social): They choose a provider, authenticate, and the system links the account automatically.

Design note: In the password flow, the candidate enters a password, then is redirected to the login screen to enter it again. A smoother "programmatic login" option (no second password entry) was considered but deferred for now. We'll revisit if candidates find the double entry frustrating.

What happens behind the scenes when they claim: All the data the recruiter entered (preferences, resume, interview notes, Qwestly card, etc.) is linked to the candidate's real account. Nothing is lost — it's all available immediately.

Phase 4: Confirmation Page (Replaces Onboarding)

Instead of the standard multi-step onboarding flow, the candidate lands on a single confirmation page at /claim/confirmation with four sections:

Section What They See What They Can Do
1. Preferences Read-only summary of what the recruiter set Click "Edit" to adjust any preferences (auto-saves)
2. Qwestly Card Pre-generated card from LinkedIn + resume Toggle between view and edit mode
3. Resume Current resume (if uploaded by recruiter) Upload a new version (upload button — TBD)
4. Anonymity Toggle Switch controlling how they appear in search Choose De-anonymized (direct referral — specific HM sees full profile) or Anonymized (general matching — anonymous until mutual interest)

Publishing: Once the candidate is happy with everything, they click Publish. This makes their profile active and visible in recruiter search results. They're then redirected to the dashboard.

Note: The confirmation page includes explanatory copy about the anonymity toggle. That copy is placeholder and needs final wording.

Phase 5: Recruiter Searches & Finds Candidates

With all this data collected, the recruiter's search experience is enhanced in two ways:

  1. Vector search across interview notes — When a recruiter searches by keyword, the system also searches the semantic content of interview notes (plus resumes and other background info). So searching for "Go experience" can find candidates even if those exact words aren't in their resume — they might be in the recruiter's notes about the candidate.

  2. New structured filters — Recruiters can now filter candidates by:

    • Function (Engineering, Product, Design, etc.)
    • Level (Senior, Staff, Principal, Director, VP, C-Suite)
    • Search status (Active, Passive, Not Searching)

    These filters are recruiter-set (not candidate self-reported) during provisioning.

Results show "knowledge match" badges indicating which source (resume, notes, etc.) matched the search query, with relevance scores and snippets.


What's Done vs. What's Coming

✅ MVP Complete (Ready for Review)

Piece Status
Provisioned Account data model + database service Done
interview_notes knowledge base type Done
Admin management page (list + detail with all panels) Done
Admin search — vector search across knowledge base Done
Admin search — new structured filters (function, level, search status) Done
Candidate claim landing page + account creation (password + social) Done
Cross-collection user_id migration (24 collections) Done
Claim confirmation page with 4-section layout Done
Anonymity toggle (de-anonymized vs. anonymized) Done

⚡ Fast Follows

Piece What It Does
SendGrid email template + wiring The "Email Claim Link" button currently returns a URL for manual sharing. Needs the actual SendGrid template + sending integration.
Structured notes with type selector Add a dropdown for note type (Screening Call, HM Interview, Reference Check, etc.)
Skill tags & sub-specialties at intake Add skill tagging during provisioning, wired into search filters
Structured comp expectations filter Restructure comp data into min/max ranges so it can be used as a search filter (currently freeform text)
Recruiter-queued template questions Let recruiters queue standard questions for candidates to answer post-call

📋 Backlog (After Feedback Loop)

Piece What It Does
De-anonymization consent flow Candidate explicitly consents before being de-anonymized to a specific HM
"Stay Visible" opt-in When search closes, option for candidates to remain visible for other roles
HM submission view Executive summary + feedback, anonymized vs. de-anonymized per submission
Search dashboard & pipeline tracking Replace Google Sheet with proper pipeline stages and tracking
Publish notifications Email/Slack notification when a candidate publishes their profile

❓ Open Questions for the Team

These need input from the team and stakeholders before or shortly after launch:

Product / UX

# Question Owner Status
Q1 Copy for the anonymity toggle on the confirmation page — The explanatory text about de-anonymized vs. anonymized is currently placeholder. What should it say? Adam 🔴 Needs final wording
Q2 Anonymization UX flow — We're showing the de-anonymized profile first with a checkbox to anonymize. Is that the right order, or should anonymous be the default? Design team Resolved (show de-anonymized first)
Q3 Publish notifications — When a candidate publishes, should the recruiter get an email and/or Slack notification? Stakeholders ❓ Needs decision
Q4 Resume upload on confirmation page — The upload button is currently disabled pending integration. Is this a blocker for MVP, or can candidates use the dashboard resume upload as a fallback? Product ❓ Needs decision

Post-deploy step: Rebuild all search indices to backfill the new structured filter fields (function, level, search status) for existing candidates.


User Flows at a Glance

graph TD subgraph Recruiter["Recruiter Side"] A["Provision Account
(name, email, resume,
notes, preferences)"] B["Status: Invited"] A -->|"edit / resend"| B end subgraph Candidate["Candidate Side"] C["Receive claim email
with secure link"] D{"Choose"} E["Password — Create account"] F["Social — Google / LinkedIn"] G["Confirmation Page
1. Review prefs
2. View/edit Q card
3. Upload resume
4. Choose anonymity"] H["Publish"] I["Profile Active
Visible in search
Dashboard"] C -->|"Click link"| D D --> E D --> F E --> G F --> G G --> H H --> I end B -.->|"SendGrid email"| C

Key Concepts to Understand

  • Provisioned Account ≠ Candidate Account: A provisioned account is a placeholder created by the recruiter. It becomes a real candidate account only after the candidate claims it. Before that, all data is keyed to the placeholder.

  • Interview Notes Are Recruiter-Only: Anything the recruiter writes in the interview notes field is stored as recruiter data. Candidates never see these notes. They're used for search indexing and context.

  • Anonymity Is a Preference, Not a Separate State: The candidate's profile isn't inherently "anonymous" — they choose whether to appear de-anonymized (full profile visible to specific HMs) or anonymized (general matching until mutual interest). This is saved as their preference.

  • Candidate Still Has Control: Even though the recruiter pre-populates everything, the candidate can edit preferences, change their Qwestly card, upload a different resume, and choose their anonymity setting before publishing. Nothing is final until the candidate hits Publish.