QA Report — visaready SIT · https://visaready-sit.winds-os.com · run 20260711185729
20/20CORE purpose
80cases
80passed
0failed
3/3masters
9/9scoring
15/15workflow
8/8auth
6/6validation
5/5crud
4/4documents
7/7payment
3/3rbac
2/2integrations
3/3profile
13/13ui
2/2android
All green — no bugs this run ✅
📸 Screens (14)
Cases
✓
CORE TC-M01 Country master is seeded and searchable
masters · api · · 85ms
- GET /api/country?page=1&limit=100
- GET /api/country?q=India
- GET /api/country?q=France
✓
CORE TC-M02 Plans master is seeded (Lite / Starter / Advance …)
masters · api · VR-4.15 · 18ms
- GET /api/plan?page=1&limit=50
- GET /api/plan?q=Starter
✓
CORE TC-S01 Customer can create a complete application (draft)
scoring · api · VR-4.7 · 22ms
- POST /api/application
✓
CORE TC-S02 VisaScore Lite — strong profile scores High (≥85)
scoring · api · VR-4.13 · 59ms
- POST /api/flows/generate_lite_score/run
- GET /api/application/102
✓
CORE TC-S03 Scoring is blocked until the return declaration is confirmed
scoring · api · VR-4.12 · 28ms
- POST /api/application
- POST /api/flows/generate_lite_score/run
✓
CORE TC-S04 VisaScore Lite — weak profile lands in the Low band (≤30)
scoring · api · VR-4.13 · 55ms
- POST /api/application
- POST /api/flows/generate_lite_score/run
- GET /api/application/104
✓
CORE TC-S05 Final VisaScore — full lifecycle to Strong Readiness with VisaMatrix report
scoring · api · VR-4.16 · 87ms
- POST /api/application/102/transition
- POST /api/application/102/transition
- POST /api/flows/generate_final_score/run
- GET /api/application/102
✓
CORE TC-S06 One free score regeneration is allowed
scoring · api · VR-5.3 · 53ms
- POST /api/flows/regenerate_score/run
- GET /api/application/102
✓
CORE TC-S07 A second regeneration is refused (2 scores total)
scoring · api · VR-5.3 · 8ms
- POST /api/flows/regenerate_score/run
✓
CORE TC-S08 Every final score writes a VisaMatrix report record
scoring · api · VR-4.16 · 10ms
- GET /api/visa_report?page=1&limit=50
✓
CORE TC-S09 Lifecycle-button path also produces the Lite score (transition + async flow)
scoring · api · VR-4.13 · 68ms
- POST /api/application
- POST /api/application/105/transition
- GET /api/application/105
✓
CORE TC-W01 Workflow: full customer journey draft → lite → docs → paid → final → embassy → approved
workflow · api · VR-2.2 · 257ms
- POST /api/application
- POST /api/flows/generate_lite_score/run
- POST /api/document
- POST /api/document
- POST /api/document/56/transition
- POST /api/document/57/transition
- POST /api/application/106/transition
- POST /api/application/106/transition
- POST /api/flows/generate_final_score/run
- GET /api/application/106
- POST /api/application/106/transition
- PATCH /api/application/106
- POST /api/application/106/transition
- GET /api/application/106
✓
CORE TC-W02 Workflow: rejection path ends in terminal rejected status
workflow · api · VR-4.17 · 178ms
- POST /api/application
- POST /api/flows/generate_lite_score/run
- POST /api/application/107/transition
- POST /api/application/107/transition
- POST /api/flows/generate_final_score/run
- POST /api/application/107/transition
- POST /api/application/107/transition
- GET /api/application/107
✓
CORE TC-W03 Workflow: customer submits to agent, agent forwards to embassy (role interplay)
workflow · api · VR-4.5 · 193ms
- POST /api/application
- POST /api/flows/generate_lite_score/run
- POST /api/application/108/transition
- POST /api/application/108/transition
- POST /api/flows/generate_final_score/run
- POST /api/application/108/transition
- POST /api/application/108/transition
- GET /api/application/108
✓
CORE TC-W11 Workflow: single-use promo is exhausted after one redemption (usage cap)
workflow · api · VR-4.15 · 60ms
- POST /api/promo_code
- POST /api/payment
- POST /api/flows/apply_promo/run
- GET /api/payment/90
- GET /api/promo_code/49
- POST /api/payment
- POST /api/flows/apply_promo/run
✓
CORE TC-U09 Workflow UI: complete all 7 guided steps and generate a Lite score
ui · ui · VR-2.2 · 25643ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Start New Application"
- expect_text: "Step 1 of 7"
- fill: {"placeholder": "Application Title", "value": "UI Journey 20260711185729"}
- fill: {"placeholder": "Passport Number", "value": "U1857299"}
- fill: {"placeholder": "Name (as in passport)", "value": "UI Journey Tester"}
- fill: {"placeholder": "Place of Issue", "value": "Mumbai"}
- fill: {"placeholder": "YYYY-MM-DD", "nth": 0, "value": "2020-01-15"}
- fill: {"placeholder": "YYYY-MM-DD", "nth": 1, "value": "2031-01-14"}
- tap: "Select Nationality"
- tap: "India"
- tap: "Save & Continue"
- expect_text: "Step 2 of 7"
- tap: "Select Destination Country"
- tap: "France"
- tap: "Done"
- tap: "Select Visa Type"
- tap: "Tourist / Visitor"
- fill: {"placeholder": "YYYY-MM-DD", "nth": 0, "value": "2026-08-10"}
- fill: {"placeholder": "YYYY-MM-DD", "nth": 1, "value": "2026-08-24"}
- fill: {"placeholder": "Trip Duration (days)", "value": "14"}
- tap: "Save & Next"
- expect_text: "Step 3 of 7"
- fill: {"placeholder": "First Name", "value": "UI"}
- fill: {"placeholder": "YYYY-MM-DD", "nth": 0, "value": "1990-05-20"}
- tap: "Select Gender"
- tap: "Male"
- tap: "Select Marital Status"
- tap: "Married"
- fill: {"placeholder": "Current City of Residence", "value": "Mumbai"}
- fill: {"placeholder": "State", "value": "Maharashtra"}
- fill: {"placeholder": "PIN / Postal Code", "value": "400001"}
- fill: {"placeholder": "Email", "value": "qa.20260711185729@visaready.test"}
- fill: {"placeholder": "Mobile", "value": "9876543299"}
- tap: "Select Highest Qualification"
- tap: "Postgraduate"
- tap: "Select User Type"
- tap: "Salaried"
- tap: "Save & Next"
- expect_text: "Step 4 of 7"
- tap: "Save & Next"
- expect_text: "Step 5 of 7"
- tap: "Save & Next"
- expect_text: "Step 6 of 7"
- toggle: 3
- tap: "Save & Next"
- expect_text: "Step 7 of 7"
- screenshot: "journey-step7"
- tap: "Generate VisaScore"
- wait: 3500
- goto: "/"
- expect_text: "Indicative (Lite) result"
- screenshot: "journey-done"
console: error: Failed to load resource: the server responded with a status of 403 (Forbidden) ⏐ error: Failed to load resource: the server responded with a status of 403 (Forbidden)
✓
CORE TC-U10 Workflow UI: progress the application docs → paid → Final Score from the app
ui · ui · VR-4.16 · 13652ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "UI Journey 20260711185729"
- expect_text: "Application Progress"
- tap: "Documents Complete"
- wait: 900
- tap: "Payment Received"
- wait: 900
- tap: "Generate Final Score"
- wait: 4500
- goto: "/"
- expect_text: "Verified score"
- screenshot: "ui-final-score"
✓
CORE TC-U11 Workflow UI (negative): second score regeneration is refused with a visible message
ui · ui · VR-5.3 · 9777ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Verified score"
- expect_text: "Score Improvement"
- tap: "Generate New Score (re-score rule)"
- wait: 3000
- expect_text: "done ✓"
- tap: "Generate New Score (re-score rule)"
- wait: 1500
- expect_text: "Regeneration limit reached"
- screenshot: "ui-regen-cap"
console: error: Failed to load resource: the server responded with a status of 403 (Forbidden) ⏐ error: Failed to load resource: the server responded with a status of 400 (Bad Request)
✓
CORE TC-U12 Workflow UI (negative): invalid passport number shows the exact rule and blocks Step 1
ui · ui · VR-4.7 · 4634ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Start New Application"
- expect_text: "Step 1 of 7"
- fill: {"placeholder": "Passport Number", "value": "abc123"}
- tap: "Save & Continue"
- expect_text: "8–9 characters"
- expect_text: "Step 1 of 7"
- screenshot: "ui-invalid-passport"
console: error: Failed to load resource: the server responded with a status of 400 (Bad Request)
✓
CORE TC-U13 Workflow UI (negative): scoring without the return declaration shows the guard message
ui · ui · VR-4.12 · 10625ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Start New Application"
- expect_text: "Step 1 of 7"
- fill: {"placeholder": "Passport Number", "value": "D1857299"}
- tap: "Save & Continue"
- expect_text: "Step 2 of 7"
- tap: "Save & Next"
- expect_text: "Step 3 of 7"
- tap: "Save & Next"
- expect_text: "Step 4 of 7"
- tap: "Save & Next"
- expect_text: "Step 5 of 7"
- tap: "Save & Next"
- expect_text: "Step 6 of 7"
- tap: "Save & Next"
- expect_text: "Step 7 of 7"
- tap: "Generate VisaScore"
- wait: 1500
- expect_text: "Please confirm the return declaration"
- screenshot: "ui-declaration-block"
console: error: Failed to load resource: the server responded with a status of 403 (Forbidden) ⏐ error: Failed to load resource: the server responded with a status of 403 (Forbidden) ⏐ error: Failed to load resource: the server responded with a status of 400 (Bad Request)
✓
TC-A01 OTP request succeeds for a new email with a resend timer
auth · api · VR-4.2 · 11ms
- POST /api/auth/request-otp
✓
TC-A02 Correct OTP signs the user in and creates a customer account
auth · api · VR-4.2 · 28ms
- POST /api/auth/request-otp
- POST /api/auth/verify-otp
✓
TC-A03 Wrong OTP is rejected
auth · api · VR-4.2 · 15ms
- POST /api/auth/request-otp
- POST /api/auth/verify-otp
✓
TC-A04 OTP verify without a prior request is rejected as expired
auth · api · VR-4.2 · 5ms
- POST /api/auth/verify-otp
✓
TC-A05 Empty identifier is rejected with a helpful message
auth · api · VR-4.2 · 2ms
- POST /api/auth/request-otp
✓
TC-A06 Session token identifies the signed-in customer on /auth/me
auth · api · VR-4.2 · 4ms
- GET /api/auth/me
✓
TC-A07 Protected APIs refuse anonymous access
auth · api · VR-4.2 · 3ms
- GET /api/application
✓
TC-A08 Mobile-number OTP login is enabled
auth · api · VR-4.2 · 7ms
- POST /api/auth/request-otp
✓
TC-M03 Document checklist master is seeded
masters · api · VR-4.14 · 8ms
- GET /api/doc_requirement?page=1&limit=100
✓
TC-V01 Passport number format is enforced (8–9 uppercase alphanumerics)
validation · api · VR-4.7 · 3ms
- POST /api/application
✓
TC-V02 PIN code must be 6 digits
validation · api · VR-4.9 · 3ms
- POST /api/application
✓
TC-V03 Travel end date cannot be before the start date (cross-field)
validation · api · VR-4.8 · 4ms
- POST /api/application
✓
TC-V04 Required fields are enforced on application create
validation · api · VR-4.9 · 4ms
- POST /api/application
✓
TC-V05 GSTIN format is validated when provided
validation · api · VR-4.9 · 4ms
- POST /api/application
✓
TC-V06 Passport expiry must be after the issue date (cross-field)
validation · api · VR-4.7 · 3ms
- POST /api/application
✓
TC-C01 Applications are searchable by title
crud · api · · 10ms
- GET /api/application?q=QA%20Strong%2020260711185729
✓
TC-C02 List pagination respects the limit
crud · api · · 9ms
- GET /api/application?page=1&limit=2
✓
TC-C03 Application fields can be updated (PATCH)
crud · api · · 29ms
- PATCH /api/application/102
- GET /api/application/102
✓
TC-C04 Deleting an application removes it from lists (soft delete)
crud · api · · 37ms
- POST /api/application
- DELETE /api/application/109
- GET /api/application?q=QAScratch20260711185729
✓
TC-C05 Fetching a non-existent application returns 404
crud · api · · 5ms
- GET /api/application/999999
✓
TC-D01 Customer can attach a document to their application
documents · api · VR-4.14 · 8ms
- POST /api/document
✓
TC-D02 Document can be verified (uploaded → verified)
documents · api · VR-4.14 · 22ms
- POST /api/document/58/transition
- GET /api/document/58
✓
TC-D03 Admin can flag a document
documents · api · VR-4.14 · 31ms
- POST /api/document
- PATCH /api/document/59
- POST /api/document/59/transition
- GET /api/document/59
✓
TC-D04 Customer cannot flag documents (admin-only transition)
documents · api · VR-4.14 · 14ms
- POST /api/document
- POST /api/document/60/transition
✓
TC-P01 Admin can register an agency
payment · api · VR-4.5 · 8ms
- POST /api/agency
✓
TC-P02 Admin approves the agency (KYC → active)
payment · api · VR-4.5 · 9ms
- POST /api/agency/24/transition
✓
TC-P03 Admin issues a promo code allocated to the agency
payment · api · VR-4.15 · 8ms
- POST /api/promo_code
✓
TC-P04 Valid promo waives the fee and issues an invoice
payment · api · VR-4.15 · 42ms
- POST /api/payment
- POST /api/flows/apply_promo/run
- GET /api/payment/83
✓
TC-P05 Unknown promo code is rejected with guidance
payment · api · VR-4.15 · 14ms
- POST /api/payment
- POST /api/flows/apply_promo/run
✓
TC-P06 Applying promo without a code tells the user to enter one
payment · api · VR-4.15 · 11ms
- POST /api/payment
- POST /api/flows/apply_promo/run
✓
TC-P07 Successful payment triggers automatic invoice issuance
payment · api · VR-4.15 · 1025ms
- POST /api/payment/85/transition
- GET /api/payment/85
✓
TC-R01 Customer cannot approve agencies (admin-only lifecycle)
rbac · api · VR-4.5 · 13ms
- POST /api/agency
- POST /api/agency/25/transition
✓
TC-R02 Flows cannot be triggered anonymously
rbac · api · · 2ms
- POST /api/flows/generate_final_score/run
✓
TC-R03 SIT header-auth backdoor works for admin (must be OFF outside SIT)
rbac · api · · 3ms
- GET /api/auth/me
✓
TC-I01 Signed-in users can upload files (storage slot → R2)
integrations · api · · 193ms
- POST /api/upload
✓
TC-I02 Anonymous users cannot upload files
integrations · api · · 4ms
- POST /api/upload
✓
TC-F01 Customer can create their applicant profile
profile · api · VR-4.6 · 11ms
- POST /api/applicant_profile
✓
TC-F02 Duplicate profile email is rejected cleanly (unique)
profile · api · VR-4.6 · 6ms
- POST /api/applicant_profile
✓
TC-F03 First name must be at least 2 characters
profile · api · VR-4.6 · 3ms
- POST /api/applicant_profile
✓
TC-W04 Workflow: agency code is validated — valid code maps, unknown code errors
workflow · api · VR-4.13 · 60ms
- PATCH /api/application/108
- POST /api/flows/map_agency_code/run
- PATCH /api/application/108
- POST /api/flows/map_agency_code/run
✓
TC-W05 Workflow: multi-applicant — co-applicant attaches to the application
workflow · api · VR-4.7a · 39ms
- PATCH /api/application/106
- POST /api/co_applicant
- GET /api/co_applicant?filter[application]=106
✓
TC-W06 Workflow: failed payment can be retried and still issues an invoice
workflow · api · VR-4.15 · 56ms
- POST /api/payment
- POST /api/payment/86/transition
- POST /api/payment/86/transition
- GET /api/payment/86
✓
TC-W07 Workflow: promo redemption increments its usage counter
workflow · api · VR-4.15 · 4ms
- GET /api/promo_code/45
✓
TC-W08 Workflow: expired promo code is refused
workflow · api · VR-4.15 · 37ms
- POST /api/promo_code
- POST /api/payment
- POST /api/flows/apply_promo/run
✓
TC-W09 Workflow: promo code not yet in its validity window is refused
workflow · api · VR-4.15 · 27ms
- POST /api/promo_code
- POST /api/payment
- POST /api/flows/apply_promo/run
✓
TC-W10 Workflow: deactivated promo code is refused
workflow · api · VR-4.15 · 22ms
- POST /api/promo_code
- POST /api/payment
- POST /api/flows/apply_promo/run
✓
TC-W12 Workflow: improving the profile and regenerating raises the final score
workflow · api · VR-5.3 · 209ms
- POST /api/application
- POST /api/flows/generate_lite_score/run
- POST /api/application/110/transition
- POST /api/application/110/transition
- POST /api/flows/generate_final_score/run
- GET /api/application/110
- PATCH /api/application/110
- POST /api/flows/regenerate_score/run
- GET /api/application/110
✓
TC-W13 Workflow: flagged document — customer cannot clear the flag, agent can
workflow · api · VR-4.14 · 17ms
- POST /api/document/59/transition
- POST /api/document/59/transition
- GET /api/document/59
✓
TC-W14 Workflow: admin analytics reports run and group correctly
workflow · api · VR-5.x · 7ms
- GET /api/reports
- GET /api/reports/applications_by_band
✓
TC-W15 Workflow: uploaded document gets OCR-scanned into ocr_summary (vision model)
workflow · api · VR-4.14 · 3188ms
- POST /api/upload
- POST /api/document
- POST /api/document/61/transition
- GET /api/document/61
✓
TC-U01 Email OTP login lands on the personalised dashboard
ui · ui · VR-4.2 · 3056ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- screenshot: "home"
✓
TC-U02 Wrong OTP shows an inline error
ui · ui · VR-4.2 · 3002ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.ui2.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "9999"}
- tap: "Verify & sign in"
- expect_text: "Incorrect code"
- screenshot: "wrong-otp"
console: error: Failed to load resource: the server responded with a status of 401 (Unauthorized)
✓
TC-U03 Dashboard shows score card, journeys, recent apps and explore links
ui · ui · VR-2.2 · 3029ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- expect_text: "Visa Readiness"
- expect_text: "Get started"
- expect_text: "Visa Application (6 Steps + Score)"
- expect_text: "Start New Application"
- expect_text: "Explore"
- screenshot: "dashboard"
✓
TC-U04 Profile tab opens the applicant profile form
ui · ui · VR-4.6 · 3838ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Profile"
- expect_text: "Passport Number"
- screenshot: "profile"
✓
TC-U05 Customer does not see admin/agent-only navigation
ui · ui · · 5924ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- expect_not_text: "Leads"
- expect_not_text: "Administration"
✓
TC-U06 Guided journey opens at Step 1 with the passport form
ui · ui · VR-2.2 · 3815ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Visa Application (6 Steps + Score)"
- expect_text: "Step 1 of 7"
- fill: {"placeholder": "Passport Number", "value": "M7654321"}
- screenshot: "wizard-step1"
✓
TC-U07 Explore links include the Terms & Consent page
ui · ui · VR-4.4 · 3064ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- expect_text: "Terms of Use, Consent & Disclaimer"
✓
TC-U08 Library tab renders without errors
ui · ui · · 5255ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- tap: "Library"
- wait: 1500
- screenshot: "library"
✓
TC-U01-AND Email OTP login lands on the personalised dashboard [Android device]
android · android · VR-4.2 · 6911ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- screenshot: "home"
✓
TC-U03-AND Dashboard shows score card, journeys, recent apps and explore links [Android device]
android · android · VR-2.2 · 6196ms
- goto: "/"
- fill: {"placeholder": "you@example.com", "value": "qa.20260711185729@visaready.test"}
- tap: "Send code"
- expect_text: "Enter the 4-digit code"
- fill: {"nth": 0, "value": "1234"}
- tap: "Verify & sign in"
- expect_text: "Hi there"
- expect_text: "Visa Readiness"
- expect_text: "Get started"
- expect_text: "Visa Application (6 Steps + Score)"
- expect_text: "Start New Application"
- expect_text: "Explore"
- screenshot: "dashboard"
Generated by spec-studio QA runner — deterministic execution, AI only authors the test pack.