Compare commits

..

1 Commits

Author SHA1 Message Date
669958178d scope upload quotas
All checks were successful
Tests / Tests (pull_request) Successful in 11s
2026-04-14 15:40:15 -07:00
7 changed files with 90 additions and 1097 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -31,32 +31,41 @@ fragment VideoCardFields on VideoGQL {
} }
name name
screenshotUri screenshotUri
totalShotsMade
totalShots totalShots
makePercentage makePercentage
averageTimeBetweenShots averageTimeBetweenShots
averageDifficulty averageDifficulty
createdAt
updatedAt
startTime startTime
endTime
private private
elapsedTime elapsedTime
screenshotUri
stream { stream {
id id
lastIntendedSegmentBound lastIntendedSegmentBound
isCompleted
streamSegmentType streamSegmentType
} }
tableSize tableSize
pocketSize pocketSize
tags { tags {
name
tagClasses { tagClasses {
name name
} }
} name
playerSummaries {
...PlayerSummaryFields
} }
currentProcessing { currentProcessing {
id id
errors {
message
}
status status
statuses {
status
}
} }
reactions { reactions {
videoId videoId
@@ -101,27 +110,6 @@ query GetVideoFeedSessionCount(
} }
} }
# Minimal query for the Home recency nudge ("you haven't recorded in N days").
# Only the most recent session's start time — avoids pulling the full
# VideoCardFields payload (reactions, comments, player summaries, etc.).
query GetLastSessionDate(
$filters: VideoFilterInput = null
$includePrivate: IncludePrivateEnum = MINE
$feedInput: VideoFeedInputGQL = null
) {
getFeedVideos(
limit: 1
filters: $filters
includePrivate: $includePrivate
feedInput: $feedInput
) {
videos {
id
startTime
}
}
}
query GetVideoFeed( query GetVideoFeed(
$limit: Int! = 5 $limit: Int! = 5
$after: String = null $after: String = null

View File

@@ -20,15 +20,8 @@ mutation CreateSubscription($priceId: String!) {
} }
} }
mutation CreateCustomerPortalSession {
createCustomerPortalSession {
portalUrl
}
}
query GetAvailableSubscriptionOptions { query GetAvailableSubscriptionOptions {
getAvailableSubscriptionOptions { getAvailableSubscriptionOptions {
trialPeriodDays
products { products {
id id
name name

View File

@@ -1,52 +0,0 @@
fragment PlayerSummaryFields on PlayerSummaryGQL {
clusterId
userId
username
profileImageUri
representativeFullFrameUrl
totalShots
totalShotsMade
makePercentage
score
longestRun
averageDifficulty
averageTimeBetweenShots
}
fragment PlayerClusterShotFields on PlayerClusterShotGQL {
shotId
bboxX1
bboxY1
bboxX2
bboxY2
confidence
isConfirmed
cropUrl
fullFrameUrl
}
fragment PlayerClusterFields on PlayerClusterGQL {
videoId
clusterId
nShots
userId
username
profileImageUri
confirmed
score
shots {
...PlayerClusterShotFields
}
}
query VideoPlayerClusters($videoId: Int!) {
videoPlayerClusters(videoId: $videoId) {
...PlayerClusterFields
}
}
mutation FinalizePlayerAssignments($input: FinalizePlayerAssignmentsInput!) {
finalizePlayerAssignments(input: $input) {
...PlayerClusterFields
}
}

View File

@@ -132,38 +132,6 @@ query GetShotsByIds($ids: [Int!]!) {
} }
} }
# Lightweight clip boundaries for condensed session playback. The inline
# session player only needs each shot's frame/time window to seek between
# shots — this skips the heavy ShotWithAllFeatures payload (cue/pocketing
# features, serialized shot paths, annotations, nested video/playlist). The
# startTime/endTime @client resolvers derive their values from the frame
# fields + the video (looked up internally), so this is all they require.
fragment ShotClipRange on ShotGQL {
id
videoId
startFrame
endFrame
startTime @client
endTime @client
}
query GetShotClipRanges(
$filterInput: FilterInput!
$shotsOrdering: GetShotsOrdering
$limit: Int
) {
getOrderedShots(
filterInput: $filterInput
shotsOrdering: $shotsOrdering
limit: $limit
) {
count
shots {
...ShotClipRange
}
}
}
fragment ShotWithAllFeatures on ShotGQL { fragment ShotWithAllFeatures on ShotGQL {
id id
videoId videoId

View File

@@ -83,9 +83,6 @@ query GetVideoDetails($videoId: Int!) {
} }
name name
} }
playerSummaries {
...PlayerSummaryFields
}
} }
} }
@@ -139,15 +136,6 @@ query GetVideoSocialDetailsById($videoId: Int!) {
} }
} }
# Full card payload for a single video — reuses the same VideoCardFields
# fragment the feed list uses, so the session-detail meta header shares one
# source of truth (and the normalized Apollo cache) with the feed card.
query GetVideoCard($videoId: Int!) {
getVideo(videoId: $videoId) {
...VideoCardFields
}
}
query GetVideos($videoIds: [Int!]!) { query GetVideos($videoIds: [Int!]!) {
getVideos(videoIds: $videoIds) { getVideos(videoIds: $videoIds) {
...VideoStreamMetadata ...VideoStreamMetadata

View File

@@ -28,7 +28,7 @@ type Query {
getLongestRunsLeaderboard( getLongestRunsLeaderboard(
interval: TimeInterval = null interval: TimeInterval = null
when: DateTime = null when: DateTime = null
limit: Int! = 50 limit: Int! = 100
requiredTags: [String!] = null requiredTags: [String!] = null
): RunLeaderboardGQL! ): RunLeaderboardGQL!
getMakesLeaderboard( getMakesLeaderboard(
@@ -49,7 +49,6 @@ type Query {
limit: Int! = 500 limit: Int! = 500
countRespectsLimit: Boolean! = false countRespectsLimit: Boolean! = false
): GetRunsResult! ): GetRunsResult!
videoPlayerClusters(videoId: Int!): [PlayerClusterGQL!]!
getShotAnnotationTypes(errorTypes: Boolean = false): [ShotAnnotationTypeGQL!]! getShotAnnotationTypes(errorTypes: Boolean = false): [ShotAnnotationTypeGQL!]!
getTableState( getTableState(
b64Image: String! b64Image: String!
@@ -406,7 +405,6 @@ type VideoGQL {
currentProcessing: VideoProcessingGQL currentProcessing: VideoProcessingGQL
reactions: [ReactionGQL!]! reactions: [ReactionGQL!]!
comments: [CommentGQL!]! comments: [CommentGQL!]!
playerSummaries: [PlayerSummaryGQL!]!
} }
type ShotGQL { type ShotGQL {
@@ -666,21 +664,6 @@ type CommentGQL {
replies: [CommentGQL!]! replies: [CommentGQL!]!
} }
type PlayerSummaryGQL {
clusterId: Int!
userId: Int
username: String
profileImageUri: String
representativeFullFrameUrl: String
totalShots: Int!
totalShotsMade: Int!
makePercentage: Float!
score: Int
longestRun: Int!
averageDifficulty: Float
averageTimeBetweenShots: Float
}
type DeployedConfigGQL { type DeployedConfigGQL {
allowNewUsers: Boolean! allowNewUsers: Boolean!
firebase: Boolean! firebase: Boolean!
@@ -877,30 +860,6 @@ input DatetimeOrdering {
startingAt: DateTime = null startingAt: DateTime = null
} }
type PlayerClusterGQL {
videoId: Int!
clusterId: Int!
nShots: Int!
userId: Int
username: String
profileImageUri: String
confirmed: Boolean!
score: Int
shots: [PlayerClusterShotGQL!]!
}
type PlayerClusterShotGQL {
shotId: Int!
bboxX1: Int!
bboxY1: Int!
bboxX2: Int!
bboxY2: Int!
confidence: Float!
isConfirmed: Boolean!
cropUrl: String
fullFrameUrl: String
}
type TableStateGQL { type TableStateGQL {
identifierToPosition: [[Float!]!]! identifierToPosition: [[Float!]!]!
homography: HomographyInfoGQL homography: HomographyInfoGQL
@@ -981,7 +940,6 @@ type UserRelationship {
type StripeSubscriptionOptionsGQL { type StripeSubscriptionOptionsGQL {
products: [StripeProductGQL!]! products: [StripeProductGQL!]!
trialPeriodDays: Int
} }
type StripeProductGQL { type StripeProductGQL {
@@ -1040,10 +998,17 @@ type QuotaStatusGQL {
durationUsedSeconds: Float! durationUsedSeconds: Float!
durationLimitSeconds: Int durationLimitSeconds: Int
maxVideoDurationSeconds: Int maxVideoDurationSeconds: Int
recordingPermission: UploadPermissionGQL!
importUploadPermission: UploadPermissionGQL!
durationRemainingSeconds: Float durationRemainingSeconds: Float
canUpload: Boolean! canUpload: Boolean!
} }
type UploadPermissionGQL {
allowed: Boolean!
reason: String
}
type UserPlayTimeGQL { type UserPlayTimeGQL {
totalSeconds: Float! totalSeconds: Float!
} }
@@ -1135,9 +1100,6 @@ type Mutation {
markAllNotificationsAsRead: Boolean! markAllNotificationsAsRead: Boolean!
markNotificationsAsRead(notificationIds: [Int!]!): Boolean! markNotificationsAsRead(notificationIds: [Int!]!): Boolean!
deleteNotification(notificationId: Int!): Boolean! deleteNotification(notificationId: Int!): Boolean!
finalizePlayerAssignments(
input: FinalizePlayerAssignmentsInput!
): [PlayerClusterGQL!]!
addAnnotationToShot( addAnnotationToShot(
shotId: Int! shotId: Int!
annotationName: String! annotationName: String!
@@ -1162,7 +1124,6 @@ type Mutation {
ensureStripeCustomerExists: UserGQL! ensureStripeCustomerExists: UserGQL!
deleteUser: Boolean! deleteUser: Boolean!
createSubscription(priceId: String!): CreateSubscriptionResultGQL! createSubscription(priceId: String!): CreateSubscriptionResultGQL!
createCustomerPortalSession: CreateCustomerPortalSessionResultGQL!
cancelSubscription: UserSubscriptionStatusGQL! cancelSubscription: UserSubscriptionStatusGQL!
grantManualEntitlement( grantManualEntitlement(
userId: Int! userId: Int!
@@ -1180,6 +1141,7 @@ type Mutation {
findPrerecordTableLayout(b64Image: String!, videoId: Int!): HomographyInfoGQL findPrerecordTableLayout(b64Image: String!, videoId: Int!): HomographyInfoGQL
createUploadStream( createUploadStream(
videoMetadata: VideoMetadataInput! videoMetadata: VideoMetadataInput!
uploadKind: UploadKindEnum = null
expectedDurationSeconds: Float = null expectedDurationSeconds: Float = null
): CreateUploadStreamReturn! ): CreateUploadStreamReturn!
getUploadLink(videoId: Int!, segmentIndex: Int!): GetUploadLinkReturn! getUploadLink(videoId: Int!, segmentIndex: Int!): GetUploadLinkReturn!
@@ -1209,23 +1171,6 @@ enum ReportReasonEnum {
OTHER OTHER
} }
input FinalizePlayerAssignmentsInput {
videoId: Int!
clusterAssignments: [ClusterAssignmentInput!]! = []
shotMoves: [ShotMoveInput!]! = []
}
input ClusterAssignmentInput {
clusterId: Int!
userId: Int = null
score: Int = null
}
input ShotMoveInput {
shotId: Int!
newClusterId: Int!
}
type AddShotAnnotationReturn { type AddShotAnnotationReturn {
value: SuccessfulAddAddShotAnnotationErrors! value: SuccessfulAddAddShotAnnotationErrors!
} }
@@ -1319,10 +1264,6 @@ type CreateSubscriptionResultGQL {
sessionId: String! sessionId: String!
} }
type CreateCustomerPortalSessionResultGQL {
portalUrl: String!
}
enum CancellationReasonEnum { enum CancellationReasonEnum {
DONT_PLAY_ENOUGH DONT_PLAY_ENOUGH
TOO_EXPENSIVE TOO_EXPENSIVE
@@ -1369,6 +1310,11 @@ input VideoResolution {
height: Int! height: Int!
} }
enum UploadKindEnum {
RECORDING
IMPORT
}
type GetUploadLinkReturn { type GetUploadLinkReturn {
value: UploadLinkGetUploadLinkErrors! value: UploadLinkGetUploadLinkErrors!
stream: UploadStreamGQL stream: UploadStreamGQL