Resource library

QA Career

Track QA Applications From Evaluation to Offer

Learn to track QA applications from evaluation to offer with clear statuses, event history, saved reports, follow-up cues, and pipeline decisions.

20 min read | 3,892 words

TL;DR

Save each evaluated QA role as one evidence-rich record, then update its status only when a real event occurs. QAJobFit keeps the evaluation report beside the current stage, attempts to record every transition, marks due follow-ups, and stores each signed-in user's pipeline behind owner-only database policies.

Key Takeaways

  • Save one evaluated posting as one application record so its report, score, legitimacy result, and job details stay together.
  • Use evaluated, applied, responded, interview, offer, rejected, and discarded as distinct evidence states rather than vague labels.
  • Treat the first applied timestamp and every status event as an audit trail for what happened and when.
  • Use responded for employer contact and interview only after an interview step is scheduled or underway.
  • Read the due marker as an action cue, while keeping lifecycle state separate from reminder state.
  • Rely on owner-scoped database policies, status checks, foreign keys, and cascade cleanup to protect pipeline integrity.

To track QA applications from evaluation to offer, save each evaluated role as one pipeline record, transition it through a consistent status set, preserve every transition as an event, and act on due follow-ups. Keep the score, legitimacy result, job description, and report attached so each decision remains evidence-based.

A useful tracker should answer three questions without a hunt through old mail. What did you learn, what took place, and what must you do next? QAJobFit maps those needs to one job application record, a set of status events, and due tasks.

Why Track QA Applications From Evaluation to Offer?

A job search yields far more evidence than one spreadsheet entry can hold. You may weigh the tool stack, role level, compensation, trust signs, resume gaps, and likely interview topics. If that work is lost after you act, the next decision has no clear base.

The goal is not to build the largest list. Keep one clear case file for each post, with the facts that led to your decision. CareerOneStop groups its official job search guidance around plans, job forms, rounds, and offers, so a staged work log fits the task.

This model helps when you evaluate openings from companies hiring QA engineers. Two posts may share a name yet ask for a different stack, level, or type of test work. A saved report lets you compare those facts before you spend time on a new resume or a mock interview.

QAJobFit starts an application record at evaluated, not applied, so a job can stay in view before you commit. The QA job tracker keeps the report close as the stage shifts. That split is why you track QA applications from evaluation to offer, not just the forms you sent.

Think of each application record as a small case file for one real job post. The score says how well the role fits, while the legitimacy badge shows a different kind of concern. The saved text and report show why those two marks were set.

What Should a QA Job Application Tracker Record?

A QA job application tracker needs four layers: job facts, evaluation facts, current status, and follow-up activity. The shared types in jobTracker.ts set the shape used by the hook and the view.

  • Job facts: JobApplicationRow keeps company, role title, job URL, source channel, job text, compensation text, and key dates.
  • Review facts: The application record keeps score, trust tier, final decision, and the full EvaluationReport as JSON data.
  • Report depth: That report holds five score blocks, strengths, hard and soft gaps, compensation context, resume edits, likely interview questions, trust signs, hard stops, and the next act.
  • Current status: The application record stores one of seven status values, plus its first applied time and last update time.
  • Due work: JobFollowUpRow links a due date, task kind, done time, and note to the same job.

Keep resume work tied to the saved facts. Use the gap list while you tailor your QA resume to the job description, and keep each claim true. Do not replace the job text with a broad note such as test role, since the source text helps with later prep.

The data store splits the current application record, past transitions, and follow-up activity into three records. Each record has one clear job, so a status transition does not erase the report.

Record Main purpose Important fields What it retains
job_applications Current job application record and saved evaluation Company, role, URL, score, trust tier, decision, status, report, compensation, applied time The latest stage and full report
job_application_events One event record for each status transition Job ID, user ID, old status, new status, note, event time A time-based trail of status changes
job_follow_ups Due work tied to a job Due date, kind, done time, note Open and done task status

The split helps you read a stalled application record with care. The stage can show that the employer replied, while the due cue can show that you still owe a note. The report then shows which claims and gaps should guide that note.

Which QA Application Pipeline Stages Are Canonical?

