Techfluenced logoTechfluenced
← Interview Prep Agent

Field notes

How it's made

An agent that turns a resume and a job description into a mock interview, then reviews your recorded answers. Here's the stack underneath it, and the bugs that stood between working code and a working demo.

Claude CodeAuth0VercelSupabaseOpenAI gpt-4o-miniOpenAI gpt-4o-transcribeOpenAI gpt-4oNext.js 16 · App RouterTypeScriptTailwind CSS v4

Components

Login

Email and password via Auth0, further gated to admins only — this demo spends OpenAI credits per session, so it isn't open to anyone who signs up.

Resume template

The resume you use is saved to your profile and pre-filled next time, so you don't retype it — edit or replace it for any session and that becomes the new saved copy.

Questions

Your resume and the job description go to gpt-4o-mini, which returns six tailored questions mixing behavioral, technical, and role-specific angles.

Recording

Each answer is recorded in the browser with MediaRecorder, transcribed by gpt-4o-transcribe, and shown back to you to correct before moving on.

Review

Once every question's answered, the full transcript goes to gpt-4o, which returns per-question talking notes and feedback, plus bullet-point takeaways on what worked and how to improve.

Redo

A completed session can be redone with the same six questions. Redoing clears the previous transcripts and feedback in place, so only the latest attempt is ever kept, not stacked as history.

Bugs & fixes

In the order they were found.

01

Lint rejected the session-list fetch

Fixed
Avoid calling setState() directly within an effect (react-hooks/set-state-in-effect)
Cause
The initial fetch of past sessions was a reusable loadSessions() function called from useEffect, and the lint rule won't allow calling anything that sets state directly from an effect body.
Fix
Inlined the initial fetch as a self-contained async block guarded by a cancelled flag — the same pattern Dream Tracker already used — and kept loadSessions() only for manual refreshes triggered by user actions.
02

Tables didn't exist yet

Fixed
Could not find the table 'public.interview_sessions' in the schema cache
Cause
The SQL to create interview_sessions and interview_questions hadn't been run against the Supabase project yet.
Fix
Walked through creating both tables in the Supabase SQL editor, step by step.
03

Logout redirected to an error page

Fixed
invalid_request: The "post_logout_redirect_uri" querystring parameter is not defined as a valid URL in "Allowed Logout URLs".
Cause
Auth0 checks the logout redirect against a per-application allowlist, and only Dream Tracker's path had been added there.
Fix
Added this demo's own path to Allowed Logout URLs in the Auth0 application settings.
04

Overall feedback still read as one paragraph

Fixed
Cause
The model was asked for bullet-point arrays but kept writing one long run-on sentence per element instead of short, single-idea bullets — and sessions reviewed before the prompt was fixed had that paragraph already saved.
Fix
Rewrote the prompt with an explicit good/bad example enforcing short single-idea bullets, and added a “Regenerate as bullet points” action so already-completed sessions could be re-reviewed without redoing the interview.
05

Welcome message showed the email, not the name

Fixed
Cause
Auth0's default name claim mirrors the account email for this connection type. Dream Tracker had already solved this with a custom name claim sourced from user_metadata, but this demo was reading the default claim instead.
Fix
Reused Dream Tracker's custom name claim, pulling it from a shared NAME_CLAIM constant instead of duplicating it per demo.