Skip to content

Commit

Permalink
feat: add mutation collect special badgE
Browse files Browse the repository at this point in the history
  • Loading branch information
juliano-quatrin-nunes committed Jan 20, 2025
1 parent 5176067 commit 7a57edd
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Gamification
module Strategies
class CertifiedDelegate < Base
def verify_completion?
true
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Mutations
class CollectBadge < BaseMutation
argument :badge_id, ID, required: true
argument :badge_type, ID, required: true, description: "Type of the badge"

field :badge_earned, Boolean, null: true
field :errors, [String], null: false

def resolve(badge_id:, badge_type:)
badge = Gamification::BadgeReadModel.find_by(badge_id: badge_id)

unless badge
return {badge_earned: false, errors: ["Badge not found"]}
end

command_bus.call(
Gamification::CollectSpecialBadge.new(
badge_id: badge_id,
user_id: context[:current_user].id
)
)

{
badge_earned: true,
errors: []
}
rescue Gamification::SpecialBadge::VerificationFailedError
{
badge_earned: false,
errors: ["Badge requirements not met"]
}
rescue => e
{
badge_earned: false,
errors: [e.message]
}
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ class MutationType < Types::BaseObject
# Notifications
field :mark_notification_as_read, mutation: Mutations::MarkNotificationAsRead, preauthorize: {with: AuthenticatedGraphqlPolicy}
field :mark_all_notifications_as_read, mutation: Mutations::MarkAllNotificationsAsRead, preauthorize: {with: AuthenticatedGraphqlPolicy}

