You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"""The organization member associated with this team member"""
929
+
organizationMember: OrganizationMember
930
+
permissions: TeamMemberPermissions!
931
+
932
+
"""The users role within the team"""
933
+
role: TeamMemberRole!
934
+
935
+
"""The team associated with this team member"""
936
+
team: Team
937
+
938
+
"""The user associated with this team member"""
939
+
user: User
940
+
941
+
"""The public UUID for this team member"""
942
+
uuid: ID!
943
+
}
944
+
```
945
+
</details>
946
+
947
+
The queries and mutations that deal with `TeamMember`s follow a fairly predictable pattern:
948
+
[`teamMemberCreate()`][teamMemberCreate], [`teamMemberDelete()`][teamMemberDelete], [`teamMemberUpdate()`][teamMemberUpdate], and appearing as a connection on the `Team` object.
949
+
950
+
<details><summary>See the full query and mutation definitions</summary>
951
+
952
+
```graphql
953
+
"""The query root for this schema"""
954
+
type Query {
955
+
"""Find a team"""
956
+
team(
957
+
"""The slug of the team, prefixed with its organization. i.e. `acme-inc/awesome-team`"""
958
+
slug: ID!
959
+
): Team
960
+
}
961
+
962
+
"""The root for mutations in this schema"""
963
+
type Mutation {
964
+
"""Add a user to a team."""
965
+
teamMemberCreate(
966
+
"""Parameters for TeamMemberCreate"""
967
+
input: TeamMemberCreateInput!
968
+
): TeamMemberCreatePayload
969
+
970
+
"""Remove a user from a team."""
971
+
teamMemberDelete(
972
+
"""Parameters for TeamMemberDelete"""
973
+
input: TeamMemberDeleteInput!
974
+
): TeamMemberDeletePayload
975
+
976
+
"""Update a user's role in a team."""
977
+
teamMemberUpdate(
978
+
"""Parameters for TeamMemberUpdate"""
979
+
input: TeamMemberUpdateInput!
980
+
): TeamMemberUpdatePayload
981
+
}
982
+
```
983
+
</details>
984
+
985
+
and they each define their own GraphQL input and object types for input and payload:
However, there's a problem — `role` should be optional on create, but required on update and read.
1157
+
The TypeSpec above will make it required everywhere.
1158
+
To get around this we need to define a separate model:
1159
+
1160
+
```typespec
1161
+
1162
+
@withVisibility(Lifecycle.Create)
1163
+
model TeamMemberCreate {
1164
+
...TeamMember;
1165
+
role?: TeamMemberRole;
1166
+
}
1167
+
```
1168
+
1169
+
but… we can't even do this because TypeScript will complain about the duplicate `role` property.
1170
+
Instead, we would need to copy all the properties, or copy all the properties except `role` and define it separately in a `TeamMemberRead` model.
1171
+
1172
+
All of this seems confusing and somewhat arbitrary. For instance, should I create `TeamMemberUpdate` and `TeamMemberDelete` models, instead or in addition?
1173
+
Which properties need to go on which models?
1174
+
1175
+
We'd like to describe the type system of our API, but instead we're creating arbitrary types to work around limitations in expressiveness.
0 commit comments