feat: admin survey responses page with expandable detail and CSV export

- Backend: GET /admin/survey-responses (list with stats, invite join)
- Backend: GET /admin/survey-responses/export (CSV download)
- Frontend: SurveyResponsesPage with expandable row detail
- Two-column Q&A grid with typed answer rendering (chips, ranked lists, quote blocks)
- Stats cards (total responses, this week)
- CSV export button with blob download
- Sidebar nav + route wiring
- Also: updated Q14 from product domain ranking to diagnostic prioritization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-03-05 07:55:49 -05:00
parent 1644278fb1
commit 199cf315c6
9 changed files with 1339 additions and 12 deletions

View File

@@ -113,3 +113,59 @@ async def test_create_and_list_invites(client, admin_auth_headers):
assert list_res.status_code == 200
invites = list_res.json()
assert len(invites) >= 1
@pytest.mark.asyncio
async def test_list_survey_responses_admin(client, admin_auth_headers):
"""Admin can list survey responses."""
await client.post(
"/api/v1/survey/submit",
json={"respondent_name": "Tester", "responses": {"q1": "answer"}},
)
res = await client.get("/api/v1/admin/survey-responses", headers=admin_auth_headers)
assert res.status_code == 200
data = res.json()
assert "responses" in data
assert "total" in data
assert "this_week" in data
assert data["total"] >= 1
assert data["responses"][0]["respondent_name"] == "Tester"
assert data["responses"][0]["source"] == "direct"
@pytest.mark.asyncio
async def test_list_survey_responses_requires_admin(client, auth_headers):
"""Non-admin cannot list survey responses."""
res = await client.get("/api/v1/admin/survey-responses", headers=auth_headers)
assert res.status_code == 403
@pytest.mark.asyncio
async def test_export_survey_responses_csv(client, admin_auth_headers):
"""Admin can export survey responses as CSV."""
await client.post(
"/api/v1/survey/submit",
json={
"respondent_name": "CSV Tester",
"responses": {
"prereqs": ["Who's affected", "What changed recently"],
"verify_fix": "Have the user confirm",
"steps_at_a_time": "5 steps",
"prioritization": ["Likelihood", "Speed", "Blast radius"],
},
},
)
res = await client.get("/api/v1/admin/survey-responses/export", headers=admin_auth_headers)
assert res.status_code == 200
assert "text/csv" in res.headers["content-type"]
assert "attachment" in res.headers.get("content-disposition", "")
body = res.text
assert "CSV Tester" in body
assert "Respondent" in body
@pytest.mark.asyncio
async def test_export_survey_responses_requires_admin(client, auth_headers):
"""Non-admin cannot export survey responses."""
res = await client.get("/api/v1/admin/survey-responses/export", headers=auth_headers)
assert res.status_code == 403