Skip to content

Instantly share code, notes, and snippets.

@mmierzwa
Last active October 12, 2021 13:31
Show Gist options
  • Save mmierzwa/8ed76334c99571fbcc0ec4953e7b2d67 to your computer and use it in GitHub Desktop.
Save mmierzwa/8ed76334c99571fbcc0ec4953e7b2d67 to your computer and use it in GitHub Desktop.
schema {
query: Query
mutation: Mutation
}
type Query {
session(id: ID!): Session
}
type Mutation {
finishSessionByUser(input: FinishSessionByUserInput!): Session
@aws_cognito_user_pools(cognito_groups: ["user_group"])
finishSessionByTutor(input: FinishSessionByTutorInput!): Session
@aws_cognito_user_pools(cognito_groups: ["tutor_group"])
# "rate session by user"
# includes reporting the tutor
rateSession(input: RateSessionInput!): Session
@aws_cognito_user_pools(cognito_groups: ["user_group"])
# "report session by tutor"
# in fact, it's more about reporting the user, not the session
reportSession(input: ReportSessionInput!): Session
@aws_cognito_user_pools(cognito_groups: ["tutor_group"])
# the tutor disconnection process is handled with the internal API + broadcastSessionUpdate
}
type Session {
id: ID!
# ...
state: SessionState!
stateLog: [SessionStateEntry!]
# the first option is to leave closure reason as a simple value:
closureReason: SessionClosureReason @aws_cognito_user_pools(cognito_groups: ["tutor_qa_group", "tutor_group_admin", "supervisor_group", "admin_group"])
# second is changing it to a complex, more descriptive type:
closureReason: SessionClosureReasonDescriptor @aws_cognito_user_pools(cognito_groups: ["tutor_qa_group", "tutor_group_admin", "supervisor_group", "admin_group"])
# third is to promote "closedBy" from the type above to the session itself:
closedBy: Actor
# closure case should be used for client integration
# is doesn't have to be persisted and can be inferred based on other persisted session fields
# this is a single value field, so a priority needs to be specified in case of multiple possible values (i.e. disconnected and later reported by tutor)
closureCase: SessionClosureCase @aws_cognito_user_pools(cognito_groups: ["user_group"])
# should rating or report be accessible by tutor or user?
userRating: UserRating @aws_cognito_user_pools(cognito_groups: ["tutor_qa_group", "tutor_group_admin", "supervisor_group", "admin_group"])
tutorReport: TutorReport @aws_cognito_user_pools(cognito_groups: ["tutor_qa_group", "tutor_group_admin", "supervisor_group", "admin_group"])
}
enum SessionState {
CREATED
STARTED
CLOSED
REJECTED
}
enum SessionClosureReason {
ANSWERED
NOT_ANSWERED
TUTOR_DISCONNECTED
LANGUAGE_NOT_SUPPORTED
}
type SessionClosureReasonDescriptor {
closedBy: Actor!
closureReason: SessionClosureReason!
}
# name is to be decided (case, scenario, etc.)
enum SessionClosureCase {
NORMAL
CONNECTION_ISSUES
TUTOR_REPORTED_USER
}
enum UserClosureReason {
FINISHED
# possibly, more values in the future
}
input FinishSessionByUserInput {
id: ID!
closureReason: UserClosureReason!
}
enum TutorClosureReason {
ANSWERED
NOT_ANSWERED
LANGUAGE_NOT_SUPPORTED
}
input FinishSessionByTutorInput {
id: ID!
closureReason: TutorClosureReason!
}
type SessionStateEntry @aws_cognito_user_pools {
state: SessionState
createdAt: AWSDateTime
createdBy: Actor
}
type UserRating @aws_iam @aws_cognito_user_pools {
session: Session!
score: UserRatingScore!
tags: [UserRatingTag!]!
comment: String
user: Actor!
createdAt: AWSDateTime!
}
type TutorReport @aws_iam @aws_cognito_user_pools {
session: Session!
tags: [TutorReportTag!]!
comment: String
tutor: Actor!
createdAt: AWSDateTime!
}
@pmbanka
Copy link

pmbanka commented Oct 12, 2021

  1. I'd alter TutorClosureReason to be even more descriptive
enum TutorClosureReason {
    ANSWERED
    NOT_ANSWERED
    LANGUAGE_NOT_SUPPORTED
}
  1. How about sth like:
enum SystemClosureReason {
    TUTOR_DISCONNECTED
    # possibly, more values in the future
}

type TutorClosure {
	closedBy: Actor!
	reason: TutorClosureReason!
}

type UserClosure {
	closedBy: Actor!
	reason: UserClosureReason!
}

// for consistency
type SystemClosure {
	reason: SystemClosureReason!
}

union SessionClosure = TutorClosure | UserClosure | SystemClosure

type Session {
	    closure: SessionClosure @aws_cognito_user_pools(cognito_groups: ["tutor_qa_group", "tutor_group_admin", "supervisor_group", "admin_group"])
}

@pmbanka
Copy link

pmbanka commented Oct 12, 2021

And I wonder if we need to have stateLog: [SessionStateEntry!] as a part of this API at all. Does any of the clients use that? If not, let's just get rid of it, the smaller the API surface the better.

@mmierzwa
Copy link
Author

mmierzwa commented Oct 12, 2021

TutorClosureReason as proposed by you, looks good for me. It's more intuitive than just finished.

There is no way for the tutor different than the one assigned to the session to close it. The same goes for the user. Therefore I don't see a point in much sense introducing the complex closure types.
Or maybe, it's just because of restrictions for unions in GraphQL (cannot set a union on non-object type)?

And I wonder if we need to have stateLog: [SessionStateEntry!] as a part of this API at all. Does any of the clients use that? If not, let's just get rid of it, the smaller the API surface the better.

Yes, we do πŸ™‚ There is a plan to display the state log in the UI for supervisors and QAs.

@mmierzwa
Copy link
Author

On the other hand, your complex session closure type proposal makes the API more descriptive and doesn't require any additional data to be persisted in DB.

@mmierzwa
Copy link
Author

@pmbanka πŸ”

@pmbanka
Copy link

pmbanka commented Oct 12, 2021

There is no way for the tutor different than the one assigned to the session to close it. The same goes for the user. Therefore I don't see a point in much sense introducing the complex closure types.

I thought about it, then I remembered the looming threat of session redirection feature πŸ˜… The design as proposed by me would allow us to add data to the closure types without breaking the client. If we went for a simpler option:

enum SystemClosureReason {
    TUTOR_DISCONNECTED
    # possibly, more values in the future
}


union SessionClosureReason = TutorClosureReason | UserClosureReason | SystemClosureReason

type Session {
	    closureReason: SessionClosureReason @aws_cognito_user_pools(cognito_groups: ["tutor_qa_group", "tutor_group_admin", "supervisor_group", "admin_group"])
}

we lose that future-proofness but API is much simpler. YAGNI or not? I don't really know.

Yes, we do πŸ™‚ There is a plan to display the state log in the UI for supervisors and QAs.

I would not make it a part of this refinement, it will require a refinement on its own. There is a difference between "we do" and "There is a plan" :D

@pmbanka
Copy link

pmbanka commented Oct 12, 2021

@mmierzwa πŸ†™

@mmierzwa
Copy link
Author

Yes, we do πŸ™‚ There is a plan to display the state log in the UI for supervisors and QAs.

I would not make it a part of this refinement, it will require a refinement on its own. There is a difference between "we do" and "There is a plan" :D

There is a thin line between being well prepared and being overprepared πŸ™ˆ But that's ok for me right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment