Compare commits

...

1 Commits

Author SHA1 Message Date
4ff2db1ef4 Add simulateShot query, cue strike and shot projection types
All checks were successful
Tests / Tests (pull_request) Successful in 12s
Generated from backend strawberry definitions for the shot simulation
feature (image -> pooltool scenario -> projected outcome). Backend PR:
shot-simulation-stubs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 16:12:11 -07:00
2 changed files with 129 additions and 0 deletions

View File

@@ -88,6 +88,12 @@ export type AppleIapSubscriptionOptionsGql = {
productIds: Array<Scalars["String"]["output"]>;
};
export type BallTrajectoryGql = {
__typename?: "BallTrajectoryGQL";
ballId: Scalars["Int"]["output"];
points: Array<TrajectoryPointGql>;
};
export type BankFeaturesGql = {
__typename?: "BankFeaturesGQL";
bankAngle: Scalars["Float"]["output"];
@@ -268,6 +274,14 @@ export type CueObjectFeaturesGql = {
spinType?: Maybe<SpinTypeEnum>;
};
export type CueStrikeInputGql = {
a?: Scalars["Float"]["input"];
b?: Scalars["Float"]["input"];
phi: Scalars["Float"]["input"];
theta?: Scalars["Float"]["input"];
v0: Scalars["Float"]["input"];
};
export type DateRangeFilter = {
greaterThan?: InputMaybe<Scalars["Date"]["input"]>;
greaterThanEqualTo?: InputMaybe<Scalars["Date"]["input"]>;
@@ -2888,6 +2902,7 @@ export type Query = {
myVideoExports: Array<VideoExportJobGql>;
notifications: NotificationConnection;
ruleSets: Array<RuleSet>;
simulateShot: ShotProjectionGql;
unreadNotificationCount: Scalars["Int"]["output"];
videoExportJob?: Maybe<VideoExportJobGql>;
videoPlayerClusters: Array<PlayerClusterGql>;
@@ -3077,6 +3092,10 @@ export type QueryNotificationsArgs = {
offset?: Scalars["Int"]["input"];
};
export type QuerySimulateShotArgs = {
simulationInput: SimulateShotInputGql;
};
export type QueryVideoExportJobArgs = {
jobId: Scalars["Int"]["input"];
};
@@ -3340,6 +3359,14 @@ export type ShotMoveInput = {
shotId: Scalars["Int"]["input"];
};
export type ShotProjectionGql = {
__typename?: "ShotProjectionGQL";
events: Array<SimulationEventGql>;
finalState: Array<SimulationBallStateGql>;
pottedBallIds: Array<Scalars["Int"]["output"]>;
trajectories: Array<BallTrajectoryGql>;
};
export type ShotsOrderingComponent =
| {
difficulty: FloatOrdering;
@@ -3390,6 +3417,42 @@ export type ShotsOrderingComponent =
videoId: IntOrdering;
};
export type SimulateShotInputGql = {
b64Image?: InputMaybe<Scalars["String"]["input"]>;
balls?: InputMaybe<Array<SimulationBallStateInputGql>>;
cueBallId: Scalars["Int"]["input"];
strike: CueStrikeInputGql;
tableSize?: InputMaybe<Scalars["Float"]["input"]>;
useHomography?: InputMaybe<HomographyInputGql>;
};
export type SimulationBallStateGql = {
__typename?: "SimulationBallStateGQL";
ballId: Scalars["Int"]["output"];
position: Array<Scalars["Float"]["output"]>;
};
export type SimulationBallStateInputGql = {
ballId: Scalars["Int"]["input"];
position: Array<Scalars["Float"]["input"]>;
};
export type SimulationEventGql = {
__typename?: "SimulationEventGQL";
ballIds: Array<Scalars["Int"]["output"]>;
eventType: SimulationEventType;
position?: Maybe<Array<Scalars["Float"]["output"]>>;
time: Scalars["Float"]["output"];
};
export enum SimulationEventType {
BallBall = "BALL_BALL",
BallCushion = "BALL_CUSHION",
BallPocket = "BALL_POCKET",
BallStop = "BALL_STOP",
StickBall = "STICK_BALL",
}
export type SpinTypeBreakdownGql = {
__typename?: "SpinTypeBreakdownGQL";
center: Scalars["Int"]["output"];
@@ -3566,6 +3629,12 @@ export type TooManyProfileImageUploadsErr = {
linksRequested: Scalars["Int"]["output"];
};
export type TrajectoryPointGql = {
__typename?: "TrajectoryPointGQL";
position: Array<Scalars["Float"]["output"]>;
time: Scalars["Float"]["output"];
};
export type UpdateAnnotationInputGql = {
name: Scalars["String"]["input"];
notes?: InputMaybe<Scalars["String"]["input"]>;

View File

@@ -66,6 +66,7 @@ type Query {
tableSize: Float = 100
useHomography: HomographyInputGQL = null
): TableStateGQL!
simulateShot(simulationInput: SimulateShotInputGQL!): ShotProjectionGQL!
getOrderedShots(
filterInput: FilterInput!
ids: [Int!] = null
@@ -970,6 +971,65 @@ input IntPoint2DInput {
y: Int!
}
type ShotProjectionGQL {
trajectories: [BallTrajectoryGQL!]!
events: [SimulationEventGQL!]!
finalState: [SimulationBallStateGQL!]!
pottedBallIds: [Int!]!
}
type BallTrajectoryGQL {
ballId: Int!
points: [TrajectoryPointGQL!]!
}
type TrajectoryPointGQL {
time: Float!
position: [Float!]!
}
type SimulationEventGQL {
eventType: SimulationEventType!
time: Float!
ballIds: [Int!]!
position: [Float!]
}
enum SimulationEventType {
STICK_BALL
BALL_BALL
BALL_CUSHION
BALL_POCKET
BALL_STOP
}
type SimulationBallStateGQL {
ballId: Int!
position: [Float!]!
}
input SimulateShotInputGQL {
cueBallId: Int!
strike: CueStrikeInputGQL!
balls: [SimulationBallStateInputGQL!] = null
b64Image: String = null
useHomography: HomographyInputGQL = null
tableSize: Float = null
}
input CueStrikeInputGQL {
v0: Float!
phi: Float!
theta: Float! = 0
a: Float! = 0
b: Float! = 0
}
input SimulationBallStateInputGQL {
ballId: Int!
position: [Float!]!
}
type GetShotsResult {
shots: [ShotGQL!]!
count: Int