The canonical QA application pipeline stages are set once in jobTracker.ts. The same file gives the status type, the list order, and the text shown in the picker.

  • evaluated means a role evaluation has been saved, but no sent form is implied.
  • applied means you sent the form through the real employer or job site.
  • responded means the employer side sent a useful reply or asked for a next step.
  • interview means a live, phone, video, take-home, or panel step is set or in flight.
  • offer means you have a real offer to assess, not a vague hint from a recruiter.
  • rejected means the employer closed the path at any point in its hiring flow.
  • discarded means you chose to stop the work and no longer seek that role.
export const APPLICATION_STATUSES = [
  'evaluated',
  'applied',
  'responded',
  'interview',
  'offer',
  'rejected',
  'discarded',
] as const;

The SQL file has the same seven values in a CHECK rule. PostgreSQL says a check constraint blocks an application record when its rule is false. An unknown status should fail at the data layer even if a client skips the normal picker.

Stage Proof for entry Next act Due-work effect proved here
Evaluated A QAJobFit report was saved Decide if the job is worth the time No exact time rule appears in the four article sources
Applied The form was sent and confirmed Save evidence and watch for a reply A status helper may create follow-up rows
Responded The employer or recruiter wrote back Pin down the next step and date A follow-up record can later show the warning dot
Interview An interview is booked or active Prep from the saved report A status helper may create thank-you work
Offer Written or clear offer terms arrived Check compensation, scope, and terms Open follow-up activity may be closed
Rejected The employer ended the path Save the result and note lessons Open follow-up activity may be closed
Discarded You chose to stop Save the cause and cease active work Open follow-up activity may be closed

The code comment shows the usual flow from evaluated through applied, responded, and interview. It then branches to offer or rejected, while discarded can be reached near the start. The same comment allows both forward and backward moves, and the picker shows all seven choices.

This freedom helps with a wrong click, an employer that reopens a role, or an extra interview added late in the process. It also means the app will not stop a transition that makes little sense. Before you transition an offer back to interview, use the QA engineer salary guide and the employer's note to check why the stage changed.

Use a fact test when two states seem close. Ask what new event took place, who caused it, and which task now comes next. If you cannot name that event in one short line, wait before you change the application record.

How Does Evaluation Become a Saved Application?

The insertFromReport function in use-job-tracker.ts turns a report into a stored application record. It first checks for a signed-in user, and it returns null when no user is present.

  • It trims the employer and role names, then uses Unknown company or Unknown role if either is blank.
  • It stores the job URL when one is present and keeps the full job text as jd_text.
  • It copies the score, trust tier, final decision, full report, and shown compensation from the report.
  • It sets the first status to evaluated, then inserts the application record and asks for the saved result.
  • It tries to add a first event from null to evaluated after the application record exists.
const applicationPayload = {
  user_id: user.id,
  company: report.company?.trim() || 'Unknown company',
  role_title: report.roleTitle?.trim() || 'Unknown role',
  job_url: jobUrl?.trim() || null,
  jd_text: jdText,
  score: report.globalScore ?? null,
  legitimacy_tier: report.legitimacy?.tier ?? null,
  final_decision: report.finalDecision ?? null,
  status: 'evaluated',
  report,
  advertised_comp: report.comp?.advertised ?? null,
};

The application record and first event are two calls, not one all-or-none call in the hook. If the event call fails, the application record stays saved and a warning says the history item was not made. The new application record is still placed at the top of local state.

To save QA job evaluation report data, open the job tracker workspace and check the employer, role, score, legitimacy badge, and report button. A gray report button means that application record has no report to open. An active button opens the saved report in a side sheet.

Next, use the report's true gap list in the QA resume tailoring workflow. Keep the application record at evaluated while you decide and write. A polished resume is not evidence that the form was sent.

When Should Evaluated Move to Applied?

Move a role from evaluated to applied only after you send the form through the employer's true channel. A saved evaluation is not a submission, and QAJobFit does not send the resume for you. The status change should match evidence such as a receipt, sent-mail copy, or portal screen.

This makes the evaluated to applied status change useful. CareerOneStop's official apply for jobs guidance tells job seekers to record the posts and firms they contact. Here, the application record and its first applied time serve that need.

When updateStatus gets applied, it writes the new status and update time. It also writes applied_at if that field is blank. A later transition does not clear it, and a return to applied does not replace the first saved time.

Use a three-part evidence check before the transition. Make sure the form reached the right employer, the sent resume fits the saved job text, and the receipt has the right role. The company research guide can help with the employer check, but your sent evidence is what sets the status.

Do not use applied for a task that sits in a draft folder. Leave it at evaluated until the last send step is done. If you choose not to send it, discarded tells the truth and keeps your active count clean.

