WorkWingman — Interview Prep Bank (Technical)¶
Pre-interview prep content for a job: behavioral/leadership STAR question bank, questions the
candidate should ask the interviewer, "what you bring" reflection prompts, and curated external
prep resources — all matched to the job's inferred role track. Built entirely from curated,
hand-written content plus local string matching against the job's own FitAssessment and the
user's StoryProfile. No network calls happen to build a bank — this sits alongside
Study & prep (which does call out to search engines/course platforms) as the
"prep for the room" counterpart to "prep for the take-home."
Model¶
public class InterviewPrepBank
{
public string JobId { get; set; }
public List<BehavioralQuestion> BehavioralQuestions { get; set; }
public List<CandidateQuestion> QuestionsToAsk { get; set; }
public List<string> WhatYouBringPrompts { get; set; }
public List<PrepResource> ExternalResources { get; set; }
public RoleTrack RoleTrack { get; set; }
}
RoleTrack is SoftwareEngineer | ProductManager | EngineeringManager | SeniorLeadership — the
four interview tracks the curated content is organized around.
Role-track inference¶
InterviewPrepBankService.InferRoleTrack
is a pure public static function (same testable-helper pattern as AtsDetector) that maps a
JobPosting.Title string to a RoleTrack via lowercase substring matching:
public static RoleTrack InferRoleTrack(string jobTitle)
Priority order matters: senior-leadership titles ("VP", "Director", "CTO", "Head of Engineering")
are checked before "engineering manager" / "manager" substrings, so "Director of Engineering"
resolves to SeniorLeadership, not EngineeringManager. Anything that doesn't match a more
specific track — including an empty/null title — defaults to SoftwareEngineer, the most
universal bank and the safest fallback.
Behavioral/leadership question bank¶
InterviewPrepBankService.CuratedBehavioralBank() returns the full hand-curated bank of
BehavioralQuestion records, each tagged with:
Theme— one of six STAR themes:ProudestWork,HardestChallenge,ConflictOrDisagreement,FailureAndLearning,LeadershipOrInfluence,Ambiguity. Every theme has at least one universal (all-role-track) prompt plus role-specific variants.RoleTracks— which of the four tracks a prompt applies to.GetPrepBankAsyncfilters the full bank down to only the prompts tagged with the job's inferred track.Key— a stable string (e.g."proudest-build","failure-and-learning") chosen to matchStoryPrompt.Keyvalues already seeded onStoryProfile(src/WorkWingman.Core/Models/StoryProfile.cs).
Linking to the user's own stories: after filtering by role track,
InterviewPrepBankService loads the user's StoryProfile (via IProfileService.GetStoryAsync)
and, for every behavioral prompt whose Key matches an answered StoryPrompt.Key, sets
BehavioralQuestion.LinkedStoryPromptKey. The UI uses this to show "you already have a story for
this" instead of a cold blank prompt — turning story-writing (Your story feature) and interview
prep into the same underlying content instead of two disconnected chores. An unanswered or
missing story prompt leaves LinkedStoryPromptKey as null — never a guess.
Questions the candidate should ask¶
InterviewPrepBankService.BuildQuestionsToAsk() returns a fixed, curated list of
CandidateQuestion records (these don't depend on the JD — the questions an interviewer should
be asked are the same regardless of the specific job), grouped by
CandidateQuestionCategory:
| Category | Example |
|---|---|
RoleAndBackfill |
"What happened to the person previously in this role — is this a backfill, or a growth/new position?" |
ProcessAndTimeline |
"What does the interview process look like from here?" |
SuccessMetrics |
"What does success look like in this role after 6 months? After 12 months?" |
TeamAndOnboarding |
"What does onboarding look like for the first 30/60/90 days?" |
FeedbackElicitingCloser |
"Is there anything about my background that gives you hesitation I could address right now?" |
Every CandidateQuestion carries a WhyAsk field — supportive coaching copy explaining what the
question surfaces, never a guilt-trip about "you should be asking this." Three questions are
flagged IsNonObvious = true — the feedback-eliciting closers most candidates never think to ask
— and the UI renders them in a distinct "takes a little nerve" callout rather than mixed in with
the routine process questions.
"What can you bring" reflection prompts¶
InterviewPrepBankService.BuildWhatYouBringPrompts(FitAssessment fit) derives reflection prompts
directly from the job's own Fit.MatchedKeywords and Fit.GapKeywords
(JobPosting.cs) — the same fields
StudyPlanService already uses to build study resources:
- For each matched keyword: "The JD calls out
"{kw}"and it's already a strength of yours — what's a specific, concrete example of you using it that you can walk through in under two minutes?" - For each gap keyword: "The JD mentions
"{kw}"and it's not a strong area yet — what's the closest adjacent thing you've done, and how would you frame your ability to ramp up on it quickly?" - Empty-safe: with zero matched and zero gap keywords, a general fallback prompt is used instead of returning nothing.
- A final prompt — "Beyond the skills on the JD, what do you bring that most candidates for this role wouldn't?" — is always appended, so the reflection never stops at "match the keywords back to the interviewer."
Curated external resources¶
InterviewPrepBankService.CuratedResourceLibrary() returns the full set of PrepResource
records; GetPrepBankAsync filters to only the resources tagged with the job's RoleTrack via
PrepResource.ForRole. Every resource was checked live (via a direct fetch or a corroborating
web search showing a current, recently-updated page) before being added here:
| Name | URL | For role | What it offers |
|---|---|---|---|
| Exponent — tech interview prep (YouTube) | https://www.youtube.com/@tryexponent | PM, EM, SWE | Free mock interviews and prep videos for product management, engineering management, and software engineering interviews at major tech companies (472K subscribers). |
| Exponent — Engineering Manager Interview Guide | https://www.tryexponent.com/blog/how-to-prepare-for-an-engineering-manager-interview | EM, Senior Leadership | A written walkthrough of the EM interview process end to end — system design, people management, project retrospectives, behavioral rounds — with company-specific notes. |
| IGotAnOffer — Engineering Manager Interview Questions | https://igotanoffer.com/blogs/tech/engineering-manager-interviews | EM, Senior Leadership | 40+ engineering manager interview questions with answer techniques, written by ex-interviewers; last updated June 2026. |
| MIT Career Advising — The STAR Method for Behavioral Interviews | https://capd.mit.edu/resources/the-star-method-for-behavioral-interviews/ | All tracks | A university career-center guide to structuring behavioral answers with the STAR method, plus a worksheet for building your own stories. |
| The Muse — STAR Interview Method | https://www.themuse.com/advice/star-interview-method | All tracks | A practical, example-driven guide to the STAR method with sample answers to pattern-match against. |
A Fortune engineering-leadership interview article was considered and dropped. No live, citable Fortune article specifically about engineering-leadership interview questions could be found — the closest candidate URLs 404'd, and Fortune's own "interview questions" tag page carries general hiring-practice pieces, not an engineering-manager-specific guide. Rather than cite a dead or off-topic link, it was replaced with the two verified EM-specific guides above (Exponent, IGotAnOffer). If a genuine Fortune engineering-leadership piece is published later, swap it back in here.
PM-specific channels beyond Exponent were evaluated and not added. Several candidate PM YouTube channels either 404'd on direct fetch or couldn't be independently corroborated as still active during this pass; rather than guess, the PM track currently relies on Exponent (confirmed live and PM-focused) plus the two universal STAR guides. Revisit and expand when a new candidate can be verified live.
Wiring¶
Registered in Program.cs as a plain singleton, same as
every other domain service:
builder.Services.AddSingleton<IInterviewPrepBankService, InterviewPrepBankService>();
InterviewPrepBankService depends on IJobQueueService (to load the job) and IProfileService
(to load the StoryProfile for linking) — no new persistence: nothing about the prep bank itself
is saved to disk, since it's cheap to rebuild deterministically from the job + story profile on
every request.
API: InterviewPrepController
exposes a single read endpoint:
GET /api/interview-prep/{jobId} -> InterviewPrepBank
Frontend: surfaced inside the existing Study & prep
feature (frontend/src/app/features/study/study.ts/.html) rather than as a new nav item — an
"Interview prep" section renders below the existing study-resource grid for the currently
selected job, matching the same job-tab selector. ApiService.getInterviewPrepBank(jobId)
(frontend/src/app/core/api.service.ts) is the typed client call. All four sub-sections
(behavioral questions, what-you-bring prompts, questions to ask, curated resources) render
@empty fallbacks — picking a job with no plan yet, or a prep bank with an unmatched role track,
never renders a blank/broken section.
Tests¶
InterviewPrepBankServiceTests.cs— role-track inference (including the Director-of-Engineering priority case and case- insensitivity), behavioral-bank role filtering per track, everyBehavioralThemerepresented, StoryProfile linking (answered/unanswered/no-match), questions-to-ask content (backfill question, timeline/success-metrics questions, the non-obvious hesitation closer, every question has a non-emptyWhyAsk), what-you-bring derivation from matched/gap keywords (including the empty-safe fallback and the always-present "beyond the JD" prompt), external-resource role matching, and the unknown-jobKeyNotFoundExceptionpath.- Frontend:
study.spec.tscovers the newprepBanksignal load,roleTrackLabel(), thequestionsToAsk()/nonObviousClosers()split,themeLabel()/categoryLabel()mapping, the empty-safe case, and thatselect()refreshes the prep bank for the newly chosen job. - Bogus/faker test data is reused from the existing
TestData.JobFaker/TestData.StoryFakerbuilders (TestData.cs) — no new fakers were needed since the service only reads existingJobPosting/StoryProfileshapes. - Mutation testing: covered by the existing
**/Services/*.csglob instryker-config.json(no new folder was introduced, so no config change was needed) and the frontend'ssrc/app/**/*.tsglob instryker.conf.json.
Related docs¶
- Plain-language version: ../plain/interview-prep-bank.md
- job-signals.md — the JD keyword matching this feature reuses
- Doc index: ../README.md