{
  "summary": "End-to-end backend chain (login -> district -> coordinator -> block -> volunteer -> accept -> school-visit -> accept -> student -> fee-collect -> fee-verify -> marks -> report-card.pdf -> id-card.pdf -> authority-letter.pdf -> wallet payout -> finance summary) succeeded. Role-gating verified (DC and Volunteer both get 403 on POST /districts, POST /coordinators, POST /blocks). Frontend smoke: /login loads, ADMIN/ADMIN321 -> /sm dashboard with Hindi sidebar and stat cards. Two Excel report endpoints crash with HTTP 500 due to openpyxl sheet-title constraint (character '/' invalid).",
  "tested_scope": ["backend", "frontend", "auth", "integration"],
  "passed": [
    "POST /api/auth/login ADMIN/ADMIN321 returns token + user (state_manager)",
    "GET /api/auth/me with Bearer token returns user + profile",
    "POST /api/districts + GET /api/districts (SM)",
    "POST /api/coordinators (requires father_name, aadhaar, bank_name, account_number, ifsc) — DC user can login and role=district_coordinator",
    "DC POST /api/blocks (scoped to their district_id) + GET /api/blocks scoped",
    "DC POST /api/volunteers (requires mother_name, dob) status=pending, volunteer_code=null",
    "SM POST /api/volunteers/{id}/status accepted -> volunteer_code=MOF/VO/0001, user created with password 123456; volunteer login works, role=volunteer",
    "Volunteer POST /api/school-visits auto-attached to district/block/volunteer_id",
    "SM POST /api/school-visits/{id}/status accepted",
    "Volunteer POST /api/students (school_id = accepted school_visit id, field name is student_class not class_name); fee_amount=300, fee_paid=false, fee_verified=false",
    "Volunteer POST /api/students/{id}/fee-collect; SM POST /api/students/{id}/fee-verify",
    "SM POST /api/students/{id}/marks returns percentage & report_card object",
    "GET /api/reports/student/{id}/report-card.pdf -> 200 application/pdf",
    "GET /api/reports/coordinators.pdf, /api/reports/students.pdf -> 200 application/pdf",
    "GET /api/reports/volunteer/{id}/id-card.pdf and /authority-letter.pdf -> 200 application/pdf",
    "POST /api/wallet/transactions (SM payout) works; GET /api/wallet/transactions as volunteer returns only their own txn",
    "GET /api/finance/summary correct: total_students=1, fees_collected_count/amount=1/300, fees_verified_count/amount=1/300, total_payouts=500",
    "Role gating: DC gets 403 on POST /api/districts and POST /api/coordinators; Volunteer gets 403 on POST /api/districts and POST /api/blocks",
    "Frontend /login loads with data-testids login-username/password/submit; ADMIN/ADMIN321 -> /sm; Hindi sidebar (डैशबोर्ड, जिला प्रबंधन, वॉलंटियर, ...) and stat cards render"
  ],
  "failed": [
    {
      "area": "backend / reports",
      "issue": "GET /api/reports/volunteers.xlsx returns HTTP 500 Internal Server Error",
      "evidence": "openpyxl ValueError: Invalid character / found in sheet title at server.py:754 (_make_xlsx uses title with '/' e.g. 'MOF/Volunteers')",
      "priority": "HIGH"
    },
    {
      "area": "backend / reports",
      "issue": "GET /api/reports/school-visits.xlsx returns HTTP 500 Internal Server Error",
      "evidence": "Same openpyxl 'Invalid character / found in sheet title' traceback at server.py:754",
      "priority": "HIGH"
    }
  ],
  "action_items": [
    "In backend/server.py _make_xlsx (line ~754), sanitize the sheet title before assigning to ws.title — strip or replace openpyxl-forbidden characters (/, \\, ?, *, [, ], :). Example: ws.title = re.sub(r'[\\\\/*?:\\[\\]]', '-', title)[:30]. Applies to both volunteers.xlsx and school-visits.xlsx endpoints."
  ],
  "success_rate": {"backend": "~88% (15/17 endpoints tested pass; 2 xlsx endpoints 500)", "frontend": "100% (login + SM dashboard smoke pass)"},
  "retest_needed": true,
  "full_testing_deferred": true,
  "test_credentials": "Loaded from /app/memory/test_credentials.md — ADMIN/ADMIN321 valid; DC and Volunteer created dynamically as documented."
}
