diff --git a/instruqt/challenge.go b/instruqt/challenge.go index 202d147..59a1cc0 100644 --- a/instruqt/challenge.go +++ b/instruqt/challenge.go @@ -6,25 +6,38 @@ import ( "github.com/shurcooL/graphql" ) +// challengeQuery represents the GraphQL query structure for retrieving a single challenge +// by its challenge ID. type challengeQuery struct { Challenge `graphql:"challenge(challengeID: $challengeId)"` } +// userChallengeQuery represents the GraphQL query structure for retrieving a single challenge +// associated with a specific user by user ID and challenge ID. type userChallengeQuery struct { Challenge `graphql:"challenge(userID: $userId, challengeID: $challengeId)"` } +// Challenge represents the data structure for an Instruqt challenge. type Challenge struct { - Id string `json:"id"` - Slug string `json:"slug"` - Title string `json:"title"` - Index int `json:"index"` - Status string `json:"status"` + Id string `json:"id"` // The unique identifier for the challenge. + Slug string `json:"slug"` // The slug for the challenge, which is a human-readable identifier. + Title string `json:"title"` // The title of the challenge. + Index int `json:"index"` // The index of the challenge in the track. + Status string `json:"status"` // The status of the challenge (e.g., "unlocked", "completed"). Track struct { - Id string + Id string // The identifier for the track associated with the challenge. } `json:"-"` } +// GetChallenge retrieves a challenge from Instruqt using its unique challenge ID. +// +// Parameters: +// - id: The unique identifier of the challenge to retrieve. +// +// Returns: +// - Challenge: The challenge details if found. +// - error: Any error encountered while retrieving the challenge. func (c *Client) GetChallenge(id string) (ch Challenge, err error) { if id == "" { return ch, nil @@ -43,6 +56,16 @@ func (c *Client) GetChallenge(id string) (ch Challenge, err error) { return q.Challenge, nil } +// GetUserChallenge retrieves a challenge associated with a specific user from Instruqt +// using the user's ID and the challenge's ID. +// +// Parameters: +// - userId: The unique identifier of the user. +// - id: The unique identifier of the challenge. +// +// Returns: +// - Challenge: The challenge details if found. +// - error: Any error encountered while retrieving the challenge. func (c *Client) GetUserChallenge(userId string, id string) (ch Challenge, err error) { if id == "" { return ch, nil @@ -62,6 +85,15 @@ func (c *Client) GetUserChallenge(userId string, id string) (ch Challenge, err e return q.Challenge, nil } +// SkipToChallenge allows a user to skip to a specific challenge in a track on Instruqt. +// +// Parameters: +// - userId: The unique identifier of the user. +// - trackId: The unique identifier of the track. +// - id: The unique identifier of the challenge to skip to. +// +// Returns: +// - error: Any error encountered while performing the skip operation. func (c *Client) SkipToChallenge(userId string, trackId string, id string) (err error) { var m struct { SkipToChallenge struct { diff --git a/instruqt/client.go b/instruqt/client.go index c451eae..bcfc735 100644 --- a/instruqt/client.go +++ b/instruqt/client.go @@ -9,20 +9,32 @@ import ( "github.com/shurcooL/graphql" ) +// GraphQLClient is an interface that defines the methods for interacting with +// a GraphQL API, including querying and mutating data. type GraphQLClient interface { Query(ctx context.Context, q interface{}, variables map[string]interface{}) error Mutate(ctx context.Context, m interface{}, variables map[string]interface{}) error } +// Client represents the Instruqt API client, which provides methods to +// interact with the Instruqt platform. It includes a GraphQL client, logging capabilities, +// and the team slug to identify which team's data to interact with. type Client struct { - GraphQLClient GraphQLClient - - LogClient *logging.Client - InfoLogger *log.Logger - - TeamSlug string + GraphQLClient GraphQLClient // The GraphQL client used to execute queries and mutations. + LogClient *logging.Client // The client for logging to Google Cloud Logging. + InfoLogger *log.Logger // Logger for informational messages. + TeamSlug string // The slug identifier for the team within Instruqt. } +// NewClient creates a new instance of the Instruqt API client. It initializes +// the GraphQL client with the provided API token and team slug. +// +// Parameters: +// - token: The API token used for authentication with the Instruqt GraphQL API. +// - teamSlug: The slug identifier for the team. +// +// Returns: +// - A pointer to the newly created Client instance. func NewClient(token string, teamSlug string) *Client { httpClient := &http.Client{} httpClient.Transport = &BearerTokenRoundTripper{ @@ -35,11 +47,21 @@ func NewClient(token string, teamSlug string) *Client { } } +// BearerTokenRoundTripper is a custom HTTP RoundTripper that adds a Bearer token +// for authorization in the HTTP request headers. type BearerTokenRoundTripper struct { - Transport http.RoundTripper - Token string + Transport http.RoundTripper // The underlying transport to use for HTTP requests. + Token string // The Bearer token for authorization. } +// RoundTrip executes a single HTTP transaction, adding the Authorization header +// with the Bearer token to the request before forwarding it to the underlying transport. +// +// Parameters: +// - req: The HTTP request to be sent. +// +// Returns: +// - An HTTP response and any error encountered while making the request. func (rt *BearerTokenRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Set("Authorization", "Bearer "+rt.Token) return rt.Transport.RoundTrip(req) diff --git a/instruqt/invite.go b/instruqt/invite.go index f1ad542..70f203d 100644 --- a/instruqt/invite.go +++ b/instruqt/invite.go @@ -7,32 +7,45 @@ import ( "github.com/shurcooL/graphql" ) +// inviteQuery represents the GraphQL query structure for retrieving a single +// track invite by its invite ID. type inviteQuery struct { TrackInvite `graphql:"trackInvite(inviteID: $inviteId)"` } +// TrackInvite represents the data structure for an Instruqt track invite. type TrackInvite struct { - Id string - PublicTitle string - RuntimeParameters struct { - EnvironmentVariables []variable + Id string // The unique identifier for the invite. + PublicTitle string // The public title of the track invite. + RuntimeParameters struct { // The runtime parameters associated with the invite. + EnvironmentVariables []variable // Environment variables used during the invite session. } - Claims []TrackInviteClaim + Claims []TrackInviteClaim // A list of claims associated with the track invite. } +// TrackInviteClaim represents a claim made by a user for a specific track invite. type TrackInviteClaim struct { - Id string - User struct { - Id string + Id string // The unique identifier of the claim. + User struct { // Information about the user who made the claim. + Id string // The unique identifier of the user. } - ClaimedAt time.Time + ClaimedAt time.Time // The timestamp when the claim was made. } +// variable represents an environment variable key-value pair. type variable struct { - Key string - Value string + Key string // The key of the environment variable. + Value string // The value of the environment variable. } +// GetInvite retrieves a track invite from Instruqt using its unique invite ID. +// +// Parameters: +// - inviteId: The unique identifier of the track invite to retrieve. +// +// Returns: +// - TrackInvite: The track invite details if found. +// - error: Any error encountered while retrieving the invite. func (c *Client) GetInvite(inviteId string) (i TrackInvite, err error) { if inviteId == "" { return i, nil @@ -51,10 +64,17 @@ func (c *Client) GetInvite(inviteId string) (i TrackInvite, err error) { return q.TrackInvite, nil } +// invitesQuery represents the GraphQL query structure for retrieving all track invites +// for a specific team. type invitesQuery struct { TrackInvites []TrackInvite `graphql:"trackInvites(teamSlug: $teamSlug)"` } +// GetInvites retrieves all track invites for the specified team slug from Instruqt. +// +// Returns: +// - []TrackInvite: A list of track invites for the team. +// - error: Any error encountered while retrieving the invites. func (c *Client) GetInvites() (i []TrackInvite, err error) { var q invitesQuery variables := map[string]interface{}{ diff --git a/instruqt/play.go b/instruqt/play.go index 95f10b1..0f7bf07 100644 --- a/instruqt/play.go +++ b/instruqt/play.go @@ -7,61 +7,79 @@ import ( "github.com/shurcooL/graphql" ) +// playType defines a custom type for play modes on Instruqt. type playType string +// Constants representing different types of plays. const ( - PlayTypeAll playType = "ALL" - PlayTypeDeveloper playType = "DEVELOPER" - PlayTypeNormal playType = "NORMAL" + PlayTypeAll playType = "ALL" // Represents all play types. + PlayTypeDeveloper playType = "DEVELOPER" // Represents developer-specific play types. + PlayTypeNormal playType = "NORMAL" // Represents normal play types. ) +// playQuery represents the GraphQL query structure for retrieving play reports +// with specific filters like team slug, date range, and pagination. type playQuery struct { PlayReports `graphql:"playReports(input: {teamSlug: $teamSlug, dateRangeFilter: {from: $from, to: $to}, pagination: {skip: $skip, take: $take}})"` } +// PlayReports represents a collection of play reports retrieved from Instruqt. type PlayReports struct { - Items []PlayReport - TotalItems int + Items []PlayReport // A list of play reports. + TotalItems int // The total number of play reports available. } +// PlayReport represents the data structure for a single play report on Instruqt. type PlayReport struct { - Id string + Id string // The unique identifier for the play report. Track struct { - Id string + Id string // The unique identifier of the track associated with the play. } TrackInvite struct { - Id string + Id string // The unique identifier of the track invite associated with the play. } User struct { - Id string + Id string // The unique identifier of the user associated with the play. } - CompletionPercent float64 - TotalChallenges int - CompletedChallenges int - TimeSpent int - StoppedReason string - Mode string - StartedAt time.Time + CompletionPercent float64 // The percentage of the play that has been completed. + TotalChallenges int // The total number of challenges in the play. + CompletedChallenges int // The number of challenges completed by the user in the play. + TimeSpent int // The total time spent on the play, in seconds. + StoppedReason string // The reason why the play was stopped (if applicable). + Mode string // The mode of the play (e.g., NORMAL, DEVELOPER). + StartedAt time.Time // The time when the play started. - Activity []struct { - Time time.Time - Message string + Activity []struct { // A list of activities performed during the play. + Time time.Time // The time when the activity occurred. + Message string // A message describing the activity. } - PlayReview struct { - Id string - Score int - Content string + PlayReview struct { // The review details for the play, if available. + Id string // The unique identifier of the play review. + Score int // The score given in the play review. + Content string // The content of the play review. } - CustomParameters []struct { - Key string - Value string + CustomParameters []struct { // Custom parameters associated with the play. + Key string // The key of the custom parameter. + Value string // The value of the custom parameter. } } -// TODO: playTypes +// GetPlays retrieves a list of play reports from Instruqt for the specified team, +// within a given date range, and using pagination parameters. +// +// Parameters: +// - from: The start date of the date range filter. +// - to: The end date of the date range filter. +// - take: The number of play reports to retrieve in one call. +// - skip: The number of play reports to skip before starting to retrieve. +// +// Returns: +// - []PlayReport: A list of play reports that match the given criteria. +// - int: The total number of play reports available for the given criteria. +// - error: Any error encountered while retrieving the play reports. func (c *Client) GetPlays(from time.Time, to time.Time, take int, skip int) (plays []PlayReport, totalItems int, err error) { variables := map[string]interface{}{ "teamSlug": graphql.String(c.TeamSlug), diff --git a/instruqt/sandbox.go b/instruqt/sandbox.go index f0829e3..f1f440c 100644 --- a/instruqt/sandbox.go +++ b/instruqt/sandbox.go @@ -7,28 +7,45 @@ import ( "github.com/shurcooL/graphql" ) +// sandboxVarQuery represents the GraphQL query structure for retrieving a single +// sandbox variable based on the sandbox ID, hostname, and key. type sandboxVarQuery struct { GetSandboxVariable SandboxVar `graphql:"getSandboxVariable(sandboxID: $sandboxID, hostname: $hostname, key: $key)"` } +// SandboxVar represents a key-value pair for a variable within a sandbox environment. type SandboxVar struct { - Key string - Value string + Key string // The key of the sandbox variable. + Value string // The value of the sandbox variable. } +// sandboxesQuery represents the GraphQL query structure for retrieving all sandboxes +// associated with a specific team. type sandboxesQuery struct { Sandboxes struct { - Nodes []Sandbox + Nodes []Sandbox // A list of sandboxes retrieved by the query. } `graphql:"sandboxes(teamSlug: $teamSlug)"` } +// Sandbox represents a sandbox environment within Instruqt, including details +// about its state, associated track, and invite. type Sandbox struct { - Last_Activity_At time.Time - State string - Track SandboxTrack - Invite TrackInvite + Last_Activity_At time.Time // The timestamp of the last activity in the sandbox. + State string // The current state of the sandbox (e.g., "running", "stopped"). + Track SandboxTrack // The track associated with the sandbox. + Invite TrackInvite // The invite details associated with the sandbox. } +// GetSandboxVariable retrieves a specific variable from a sandbox environment +// using the sandbox ID and the variable's key. +// +// Parameters: +// - playID: The unique identifier of the sandbox environment. +// - key: The key of the sandbox variable to retrieve. +// +// Returns: +// - string: The value of the requested sandbox variable. +// - error: Any error encountered while retrieving the variable. func (c *Client) GetSandboxVariable(playID string, key string) (v string, err error) { if playID == "" || key == "" { return v, nil @@ -51,6 +68,11 @@ func (c *Client) GetSandboxVariable(playID string, key string) (v string, err er return q.GetSandboxVariable.Value, nil } +// GetSandboxes retrieves all sandboxes associated with the team slug defined in the client. +// +// Returns: +// - []Sandbox: A list of sandboxes for the team. +// - error: Any error encountered while retrieving the sandboxes. func (c *Client) GetSandboxes() (s []Sandbox, err error) { var q sandboxesQuery variables := map[string]interface{}{ diff --git a/instruqt/team.go b/instruqt/team.go index 191b612..79d994a 100644 --- a/instruqt/team.go +++ b/instruqt/team.go @@ -7,12 +7,19 @@ import ( "github.com/shurcooL/graphql" ) +// teamQuery represents the GraphQL query structure for retrieving the TPG public key +// associated with a specific team identified by its slug. type teamQuery struct { Team struct { - TPGPublicKey graphql.String `graphql:"tpgPublicKey"` + TPGPublicKey graphql.String `graphql:"tpgPublicKey"` // The TPG public key of the team. } `graphql:"team(teamSlug: $teamSlug)"` } +// GetTPGPublicKey retrieves the TPG public key for the team associated with the client. +// +// Returns: +// - string: The TPG public key of the team. +// - error: Any error encountered while retrieving the TPG public key. func (c *Client) GetTPGPublicKey() (string, error) { var q teamQuery variables := map[string]interface{}{ diff --git a/instruqt/track.go b/instruqt/track.go index f8f1038..032331d 100644 --- a/instruqt/track.go +++ b/instruqt/track.go @@ -8,80 +8,101 @@ import ( "github.com/shurcooL/graphql" ) +// trackQuery represents the GraphQL query structure for retrieving a single +// track by its track ID. type trackQuery struct { Track `graphql:"track(trackID: $trackId)"` } +// userTrackQueryWithChallenges represents the GraphQL query structure for retrieving +// a user's specific track along with its challenges by track ID, user ID, and organization slug. type userTrackQueryWithChallenges struct { Track SandboxTrack `graphql:"track(trackID: $trackId, userID: $userId, organizationSlug: $organizationSlug)"` } +// trackQueryBySlug represents the GraphQL query structure for retrieving a single +// track by its slug and team slug. type trackQueryBySlug struct { Track `graphql:"track(trackSlug: $trackSlug, teamSlug: $teamSlug)"` } +// tracksQuery represents the GraphQL query structure for retrieving all tracks +// associated with a specific organization slug. type tracksQuery struct { Tracks []Track `graphql:"tracks(organizationSlug: $organizationSlug)"` } +// Track represents the data structure for an Instruqt track. type Track struct { - Slug string - Id string - Icon string - Title string - Description string - Teaser string - Level string - Embed_Token string - Statistics struct { - Average_review_score float32 - } - TrackTags []TrackTag - TrackReviews struct { + Slug string // The slug identifier for the track. + Id string // The unique identifier for the track. + Icon string // The icon associated with the track. + Title string // The title of the track. + Description string // The description of the track. + Teaser string // A teaser or short description of the track. + Level string // The difficulty level of the track. + Embed_Token string // The token used for embedding the track. + Statistics struct { // Statistics about the track. + Average_review_score float32 // The average review score of the track. + } + TrackTags []TrackTag // A list of tags associated with the track. + TrackReviews struct { // A collection of reviews for the track. TotalCount int Nodes []Review } } +// TrackTag represents a tag associated with an Instruqt track. type TrackTag struct { - Value string + Value string // The value of the tag. } +// SandboxTrack represents a track in a sandbox environment, including its details +// and associated challenges. type SandboxTrack struct { - Id string - Slug string - Icon string - Title string - Description string - Teaser string - Level string - Embed_Token string - Statistics struct { - Average_review_score float32 - } - TrackTags []struct { + Id string // The unique identifier for the sandbox track. + Slug string // The slug identifier for the sandbox track. + Icon string // The icon associated with the sandbox track. + Title string // The title of the sandbox track. + Description string // The description of the sandbox track. + Teaser string // A teaser or short description of the sandbox track. + Level string // The difficulty level of the sandbox track. + Embed_Token string // The token used for embedding the sandbox track. + Statistics struct { // Statistics about the sandbox track. + Average_review_score float32 // The average review score of the sandbox track. + } + TrackTags []struct { // A list of tags associated with the sandbox track. Value string } - TrackReviews struct { + TrackReviews struct { // A collection of reviews for the sandbox track. TotalCount int Nodes []Review } - Challenges []Challenge - Status string - Started time.Time - Completed time.Time - Participant struct { + Challenges []Challenge // A list of challenges associated with the sandbox track. + Status string // The current status of the sandbox track. + Started time.Time // The timestamp when the sandbox track was started. + Completed time.Time // The timestamp when the sandbox track was completed. + Participant struct { // Information about the participant of the sandbox track. Id string } } +// Review represents a review for an Instruqt track. type Review struct { - Score int `json:"score"` - Content string `json:"content"` - Created_At time.Time `json:"created_at"` - Updated_At time.Time `json:"updated_at"` + Score int `json:"score"` // The score given in the review. + Content string `json:"content"` // The content of the review. + Created_At time.Time `json:"created_at"` // The timestamp when the review was created. + Updated_At time.Time `json:"updated_at"` // The timestamp when the review was last updated. } +// GetTrack retrieves a track from Instruqt using its unique track ID. +// +// Parameters: +// - trackId: The unique identifier of the track to retrieve. +// +// Returns: +// - Track: The track details if found. +// - error: Any error encountered while retrieving the track. func (c *Client) GetTrack(trackId string) (t Track, err error) { if trackId == "" { return t, nil @@ -100,6 +121,16 @@ func (c *Client) GetTrack(trackId string) (t Track, err error) { return q.Track, nil } +// GetUserTrack retrieves a track for a specific user, including its challenges, +// using the user's ID and the track's ID. +// +// Parameters: +// - userId: The unique identifier of the user. +// - trackId: The unique identifier of the track. +// +// Returns: +// - SandboxTrack: The track details with challenges if found. +// - error: Any error encountered while retrieving the track. func (c *Client) GetUserTrack(userId string, trackId string) (t SandboxTrack, err error) { if trackId == "" { return t, nil @@ -120,6 +151,14 @@ func (c *Client) GetUserTrack(userId string, trackId string) (t SandboxTrack, er return q.Track, nil } +// GetTrackBySlug retrieves a track from Instruqt using its slug and team slug. +// +// Parameters: +// - trackSlug: The slug identifier of the track to retrieve. +// +// Returns: +// - Track: The track details if found. +// - error: Any error encountered while retrieving the track. func (c *Client) GetTrackBySlug(trackSlug string) (t Track, err error) { if trackSlug == "" { return t, nil @@ -139,6 +178,16 @@ func (c *Client) GetTrackBySlug(trackSlug string) (t Track, err error) { return q.Track, nil } +// GetTrackUnlockedChallenge retrieves the first unlocked challenge for a specific +// user's track. +// +// Parameters: +// - userId: The unique identifier of the user. +// - trackId: The unique identifier of the track. +// +// Returns: +// - Challenge: The first unlocked challenge found. +// - error: Any error encountered while retrieving the challenge. func (c *Client) GetTrackUnlockedChallenge(userId string, trackId string) (challenge Challenge, err error) { track, err := c.GetUserTrack(userId, trackId) if err != nil { @@ -155,6 +204,11 @@ func (c *Client) GetTrackUnlockedChallenge(userId string, trackId string) (chall return } +// GetTracks retrieves all tracks associated with the client's team slug. +// +// Returns: +// - []Track: A list of tracks for the team. +// - error: Any error encountered while retrieving the tracks. func (c *Client) GetTracks() (t []Track, err error) { var q tracksQuery variables := map[string]interface{}{ @@ -169,6 +223,14 @@ func (c *Client) GetTracks() (t []Track, err error) { return q.Tracks, nil } +// GenerateOneTimePlayToken generates a one-time play token for a specific track. +// +// Parameters: +// - trackId: The unique identifier of the track. +// +// Returns: +// - string: The generated one-time play token. +// - error: Any error encountered while generating the token. func (c *Client) GenerateOneTimePlayToken(trackId string) (token string, err error) { var m struct { GenerateOneTimePlayToken string `graphql:"generateOneTimePlayToken(trackID: $trackID)"` diff --git a/instruqt/user.go b/instruqt/user.go index c1467c4..6baf03a 100644 --- a/instruqt/user.go +++ b/instruqt/user.go @@ -8,28 +8,40 @@ import ( "github.com/shurcooL/graphql" ) +// userInfoQuery represents the GraphQL query structure for retrieving user information +// by the user's unique ID. type userInfoQuery struct { User `graphql:"user(userID: $userID)"` } +// User represents the data structure for an Instruqt user. type User struct { - Details struct { - FirstName graphql.String - LastName graphql.String - Email graphql.String + Details struct { // Detailed user information associated with a specific team. + FirstName graphql.String // The first name of the user. + LastName graphql.String // The last name of the user. + Email graphql.String // The email of the user. } `graphql:"details(teamSlug: $teamSlug)"` - Profile struct { - Display_Name graphql.String - Email graphql.String + Profile struct { // Profile-level information for the user. + Display_Name graphql.String // The display name of the user. + Email graphql.String // The email of the user. } } +// UserInfo represents a simplified user information structure. type UserInfo struct { - FirstName string - LastName string - Email string + FirstName string // The first name of the user. + LastName string // The last name of the user. + Email string // The email of the user. } +// GetUserInfo retrieves the user information from Instruqt using the user's unique ID. +// +// Parameters: +// - userId: The unique identifier of the user. +// +// Returns: +// - UserInfo: The user's information including first name, last name, and email. +// - error: Any error encountered while retrieving the user information. func (c *Client) GetUserInfo(userId string) (u UserInfo, err error) { var q userInfoQuery ctx := context.Background()