How Do Responded and Interview States Differ?

Responded means the employer side made real contact after you applied. Interview means a named interview is booked, active, or done while the hiring path stays open. The gap between them keeps a short mail reply from looking like a full interview.

Use these rules when you track QA interview progress. Each rule ties the status to a clear recruiting event:

  • A receipt that only says the form was received does not need a transition to responded.
  • A recruiter question about notice time, compensation, location, or work rights fits responded.
  • A request to pick a screen time stays responded until the time is set, based on your chosen rule.
  • A booked HR screen, code task, tool interview, panel, or manager call fits interview.
  • A post-interview note does not need a new status when the job is still in interview.

Prepare once a real step is known. Open the saved report, choose the gaps most likely to be tested, and use the QA interview preparation workspace for focused work. A broad prep list can wait until the role and interview are clear.

PipelineTable.tsx keeps the same core facts in both screen modes. These display rules keep the two layouts aligned:

  • The wide table shows employer, role, score, trust badge, status, added date, and report action.
  • The narrow view uses stacked cards, so the status picker does not get crushed into a small cell.
  • A job link appears only when job_url has a value, and it opens in a new tab.
  • The score shows one decimal place, while known trust tiers show Legit, Caution, or Suspicious.
  • The report action is off when no report object exists and opens a side sheet when one does.

The Added date comes from created_at, not applied_at or the last event. It tells you when the application record was first saved. It cannot tell you when the employer wrote back or when an interview took place.

When a mail thread is not clear, keep the old status until the next step is plain. A short note that says we will be in touch may show interest, but it gives no booked interview. A calendar invite with a date and host is much stronger evidence.

What Should QA Application Status History Preserve?

QA application status history should keep the old status, new status, event time, owner, parent job, and a useful note. The SQL table job_application_events has fields for each part. Its job key also uses cascade delete, so its rows go when the parent application record is removed.

The status path in updateStatus works in this order. Each step has its own write or test:

  • Stop with success when the old and new status are the same, so no duplicate event is made.
  • Patch status and updated_at, plus the first applied_at value when that rule applies.
  • Insert an event with from_status, to_status, and a trimmed note or null.
  • Ask the follow-up activity helper for tasks tied to the new status, then insert any rows it returns.
  • Close open follow-up activity when the close helper says the new status ends that work.
  • Reload the tracker after a full success or after any caught error.

There is a clear limit in the current view. PipelineTable.tsx sends the job and new status to its handler, but it does not ask for a note. It also does not fetch event rows, so the table is a view of the present status, not a full trail.

Use the pipeline view to see the status and reopen the report. Do not cite that screen as evidence of each old transition. The data model can hold the trail, but this part of the view does not show it.

The writes run one after the next in the hook. A status patch can work before the event call fails, so the catch path may load an application record that has in fact moved. Check the application record before you click the same status again.

A clean trail logs facts, not every mail read or page view. Moves such as responded to interview or interview to offer tell a clear story. Small tasks belong in follow-up activity, while deep notes need a view that can save and show them.

Use a quick fault check when an error toast appears. First, read the status that came back after reload. Next, check whether the due dot changed, and only then decide if another action is safe.

How Do Follow Up Indicators Support the Pipeline?

QA application follow up indicators tell you that work is due, not that a new stage was reached. On load, useJobTracker asks for open due rows with a date of today or before. It sorts them by due date and builds a set of their parent job IDs.

PipelineTable.tsx checks that set for each application record. A match adds a small dot by the employer name, with screen-reader text that says Follow-up due. The dot does not show the date, task kind, note, or age of the task.

  • job_follow_ups.kind allows only follow_up or thank_you.
  • done_at is blank while the task is open and gets a time when it is done.
  • updateStatus asks followUpsForTransition for tasks tied to the new status.
  • The exact day offsets are not in the four source files approved for this guide.
  • closeOutFollowUps can mark all open tasks done when its rule matches the new status.

Keep the cue and status apart. A due thank-you note can sit on an application record that is still in interview, so the note should not force a false transition. A due follow-up can also sit on an applied application record while you wait for the employer.

Use the dot as a prompt to read the application record and choose the right action. Pay questions can be checked with the QA compensation guide, while interview prep belongs in the prep tool. Marking a task done and changing a status should each reflect its own fact.

