feat: analytics dashboards & two-tier feedback system (#78)
* docs: add analytics & user feedback design document Covers team analytics, personal analytics, flow analytics, step-level thumbs up/down feedback, and flow CSAT ratings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add analytics & feedback implementation plan 12-task TDD plan covering session ratings, step feedback, team/personal/flow analytics endpoints, and frontend pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add session_ratings table and analytics indexes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add SessionRating model and analytics schemas Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add session CSAT rating endpoint with tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add step thumbs feedback and /ratings alias routes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add team, personal, and flow analytics endpoints Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add recharts, analytics types, and API client Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add inline step thumbs up/down feedback during sessions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add CSAT rating modal after session completion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add Team Analytics page with charts and leaderboards Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add Flow Analytics panel with step dropoff and CSAT data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add My Analytics page with personal stats and charts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit was merged in pull request #78.
This commit is contained in:
36
frontend/src/api/analytics.ts
Normal file
36
frontend/src/api/analytics.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import apiClient from './client'
|
||||
import type {
|
||||
TeamAnalyticsResponse,
|
||||
PersonalAnalyticsResponse,
|
||||
FlowAnalyticsResponse,
|
||||
AnalyticsPeriod,
|
||||
} from '@/types'
|
||||
|
||||
const analyticsApi = {
|
||||
async getTeamAnalytics(period: AnalyticsPeriod = '30d', engineerId?: string): Promise<TeamAnalyticsResponse> {
|
||||
const params: Record<string, string> = { period }
|
||||
if (engineerId) params.engineer_id = engineerId
|
||||
const response = await apiClient.get<TeamAnalyticsResponse>('/analytics/team', { params })
|
||||
return response.data
|
||||
},
|
||||
|
||||
async getPersonalAnalytics(period: AnalyticsPeriod = '30d'): Promise<PersonalAnalyticsResponse> {
|
||||
const response = await apiClient.get<PersonalAnalyticsResponse>('/analytics/me', { params: { period } })
|
||||
return response.data
|
||||
},
|
||||
|
||||
async getFlowAnalytics(treeId: string, period: AnalyticsPeriod = '30d'): Promise<FlowAnalyticsResponse> {
|
||||
const response = await apiClient.get<FlowAnalyticsResponse>(`/analytics/flows/${treeId}`, { params: { period } })
|
||||
return response.data
|
||||
},
|
||||
|
||||
async rateSession(sessionId: string, rating: number, comment?: string): Promise<void> {
|
||||
await apiClient.post(`/sessions/${sessionId}/rate`, { rating, comment })
|
||||
},
|
||||
|
||||
async submitStepFeedback(stepId: string, sessionId: string, wasHelpful: boolean): Promise<void> {
|
||||
await apiClient.post(`/steps/${stepId}/feedback`, { session_id: sessionId, was_helpful: wasHelpful })
|
||||
},
|
||||
}
|
||||
|
||||
export default analyticsApi
|
||||
@@ -12,3 +12,4 @@ export { default as accountsApi } from './accounts'
|
||||
export { default as adminApi } from './admin'
|
||||
export { treeMarkdownApi } from './treeMarkdown'
|
||||
export { default as pinnedFlowsApi } from './pinnedFlows'
|
||||
export { default as analyticsApi } from './analytics'
|
||||
|
||||
Reference in New Issue
Block a user