Compare commits

..

2 Commits

Author SHA1 Message Date
Dean Wenstrand
f40c223dfc Add getUsageStats operation + hook
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:30:13 -07:00
Dean Wenstrand
4758c95149 Add getUsageStats admin query types
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:29:07 -07:00
4 changed files with 5300 additions and 14547 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -9,9 +9,6 @@ query GetTableState(
useHomography: $useHomography useHomography: $useHomography
) { ) {
identifierToPosition identifierToPosition
identifierToColor {
hex
}
} }
} }
@@ -21,9 +18,6 @@ query GetLiveTableState($videoId: Int!) {
frameIndex frameIndex
tableState { tableState {
identifierToPosition identifierToPosition
identifierToColor {
hex
}
homography { homography {
...HomographyInfo ...HomographyInfo
} }

View File

@@ -1,24 +1,5 @@
query getUsageStats($days: Int! = 30) { query getUsageStats($days: Int! = 30) {
getUsageStats(days: $days) { getUsageStats(days: $days) {
funnel {
freemiumEpoch
eraSignups
eraPaying
activationCohort
activationActivated
payingUsers
newPaid7d
newPaid30d
retentionPrevActive
retentionReturned
}
cohorts {
weekStart
signups
activated7d
paid7d
activatedNotPaid7d
}
totalUsers totalUsers
totalVideos totalVideos
totalShots totalShots

View File

@@ -73,7 +73,6 @@ type Query {
useHomography: HomographyInputGQL = null useHomography: HomographyInputGQL = null
): TableStateGQL! ): TableStateGQL!
getLiveTableState(videoId: Int!): LiveTableStateGQL! getLiveTableState(videoId: Int!): LiveTableStateGQL!
getShotTableState(shotId: Int!): ShotTableStateGQL!
simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL! simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL!
computePotAim( computePotAim(
simulationInput: SimulateShotInputGQL! simulationInput: SimulateShotInputGQL!
@@ -610,7 +609,7 @@ type VideoTagClass {
} }
type HomographyInfoGQL { type HomographyInfoGQL {
id: Int id: Int!
frameIndex: Int! frameIndex: Int!
crop: BoundingBoxGQL! crop: BoundingBoxGQL!
pockets: [BoundingBoxGQL!]! pockets: [BoundingBoxGQL!]!
@@ -1066,13 +1065,6 @@ type LiveTableStateGQL {
tableState: TableStateGQL! tableState: TableStateGQL!
} }
type ShotTableStateGQL {
shotId: Int!
videoId: Int!
frameIndex: Int!
tableState: TableStateGQL!
}
type ShotProjectionGQL { type ShotProjectionGQL {
trajectories: [BallTrajectoryGQL!]! trajectories: [BallTrajectoryGQL!]!
events: [SimulationEventGQL!]! events: [SimulationEventGQL!]!
@@ -1178,38 +1170,15 @@ input CreatedAfter @oneOf {
} }
type UsageStatsGQL { type UsageStatsGQL {
funnel: FunnelStatsGQL!
totalUsers: Int! totalUsers: Int!
totalVideos: Int! totalVideos: Int!
totalShots: Int! totalShots: Int!
totalRuns: Int! totalRuns: Int!
cohorts: [CohortStatsGQL!]!
windows: [UsageStatsWindowGQL!]! windows: [UsageStatsWindowGQL!]!
daily: [UsageStatsDailyGQL!]! daily: [UsageStatsDailyGQL!]!
processingLast24h: [ProcessingStatusCountGQL!]! processingLast24h: [ProcessingStatusCountGQL!]!
} }
type FunnelStatsGQL {
freemiumEpoch: Date!
eraSignups: Int!
eraPaying: Int!
activationCohort: Int!
activationActivated: Int!
payingUsers: Int!
newPaid7d: Int!
newPaid30d: Int!
retentionPrevActive: Int!
retentionReturned: Int!
}
type CohortStatsGQL {
weekStart: Date!
signups: Int!
activated7d: Int!
paid7d: Int!
activatedNotPaid7d: Int!
}
type UsageStatsWindowGQL { type UsageStatsWindowGQL {
label: String! label: String!
newUsers: Int! newUsers: Int!