If many dots appear, sort your work by the due item and the worth of the role. Send the note that has a clear aim, such as asking for a date or thanking a panel. Do not send a blank check-in just to clear a mark.

Step by Step: Track QA Applications From Evaluation to Offer

The safest way to track QA applications from evaluation to offer is to transition an application record only when new evidence arrives. The steps below do not assume mail sync, auto-submit, or a screen that shows the full event trail.

  1. Review the exact post, including its full job text, employer, role, URL, score, trust result, and final decision.
  2. Save while signed in, then check that the application record appears at evaluated with a report you can open.
  3. Read the report and make only the resume changes that its gap and edit notes support.
  4. Send the form through the employer's stated route, keep the receipt, and then transition the application record to applied.
  5. Use responded when the employer asks for a real next step, then learn whether it is a screen, task, or booking request.
  6. Move to interview once an interview is set, and prep from the job facts rather than a broad list.
  7. Act on each due cue, while keeping task completion apart from the status picker.
  8. End with offer, rejected, or discarded only when the right side has made that decision.

This sample uses dates only to show how the records fit. It does not claim a normal hiring speed or set a follow-up activity rule.

Sample date Current status Event to keep Report use and decision
July 28 Evaluated First event from no old status to evaluated Read the Playwright gap and legitimacy signs before you act
July 30 Applied Evaluated to applied after a sent receipt Keep the sent resume tied to the saved job text
August 2 Responded Applied to responded after recruiter mail Ask if the next step is a screen, task, or interview
August 5 Interview Responded to interview after a panel is booked Reopen likely questions and plan evidence-based answers
August 8 Interview No status transition just for a thank-you task Do the task without making a false stage change
August 12 Offer Interview to offer once true terms arrive Check compensation, scope, start date, and open terms

The report stays useful at each point. Use its edit plan with the job-description resume guide, then use its likely questions in Interview Prep. Both acts draw from the same saved job facts.

After each transition, wait for the toast and read the application record after reload. The hook may save the status before a later event or follow-up activity call fails. That check stops you from making a second transition that hides what first took place.

How Should Rejected and Discarded Be Used?

Use rejected when the employer ends the path. That can occur after a form evaluation, screen, task, interview, or offer talk. The status tells who closed the path, though it does not hold the cause by itself.

Use discarded when you choose to stop. The cause may be poor fit, weak trust signs, low compensation, a role change, or a better use of your time. The QA hiring company guide can aid the decision, but the status must match your own act.

Neither status is locked for all time. The picker still offers all seven values, and the type note allows both forward and back moves. If an employer reopens a rejected path, you can set the true status and let the next event hold that transition.

Do not use rejected just because an employer has been quiet for a set count of days. A silent role can stay applied or responded while a task comes due. Do not use discarded merely to hide a low score, since that report may show a gap worth work.

Closed rows can still teach you which tools, claims, and compensation bands come up most. Keep the report when that insight has value. Delete the application record only when you also mean to remove its linked events and due tasks.

An offer may also end with discarded if you turn it down. Use offer while you weigh real terms, then choose the status that best tells what came next. The current type has no accepted or declined status, so do not claim that it does.

How Does Owner-Only Storage Protect Pipeline Data?

The migration 20260715120000_add_job_tracker.sql gives all three tables a user_id and Row Level Security. Select, insert, update, and delete policies compare auth.uid() with the value on the row being accessed. Supabase's official Row Level Security guide says auth.uid() is null without a signed-in user, so that comparison fails for a guest. These are per-row access rules, not a cross-table ownership guarantee.

The application owner references auth.users. Event and follow-up rows reference an application through application_id, with cascade deletion, but no constraint requires their user_id to match the parent owner. The foreign keys prove that the parent exists and clean up children after deletion; they do not prove owner consistency between those rows.

Other constraints keep scores and enum-like fields within allowed values, required fields non-null, and updated_at current. Indexes support owner, status, creation-time, and open-due-date reads. The hook also requires sign-in and filters application loads by user ID in the signed-in tracker route.

The policies do not make the hook's writes atomic. A status patch can succeed before an event or follow-up request fails, so reload the application before retrying. Deleting an application also removes linked events and reminders; that referential cleanup is separate from owner matching.

Conclusion: Maintain a QA Offer Pipeline Workflow

A sound QA offer pipeline workflow keeps job facts, current status, old transitions, and follow-up activity in their own places. Save first, mark applied after a true send, use responded for employer contact, and use interview for a real interview. Close with offer, rejected, or discarded when the facts fit.