# Special Badges
field :collect_badge, mutation: Mutations::CollectBadge, preauthorize: {with: AuthenticatedGraphqlPolicy}
end
end
36 changes: 36 additions & 0 deletions apps/govquests-api/rails_app/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ type BadgeDisplayData {

union BadgeableUnion = Quest | Track

"""
Autogenerated input type of CollectBadge
"""
input CollectBadgeInput {
badgeId: ID!

"""
Type of the badge
"""
badgeType: ID!

"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
}

"""
Autogenerated return type of CollectBadge.
"""
type CollectBadgePayload {
badgeEarned: Boolean

"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
errors: [String!]!
}

"""
Autogenerated input type of CompleteActionExecution
"""
Expand Down Expand Up @@ -337,6 +367,12 @@ type MarkNotificationAsReadPayload {
}

type Mutation {
collectBadge(
"""
Parameters for CollectBadge
"""
input: CollectBadgeInput!
): CollectBadgePayload
completeActionExecution(
"""
Parameters for CompleteActionExecution
Expand Down
4 changes: 3 additions & 1 deletion apps/govquests-frontend/src/graphql-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export type introspection_types = {
'BadgeDisplayData': { kind: 'OBJECT'; name: 'BadgeDisplayData'; fields: { 'description': { name: 'description'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'imageUrl': { name: 'imageUrl'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'sequenceNumber': { name: 'sequenceNumber'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'title': { name: 'title'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; };
'BadgeableUnion': { kind: 'UNION'; name: 'BadgeableUnion'; fields: {}; possibleTypes: 'Quest' | 'Track'; };
'Boolean': unknown;
'CollectBadgeInput': { kind: 'INPUT_OBJECT'; name: 'CollectBadgeInput'; isOneOf: false; inputFields: [{ name: 'badgeId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'badgeType'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }]; };
'CollectBadgePayload': { kind: 'OBJECT'; name: 'CollectBadgePayload'; fields: { 'badgeEarned': { name: 'badgeEarned'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'clientMutationId': { name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'errors': { name: 'errors'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; }; } }; }; };
'CompleteActionExecutionInput': { kind: 'INPUT_OBJECT'; name: 'CompleteActionExecutionInput'; isOneOf: false; inputFields: [{ name: 'actionType'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }, { name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'discourseVerificationCompletionData'; type: { kind: 'INPUT_OBJECT'; name: 'DiscourseVerificationCompletionDataInput'; ofType: null; }; defaultValue: null }, { name: 'executionId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }, { name: 'gitcoinScoreCompletionData'; type: { kind: 'INPUT_OBJECT'; name: 'GitcoinScoreCompletionDataInput'; ofType: null; }; defaultValue: null }, { name: 'nonce'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; defaultValue: null }]; };
'CompleteActionExecutionPayload': { kind: 'OBJECT'; name: 'CompleteActionExecutionPayload'; fields: { 'actionExecution': { name: 'actionExecution'; type: { kind: 'OBJECT'; name: 'ActionExecution'; ofType: null; } }; 'clientMutationId': { name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'errors': { name: 'errors'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; }; } }; }; };
'CompletionDataInterface': { kind: 'INTERFACE'; name: 'CompletionDataInterface'; fields: { 'actionType': { name: 'actionType'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; possibleTypes: 'DiscourseVerificationCompletionData' | 'EmptyActionCompletionData' | 'GitcoinScoreCompletionData'; };
Expand All @@ -37,7 +39,7 @@ export type introspection_types = {
'MarkAllNotificationsAsReadPayload': { kind: 'OBJECT'; name: 'MarkAllNotificationsAsReadPayload'; fields: { 'clientMutationId': { name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'errors': { name: 'errors'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; }; } }; 'success': { name: 'success'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; }; } }; }; };
'MarkNotificationAsReadInput': { kind: 'INPUT_OBJECT'; name: 'MarkNotificationAsReadInput'; isOneOf: false; inputFields: [{ name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: null }, { name: 'deliveryMethod'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; }; defaultValue: "\"in_app\"" }, { name: 'notificationId'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; }; defaultValue: null }]; };
'MarkNotificationAsReadPayload': { kind: 'OBJECT'; name: 'MarkNotificationAsReadPayload'; fields: { 'clientMutationId': { name: 'clientMutationId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'errors': { name: 'errors'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; }; }; } }; 'notificationDelivery': { name: 'notificationDelivery'; type: { kind: 'OBJECT'; name: 'NotificationDelivery'; ofType: null; } }; }; };
'Mutation': { kind: 'OBJECT'; name: 'Mutation'; fields: { 'completeActionExecution': { name: 'completeActionExecution'; type: { kind: 'OBJECT'; name: 'CompleteActionExecutionPayload'; ofType: null; } }; 'generateSiweMessage': { name: 'generateSiweMessage'; type: { kind: 'OBJECT'; name: 'GenerateSiweMessagePayload'; ofType: null; } }; 'markAllNotificationsAsRead': { name: 'markAllNotificationsAsRead'; type: { kind: 'OBJECT'; name: 'MarkAllNotificationsAsReadPayload'; ofType: null; } }; 'markNotificationAsRead': { name: 'markNotificationAsRead'; type: { kind: 'OBJECT'; name: 'MarkNotificationAsReadPayload'; ofType: null; } }; 'signInWithEthereum': { name: 'signInWithEthereum'; type: { kind: 'OBJECT'; name: 'SignInWithEthereumPayload'; ofType: null; } }; 'signOut': { name: 'signOut'; type: { kind: 'OBJECT'; name: 'SignOutPayload'; ofType: null; } }; 'startActionExecution': { name: 'startActionExecution'; type: { kind: 'OBJECT'; name: 'StartActionExecutionPayload'; ofType: null; } }; }; };
'Mutation': { kind: 'OBJECT'; name: 'Mutation'; fields: { 'collectBadge': { name: 'collectBadge'; type: { kind: 'OBJECT'; name: 'CollectBadgePayload'; ofType: null; } }; 'completeActionExecution': { name: 'completeActionExecution'; type: { kind: 'OBJECT'; name: 'CompleteActionExecutionPayload'; ofType: null; } }; 'generateSiweMessage': { name: 'generateSiweMessage'; type: { kind: 'OBJECT'; name: 'GenerateSiweMessagePayload'; ofType: null; } }; 'markAllNotificationsAsRead': { name: 'markAllNotificationsAsRead'; type: { kind: 'OBJECT'; name: 'MarkAllNotificationsAsReadPayload'; ofType: null; } }; 'markNotificationAsRead': { name: 'markNotificationAsRead'; type: { kind: 'OBJECT'; name: 'MarkNotificationAsReadPayload'; ofType: null; } }; 'signInWithEthereum': { name: 'signInWithEthereum'; type: { kind: 'OBJECT'; name: 'SignInWithEthereumPayload'; ofType: null; } }; 'signOut': { name: 'signOut'; type: { kind: 'OBJECT'; name: 'SignOutPayload'; ofType: null; } }; 'startActionExecution': { name: 'startActionExecution'; type: { kind: 'OBJECT'; name: 'StartActionExecutionPayload'; ofType: null; } }; }; };
'Node': { kind: 'INTERFACE'; name: 'Node'; fields: { 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; }; possibleTypes: 'Notification' | 'NotificationDelivery'; };
'Notification': { kind: 'OBJECT'; name: 'Notification'; fields: { 'content': { name: 'content'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ISO8601DateTime'; ofType: null; }; } }; 'deliveries': { name: 'deliveries'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'NotificationDeliveryConnection'; ofType: null; }; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'ID'; ofType: null; }; } }; 'notificationType': { name: 'notificationType'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'status': { name: 'status'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; };
'NotificationConnection': { kind: 'OBJECT'; name: 'NotificationConnection'; fields: { 'edges': { name: 'edges'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'NotificationEdge'; ofType: null; }; } }; 'nodes': { name: 'nodes'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Notification'; ofType: null; }; } }; 'pageInfo': { name: 'pageInfo'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'PageInfo'; ofType: null; }; } }; }; };
Expand Down

0 comments on commit 7a57edd

Please sign in to comment.