Compare commits

..

4 Commits

Author SHA1 Message Date
Dean Wenstrand
35c7c23ba9 Add disjoint activated segment to cohorts for stacking
All checks were successful
Tests / Tests (pull_request) Successful in 10s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:45:01 -07:00
Dean Wenstrand
40c4b82a59 Add weekly cohort funnel to getUsageStats
All checks were successful
Tests / Tests (pull_request) Successful in 13s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:40:10 -07:00
9ebe2e61df Merge pull request 'dean/usage-stats' (#292) from dean/usage-stats into master
Reviewed-on: #292
2026-07-11 19:26:13 +00:00
dc02fd8387 Merge pull request 'Select detected ball colors for Shot Lab' (#291) from colonelpanic/shot-lab-image-colors into master
Reviewed-on: #291
2026-07-10 17:20:37 +00:00
3 changed files with 48 additions and 28 deletions

View File

@@ -260,6 +260,15 @@ export type ClusterAssignmentInput = {
userId?: InputMaybe<Scalars["Int"]["input"]>;
};
export type CohortStatsGql = {
__typename?: "CohortStatsGQL";
activated7d: Scalars["Int"]["output"];
activatedNotPaid7d: Scalars["Int"]["output"];
paid7d: Scalars["Int"]["output"];
signups: Scalars["Int"]["output"];
weekStart: Scalars["Date"]["output"];
};
export type CommentGql = {
__typename?: "CommentGQL";
id: Scalars["Int"]["output"];
@@ -2400,7 +2409,7 @@ export type HomographyInfoGql = {
crop: BoundingBoxGql;
destPoints: PocketPointsGql;
frameIndex: Scalars["Int"]["output"];
id?: Maybe<Scalars["Int"]["output"]>;
id: Scalars["Int"]["output"];
pockets: Array<BoundingBoxGql>;
sourcePoints: PocketPointsGql;
};
@@ -3080,7 +3089,6 @@ export type Query = {
getResolvedTier: ResolvedTierGql;
getRuns: GetRunsResult;
getShotAnnotationTypes: Array<ShotAnnotationTypeGql>;
getShotTableState: ShotTableStateGql;
getShots: Array<ShotGql>;
getShotsByIds: Array<ShotGql>;
getShotsWithMetadata: GetShotsResult;
@@ -3226,10 +3234,6 @@ export type QueryGetShotAnnotationTypesArgs = {
errorTypes?: InputMaybe<Scalars["Boolean"]["input"]>;
};
export type QueryGetShotTableStateArgs = {
shotId: Scalars["Int"]["input"];
};
export type QueryGetShotsArgs = {
countRespectsLimit?: Scalars["Boolean"]["input"];
filterInput: FilterInput;
@@ -3609,14 +3613,6 @@ export type ShotProjectionGql = {
trajectories: Array<BallTrajectoryGql>;
};
export type ShotTableStateGql = {
__typename?: "ShotTableStateGQL";
frameIndex: Scalars["Int"]["output"];
shotId: Scalars["Int"]["output"];
tableState: TableStateGql;
videoId: Scalars["Int"]["output"];
};
export type ShotsOrderingComponent =
| {
difficulty: FloatOrdering;
@@ -3993,6 +3989,7 @@ export type UsageStatsDailyGql = {
export type UsageStatsGql = {
__typename?: "UsageStatsGQL";
cohorts: Array<CohortStatsGql>;
daily: Array<UsageStatsDailyGql>;
funnel: FunnelStatsGql;
processingLast24h: Array<ProcessingStatusCountGql>;
@@ -6839,7 +6836,7 @@ export type GetLiveTableStateQuery = {
} | null>;
homography?: {
__typename?: "HomographyInfoGQL";
id?: number | null;
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -7488,6 +7485,14 @@ export type GetUsageStatsQuery = {
retentionPrevActive: number;
retentionReturned: number;
};
cohorts: Array<{
__typename?: "CohortStatsGQL";
weekStart: any;
signups: number;
activated7d: number;
paid7d: number;
activatedNotPaid7d: number;
}>;
windows: Array<{
__typename?: "UsageStatsWindowGQL";
label: string;
@@ -7868,7 +7873,7 @@ export type GetStreamMonitoringDetailsQuery = {
elapsedTime?: number | null;
currentHomography?: {
__typename?: "HomographyInfoGQL";
id?: number | null;
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -8282,7 +8287,7 @@ export type GetVideoQuery = {
} | null;
homographyHistory: Array<{
__typename?: "HomographyInfoGQL";
id?: number | null;
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -8530,7 +8535,7 @@ export type FindPrerecordTableLayoutMutation = {
__typename?: "Mutation";
findPrerecordTableLayout?: {
__typename?: "HomographyInfoGQL";
id?: number | null;
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -8560,7 +8565,7 @@ export type FindPrerecordTableLayoutMutation = {
export type HomographyInfoFragment = {
__typename?: "HomographyInfoGQL";
id?: number | null;
id: number;
frameIndex: number;
crop: {
__typename?: "BoundingBoxGQL";
@@ -15801,6 +15806,13 @@ export const GetUsageStatsDocument = gql`
retentionPrevActive
retentionReturned
}
cohorts {
weekStart
signups
activated7d
paid7d
activatedNotPaid7d
}
totalUsers
totalVideos
totalShots

View File

@@ -12,6 +12,13 @@ query getUsageStats($days: Int! = 30) {
retentionPrevActive
retentionReturned
}
cohorts {
weekStart
signups
activated7d
paid7d
activatedNotPaid7d
}
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!]!
@@ -1183,6 +1175,7 @@ type UsageStatsGQL {
totalVideos: Int!
totalShots: Int!
totalRuns: Int!
cohorts: [CohortStatsGQL!]!
windows: [UsageStatsWindowGQL!]!
daily: [UsageStatsDailyGQL!]!
processingLast24h: [ProcessingStatusCountGQL!]!
@@ -1201,6 +1194,14 @@ type FunnelStatsGQL {
retentionReturned: Int!
}
type CohortStatsGQL {
weekStart: Date!
signups: Int!
activated7d: Int!
paid7d: Int!
activatedNotPaid7d: Int!
}
type UsageStatsWindowGQL {
label: String!
newUsers: Int!