feat(questionnaires): F8.1 admin analytics dashboards#53
Merged
Conversation
Add the admin read-side view of completed-session data, scoped to a
questionnaire version: per-question answer distributions, an invitation
completion funnel, and per-version cost actuals — with tag-aware filtering.
Read-only and aggregate-only (free-text answer values are never surfaced),
so the surface is PII-safe ahead of F8.3 anonymous-mode hardening.
- Core aggregators (pure, Prisma at the seam) in lib/app/questionnaire/analytics:
distributions, funnel, cost (+ shared query schema / scope resolver).
- Three admin-only, flag-gated, version-scoped GET routes under
.../versions/[vid]/analytics/{distributions,funnel,cost}.
- Version-scoped Analytics tab + client UI (filter, distribution, funnel,
cost panels); recharts for the cost trend.
- Cost attribution: standardise the four session-bound capabilities on the
canonical AiCostLog metadata key `appQuestionnaireSessionId` (runtime spend),
with design-time spend read via `metadata.versionId`. No migration.
Tests: 45 unit (aggregator math, per-type distributions, funnel staging,
cost runtime/design split + edge branches) + 21 route integration tests
(auth, version-scope, validation, response shape). Docs + F8.1 tracker added.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
F8.1 — Admin analytics dashboards
Opens P8. Adds the admin's read-side view of completed-session data, scoped to a questionnaire version: per-question answer distributions, an invitation completion funnel, and per-version cost actuals — with tag-aware filtering. Read-only, no new models, no migration.
Spec:
.context/app/planning/development-plan.md→ F8.1. Tracker:.context/app/planning/features/f8.1.md.What's included
lib/app/questionnaire/analytics/, pure with Prisma at the seam):distributions,funnel,cost, plus a shared query schema + scope resolver that reuses the platform date-range helpers.…/versions/[vid]/analytics/{distributions,funnel,cost}— admin-only, master-flag-gated, version-scoped (404 on a cross-questionnairevid)./admin/questionnaires/[id]/analytics) + client UI: shared filter (date window + tag chips), tabbed distribution / funnel / cost panels. recharts for the cost trend; CSS bars elsewhere; reusesTagChipandFieldHelp.Key decisions
AiCostLog, made attributable. Standardised the four session-bound capabilities on the canonical metadata keyappQuestionnaireSessionId(runtime spend); design-time spend is read viametadata.versionId(already stamped byevaluate-structure). The two key sets are disjoint, so runtime + design-time never double-count.AppQuestionnaireTurn.costUsdis untouched (it stays the F6.3 budget basis). No migration —AiCostLog.metadatais alreadyJson.userId. Anonymous (un-invited) sessions are reported separately.Testing
npm run validateclean.Gates run before opening
/pre-pr— type-check / lint / format / tests pass; changed-source coverage ≥80%; anti-pattern scan clean; CHANGELOG correctly N/A (app-tier, not platform surface)./test-review— all findings ≥80 addressed./security-review— no HIGH/MEDIUM findings (raw SQL fully parameterized; auth + version-scoping enforced; aggregate-only output).Out of scope (later P8)
🤖 Generated with Claude Code