A walk-through of the candidate-facing surface, the public API, and the marketing copy. Staff-side findings are flagged for Munaf & the team to grade on their own accounts.
What this report covers and what it deliberately does not.
This QA was requested with a 10-candidate plan and logins for the admin, bushra (HR, ABC Trading Co.) and faizan (Manager, reviewer) accounts. Neither was available at run time, so the report is split into two halves:
Each finding below was reproduced in-browser and would visibly embarrass a real candidate or HR reviewer.
The interview promised "8 questions" but the engine cycled between exactly two questions four times each: a "Trade Debtors Ageing" MCQ and a "Section 153 Freight WHT" freeform number. The candidate sees the same numbers and same wording verbatim. The "adaptive AI" engine is not adaptive.
Why it matters: the moment HR opens the report they will see "candidate answered Q1 four times" and the product's core differentiator collapses. The 8-question cap also means topic coverage is fixed; the engine cannot branch by difficulty or skip proven areas.
After the final question the URL stays on /interview, inputs disable, and the candidate is left on a static screen with no Save indicator and no next step. The /done route is fully built (warm closing, feedback box, 1-tap rating) but the redirect from the interview page never fires.
/interview, candidate has to know to navigate manually to /done to see "Thank you".Why it matters: on Pakistan mobile networks a 5-second delay or a no-action screen is read as "the form didn't work". Candidates will hit back, retake, and pollute reports with duplicates.
The "What we will cover" list on /welcome shows raw enum keys, not topic names:
core_accounting · manual_khata · payroll_statutory · taxation_pk · excel_tools · financial_statements · judgment_ethics · personality_retention
Meanwhile /interview-info lists the same eight topics with proper human-readable names: Core accounting, Manual khata, Payroll & EOBI / SESSI, Pakistani taxation, Excel, Salary → tax, Ethics & judgment, You, personally. The candidate-facing surface should use the second set.
Why it matters: it reads like a build artefact, kills trust, and is a one-line fix once the labels are pulled from the same source as /interview-info.
Marketing copy that misrepresents the experience, and UX gaps that will cost trust in the first 100 candidates.
The hero, the "How it works" section, and the live demo transcript all describe a free-form conversation in English or Roman Urdu. In reality Q1 is a four-option radio group and Q2 is a single number textbox. No free-text answer field, no chat, no image of the promised "balance sheet / khata page / voucher / cheque" attached to the question.
Why it matters: candidates expect a conversation and get a quiz. Either rebuild as a chat (large lift) or rewrite the marketing to honestly say "10 quick technical questions with real accounting scenarios".
Four different numbers on the same property:
Why it matters: a card saying ~25 turning into a 41-minute session is a trust-killer on WhatsApp. Pick one and propagate it.
After every submit the screen jumps to the next question with no "correct / partial / wrong" signal and no hint of what they got right. The home page promises "Ladders up. Answer well and the next question gets harder" but the candidate has no way to tell whether the next question is harder because of a good answer or random.
Why it matters: candidates finish with zero learning signal and HR has no per-question trail to point to in a rejection call.
The "Trade Debtors Ageing" question shows 0-30d = 9.88 crore, 31-60d = 12.1 crore, total debtors ~31.57 crore. The Section 153 freight line shows a single 30.17 crore payment. The job is "Gulshan Iqbal, near Disco Bakery, Karachi" — small/medium business. /interview-info also promises "real kacha khata page" which implies small-business scale.
Why it matters: an SME intern candidate has not seen a 30 crore debtor ledger. The question is technically correct and emotionally wrong for the role. Either scale the numbers down or scale the company profile up.
Step 2 (profile) includes a text field "Have you written articles or content?" with example hint "Two blog posts on accounting, or none". This is the wrong question for an Accountant (Internship). Likely a shared form template leaking across roles.
Why it matters: every accountant candidate wastes 20 seconds wondering why they're being asked about blog posts. The right field would be years of accounting experience, FBR return familiarity, or QuickBooks/Tally exposure.
A side-by-side of what the public site promises and what the candidate actually experiences. Use this as a copy-edit checklist.
Things only verifiable on admin / bushra / faizan accounts. Provide one of the three and this section becomes a 2-hour deep-dive instead of a stub.
All admin, HR, manager, dashboard, reports and override routes return 307 → /auth/login as expected (auth gate is working). To grade the actual report quality I need one of the following:
admin, bushra, faizan. I'll run them in read-only mode and screenshot the dashboards.Once I have access, the following is the priority checklist for the staff side:
These passed. Keep them healthy; regression-test on every deploy.
Name + phone → instant link → instant interview. The single most differentiating piece of the product. End-to-end the candidate never sees a password, an OTP or an app store prompt. This is what the market needs.
/api/public/applyReturned 429 after a few rapid-fire applies from the same IP. Without this the system is one curl loop away from 200 fake applicants.
/admin, /admin/dashboard, /admin/jobs, /hr, /hr/dashboard, /dashboard, /reports, /results, /api/admin/*, /api/staff, /api/hr all 307 → /auth/login. No staff endpoint is exposed unauthenticated.
Specific retention periods (12 months candidates, 6 months debug screenshots, 24 months analytics), named AI processing, audit-log mention, contact email, GDPR-style rights. This will survive a regulator conversation.
English + Roman Urdu flows are parallel across home, /interview-info, /start, /welcome, /done, /privacy. Tone is warm without being patronising.
CSP, HSTS, X-Content-Type-Options, Referrer-Policy, Permissions-Policy all present. OG / Twitter cards, theme-color, robots directives clean. /robots implicitly noindex via meta on the public surface.
/i/demo shows a bilingual "this link is not valid" page rather than a generic 404. Reduces support load when WhatsApp truncates a link.
What was tested, how, and the raw artefacts left behind.
/ → /start → /api/public/apply → /i/{token}/welcome → /profile → /interview (all 8 questions) → /done. All 4 sliders on the profile set to "Strong" (4/5). Both question formats (MCQ + freeform number) exercised.0-ui3g2601wl8.js) to confirm the inline form behaviour and the 5-field application shape.curl against 20 candidate, public, admin, HR and API routes to verify status codes, redirects, and the rate limit on /api/public/apply. All admin surfaces correctly 307 to /auth/login.curl -I on the home page; confirmed CSP, HSTS, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, frame-ancestors, base-uri, form-action. SEO meta (OG, Twitter, theme-color, keywords, robots) present./i/0RJ6y8_RFQ868WiOhND_My9Lp0TC715b-2DHng64ANk/done. Feedback left on /done with this bug list. Delete via admin or leave as a real test record.# Public jobs endpoint
curl -s https://jobinterview.maahir.io/api/public/jobs
# Apply endpoint (valid)
curl -s -X POST https://jobinterview.maahir.io/api/public/apply \
-H 'Content-Type: application/json' \
-d '{"jobId":19,"firstName":"Test","lastName":"Candidate","phone":"03001234567","email":"test@example.com","city":"Karachi"}'
# Auth-gate probe (admin surfaces should 307 → /auth/login)
for p in /admin /admin/dashboard /hr /dashboard /reports /api/admin/jobs; do
curl -sI -o /dev/null -w "%{http_code} %{redirect_url}\n" https://jobinterview.maahir.io$p
done
# Rate-limit verification
for i in 1 2 3 4 5; do
curl -s -o /dev/null -w "%{http_code} " -X POST https://jobinterview.maahir.io/api/public/apply \
-H 'Content-Type: application/json' \
-d "{\"jobId\":19,\"firstName\":\"Spam$i\",\"phone\":\"0300123456$i\",\"email\":\"spam$i@x.com\"}"
done; echo