Use the report to explain each decision, not just to add a score chip. Check the application record after an error since the status, event, and follow-up activity writes run in a set order. That care lets you track QA applications from evaluation to offer without false progress or lost context.

For each live application record, know the next act and the evidence that will cause the next transition. When no next act exists, decide if the application record is still live. A small, true board is more useful than a large board full of stale hope.

Prepare evidence for active interview-stage roles in QAJobFit Interview Prep. Then return to the QA application tracker after each real milestone so the status and next act stay true.

Interview Questions and Answers

How would you model a QA application pipeline?

I would separate the current application row from append-oriented status events and actionable follow-ups. The current row supports fast pipeline reads, while events preserve transitions and reminders represent due work. I would constrain status values and apply owner-based access policies at the database layer.

Why should evaluated and applied be separate statuses?

Evaluated means the candidate has analyzed and saved a role, while applied means an external submission actually occurred. Keeping them separate prevents research inventory from inflating active application counts. It also lets the first applied timestamp represent a real submission event.

What race or consistency risk exists in the status update flow?

The application update, event insert, reminder insert, and reminder closeout are separate requests. An early write can succeed before a later request fails. I would reload after failure, surface partial completion clearly, and consider a database transaction or RPC if atomic behavior became a requirement.

How does the current tracker protect one user's data from another?

Each table applies Row Level Security to select, insert, update, and delete by comparing `auth.uid()` with that row's `user_id`. This is per-row access control. The migration does not constrain an event or follow-up `user_id` to equal its parent application's owner, so I would not claim cross-table owner consistency.

How would you test the applied timestamp behavior?

I would move an evaluated row to applied and assert that `applied_at` is set. Then I would move it to another status and back to applied, asserting that the original timestamp remains unchanged. I would also test an already populated field and a failed update response.

What would you verify in the responsive pipeline interface?

I would verify that wide and narrow layouts show the same company, role, score, legitimacy, status, date, due cue, and report availability. I would test status changes, disabled report controls, long text truncation, accessible labels, optional job links, and the report sheet on keyboard and touch input.

How would you test owner-only pipeline policies?

I would create two authenticated users and test every operation against rows carrying each user ID, plus unauthenticated access and ownership-changing updates. I would separately test deliberately mismatched child and parent owners, because current foreign keys validate `application_id` but do not enforce owner equality across tables.

Frequently Asked Questions

What status should a newly saved QA job evaluation use?

A newly saved evaluation should use `evaluated`. The `insertFromReport` function creates that status and attempts an initial event from no prior status to evaluated. It does not mark the role applied, because saving research and submitting an application are separate candidate actions.

When does QAJobFit set the applied timestamp?

The tracker sets `applied_at` when `updateStatus` first moves a record to `applied` and the field is still empty. Moving away from applied does not clear it. Returning later does not replace it, so the field preserves the first recorded application time.

Can an application move backward in the QA pipeline?

Yes. The shared type comment permits forward and backward moves, and the status selector offers all seven values for every record. Use that flexibility for genuine corrections or reopened processes. Avoid toggling states as reminders because each meaningful move is intended to create a history event.

Does the pipeline table display complete application history?

No. `PipelineTable.tsx` displays the current status, added date, score, legitimacy badge, job link, due marker, and saved report control. Status events are stored in a separate table, but this component does not query or render them as a visible timeline.

What does the follow-up dot beside a company mean?

The dot means the application has at least one unfinished follow-up whose due date is today or earlier. It does not identify the reminder kind, show the date, or change the application status. Treat it as an action cue, then inspect the related workflow before responding.

What is the difference between rejected and discarded?

Use rejected when the employer ends the candidacy, and use discarded when you choose to stop pursuing the role. Both are selectable outcomes rather than permanent locks. Keeping the distinction consistent helps later review separate employer decisions from candidate prioritization and risk choices.

Is a saved evaluation report protected per user?

The migration enables Row Level Security on applications, events, and follow-ups. Each policy compares `auth.uid()` with that row's own `user_id`, and the client requires sign-in. The child foreign keys validate `application_id` but do not require a child's owner value to match the referenced application owner.

What should I verify after a status update error?

Reload or inspect the application before retrying. The hook updates the application, inserts an event, creates any transition reminders, and closes relevant reminders through separate requests. A later request can fail after the status write succeeds, so an immediate retry could create a misleading extra transition.

Related Guides