Hirely-job: The Job Portal That Refuses to Let AI Failure Break the Interview Prep Flow

A MERN-based hiring app that pairs resumes with job descriptions, then falls back to keyword-driven questions when Gemini is unavailable.

7 min read • View on GitHub • More from kARUn077

A wide editorial scene shows a resume and job description laid side by side on a desk, with an interview prep workflow branching toward two paths. One path is labeled by the viewer’s eye as an AI-assisted route, while the other continues as a simpler deterministic route, showing that the product keeps working when model calls fail. It explains the article’s core idea: resilience is the feature, not an accident.
The strongest feature is not the model call. It is the fallback path that keeps interview prep alive when the model does not cooperate.
Key Takeaways

When the LLM Fails, the Product Still Works

Most AI job tools advertise intelligence and quietly assume the model will cooperate. Hirely-job makes a different bet. It assumes the model can fail, and it still keeps the interview-prep experience moving.

That is the real story here. The app is not just a job board with a Gemini call bolted on. It is a hiring workflow that treats AI as one layer in a larger system, not the system itself.

That choice matters because interview prep is a high-friction moment. A broken model response should not strand the user at the most stressful point in the flow.

The Interview Engine Is the Real Product

The core flow starts with a resume PDF and a job description. The backend uses pdf-parse to extract the resume text, then sends that text plus the role details into an interview-plan generator.

The system is designed around branching outcomes, not a single happy path. The useful output is the same final shape whether Gemini succeeds or the fallback logic takes over.

async function createInterviewPlan(req, res) {
  const resumeBuffer = req.file.buffer;
  const resumeText = await pdfParse(resumeBuffer);

  try {
    const plan = await generateInterviewPlan({
      resumeText: resumeText.text,
      jobDescription: req.body.jobDescription,
    });

    return res.json({ success: true, plan });
  } catch (error) {
    const fallback = fallbackQuestionSet(req.body.jobDescription);
    return res.json({ success: true, plan: fallback });
  }
}

That compact shape is the point. The controller does not promise perfection. It promises continuity. If the model response is available, great. If not, the app still returns a usable interview plan.

The Fallback Is Smarter Than a Generic Error

The fallback path is not a dead end or a canned apology. The repo’s research shows a keyword pipeline built around stop-word removal and frequency analysis. That means the app can still surface useful interview prompts from the job description even when the model is offline or rate limited.

This is defensive AI product design in practice. The system shifts from probabilistic generation to deterministic heuristics, and the experience stays intact.

ApproachInputFailure modeUser value
Generic job portalResume and job descriptionStops at browsing or a blank formLow, because it does not help with preparation
Brittle AI assistantResume and job descriptionBreaks when the model errorsHigh when healthy, zero when unhealthy
Hirely-jobResume, job description, and keyword fallbackDegrades to heuristic generationConsistent, because the flow still produces a plan

That fallback logic also changes the product story. The app is not trying to prove that AI is magical. It is proving that useful software can survive the normal messiness of model APIs.

Two Users, Two Products

Hirely-job is built for two distinct roles: students and recruiters. That split is not cosmetic. It shapes access, routes, and what each person can do once they are inside the app.

The auth flow reinforces that boundary with role checks, HTTP-only cookies, and controller-level enforcement. In practice, the app behaves like two products sharing one codebase.

DimensionStudent flowRecruiter flow
Primary taskBrowse jobs and prepare for interviewsPost jobs and manage applications
Core valueReduce interview anxietyFilter and track candidates
Access controlRole-checked user sessionAdmin-style permissions
Success stateA prepared interview planA clean hiring pipeline

That is a good product shape for a compact repository. It keeps the UI coherent while still acknowledging that applicants and recruiters need different tools and different trust boundaries.

A MongoDB App With Relational Habits

The schema design is MongoDB-native, but the relationships are deliberately relational in spirit. Jobs point to companies and creators, applications point back to jobs, and interview plans store structured output rather than loose blobs.

A close-up illustration shows several linked data cards arranged like a small network. Job, company, user, application, and interview plan nodes are connected by thin lines, showing a graph that behaves like a relational system inside MongoDB. It explains how the app preserves structure across hiring workflows without leaving the document model.
The data layer reads like a graph of hiring objects. It is document-based, but it thinks in relationships.

That is convenient because Mongoose can hydrate the right view with populate(). It is also where scale questions start to show up. The same convenience that makes the app feel simple can become a bottleneck if the data volume grows sharply.

Still, for an MVP-sized hiring product, the trade-off is sensible. The model matches the workflow, and the code stays legible.

The Stack Says MVP, the Execution Says Polished

The frontend stack is the kind of stack you see in serious product prototypes: Vite, React, Redux Toolkit, Tailwind, Shadcn UI, Lucide, and Cloudinary. Nothing here is exotic. The value is in the assembly.

Redux keeps the browsing and job detail flows from repeatedly refetching the same state. Shadcn UI pushes the interface past plain forms. Cloudinary handles the file path cleanly, which matters in a job workflow where resumes are central, not incidental.

LayerChoiceWhy it matters
UIShadcn UI plus TailwindFast to build, still polished
StateRedux ToolkitReduces duplicate fetching and UI drift
File handlingMulter plus CloudinaryKeeps resumes portable and persistent
BackendExpress plus MongooseSimple enough to read, structured enough to extend

The result looks like a portfolio project at first glance, but the implementation choices are unusually coherent. The app knows what it is trying to be, and the code follows that shape.


What Hirely-job Gets Right About AI Hiring Tools

Hirely-job is not trying to replace recruiting. It is trying to reduce friction in one specific step: interview preparation. That makes the product easier to believe and easier to use.

The bigger lesson is the fallback. If you build with AI, assume it will fail at some point. Then design the non-AI path so the user still gets value.

That is the difference between an AI demo and an AI product. One collapses when the model does. The other keeps moving.