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
5 changed files with 5295 additions and 14915 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,62 +0,0 @@
# Lightweight two-step picker data for loading a recorded shot into Shot Lab.
query GetRecordedStreams($limit: Int! = 25) {
getFeedVideos(
limit: $limit
filters: { isStreamCompleted: true, excludeVideosWithNoShots: true }
includePrivate: MINE
feedInput: { allUsers: true }
) {
videos {
id
name
createdAt
screenshotUri
framesPerSecond
totalShots
owner {
id
username
profileImageUri
}
}
}
}
query GetRecordedStreamShots($videoId: Int!, $limit: Int! = 200) {
getOrderedShots(
filterInput: { videoId: [$videoId] }
shotsOrdering: { orderings: [{ startFrame: { descending: false } }] }
limit: $limit
) {
shots {
id
videoId
startFrame
endFrame
serializedShotPaths {
b64EncodedBuffer
}
cueObjectFeatures {
cueObjectDistance
cueObjectAngle
cueBallSpeed
shotDirection
spinType
}
pocketingIntentionFeatures {
make
targetPocketDistance
targetPocketAngle
targetPocketAngleDirection
marginOfErrorInDegrees
intendedPocketType
difficulty
}
pocketingIntentionInfo {
ballId
pocketId
pathMetadataIndex
}
}
}
}

View File

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

View File

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

View File

@@ -73,7 +73,6 @@ type Query {
useHomography: HomographyInputGQL = null
): TableStateGQL!
getLiveTableState(videoId: Int!): LiveTableStateGQL!
getShotTableState(shotId: Int!): ShotTableStateGQL!
simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL!
computePotAim(
simulationInput: SimulateShotInputGQL!
@@ -610,7 +609,7 @@ type VideoTagClass {
}
type HomographyInfoGQL {
id: Int
id: Int!
frameIndex: Int!
crop: BoundingBoxGQL!
pockets: [BoundingBoxGQL!]!
@@ -1066,13 +1065,6 @@ type LiveTableStateGQL {
tableState: TableStateGQL!
}
type ShotTableStateGQL {
shotId: Int!
videoId: Int!
frameIndex: Int!
tableState: TableStateGQL!
}
type ShotProjectionGQL {
trajectories: [BallTrajectoryGQL!]!
events: [SimulationEventGQL!]!
@@ -1178,7 +1170,6 @@ input CreatedAfter @oneOf {
}
type UsageStatsGQL {
funnel: FunnelStatsGQL!
totalUsers: Int!
totalVideos: Int!
totalShots: Int!
@@ -1188,19 +1179,6 @@ type UsageStatsGQL {
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 UsageStatsWindowGQL {
label: String!
newUsers: Int!