Schema GraphQL

Tự động tạo từ packages/graphql/schema.graphql.

type AuthPayload {
  accessToken: String!
  refreshToken: String!
  user: UserProfile!
}

type ChannelSummary {
  description: String
  id: ID!
  isDefault: Boolean!
  joined: Boolean!
  membersCount: Int!
  title: String!
}

type ChannelSummaryPage {
  endCursor: String
  hasNextPage: Boolean!
  nodes: [ChannelSummary!]!
}

type ConversationMemberView {
  avatarUrl: String
  displayName: String!
  lastReadSequence: Int!
  role: MemberRole!
  userId: ID!
  username: String!
}

type ConversationPage {
  endCursor: String
  hasNextPage: Boolean!
  nodes: [ConversationView!]!
}

enum ConversationType {
  CHANNEL
  DIRECT
}

type ConversationView {
  createdAt: DateTime!
  description: String
  id: ID!
  isDefault: Boolean!
  lastMessageSequence: Int
  members: [ConversationMemberView!]!
  muted: Boolean!
  pinnedAt: DateTime
  title: String
  type: ConversationType!
  updatedAt: DateTime!
  visibility: ConversationVisibility!
  workspaceId: ID!
}

enum ConversationVisibility {
  PRIVATE
  PUBLIC
}

input CreateChannelInput {
  description: String
  memberIds: [ID!]! = []
  title: String!
  visibility: ConversationVisibility!
  workspaceId: ID!
}

input CreateUploadUrlInput {
  contentType: String!
  fileName: String
  scope: UploadScope!
}

input CreateWorkspaceInput {
  iconKey: String
  name: String!
  purposes: [WorkspacePurpose!]
  slug: String!
  teamSize: WorkspaceTeamSize
}

"""
A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date-time format.
"""
scalar DateTime

input DepartmentInput {
  description: String
  leadUserId: ID
  name: String!
}

type DepartmentLead {
  displayName: String!
  userId: ID!
  username: String!
}

type DepartmentShare {
  count: Int!
  departmentId: ID
  name: String!
}

type DepartmentView {
  description: String
  id: ID!
  lead: DepartmentLead
  memberCount: Int!
  name: String!
}

type DirectoryMember {
  avatarUrl: String
  canManage: Boolean!
  channelCount: Int!
  channels: [String!]!
  department: MemberDepartmentRef
  displayName: String!
  email: String!
  isDepartmentLead: Boolean!
  isOnline: Boolean!
  jobTitle: String
  joinedAt: DateTime!
  lastActiveAt: DateTime
  role: WorkspaceRole!
  twoFactor: MemberTwoFactor
  userId: ID!
  username: String!
}

type DirectoryPage {
  items: [DirectoryMember!]!
  page: Int!
  pageSize: Int!
  totalCount: Int!
}

type EphemeralState {
  active: Boolean!
  conversationId: ID!
  userId: ID!
}

input ExchangeSocialTokenInput {
  appleAuthorizationCode: String
  appleIdentityToken: String
  googleIdToken: String
  provider: SocialProviderName!
}

type FileCategoryStat {
  bytes: Float!
  count: Int!
}

enum FileEntryKind {
  ATTACHMENT
  STORED
}

type FileEntryView {
  allowDownload: Boolean!
  canManage: Boolean!
  contentType: String!
  conversationId: ID
  conversationTitle: String
  conversationType: ConversationType
  createdAt: DateTime!
  deletedAt: DateTime
  fileName: String!
  folderId: ID
  folderName: String
  id: ID!
  isPinned: Boolean!
  kind: FileEntryKind!
  size: Int!
  uploaderAvatarUrl: String
  uploaderId: ID!
  uploaderName: String!
  visibility: WorkspaceFileVisibility
}

type FileFolderView {
  id: ID!
  name: String!
  parentId: ID
  workspaceId: ID!
}

enum FileFormat {
  DESIGN
  DOCUMENT
  IMAGE
  MEDIA
  OTHER
}

input FileLibraryInput {
  conversationId: ID
  folderId: ID
  format: FileFormat
  id: ID
  page: Int! = 1
  pageSize: Int! = 20
  pinnedOnly: Boolean! = false
  scope: FileLibraryScope! = ALL
  search: String
  sort: FileSort! = RECENT
  trashed: Boolean! = false
}

type FileLibraryPage {
  items: [FileEntryView!]!
  page: Int!
  pageSize: Int!
  totalCount: Int!
}

enum FileLibraryScope {
  ALL
  CHANNELS
  DIRECT
  MINE
}

type FileLibrarySummary {
  documents: FileCategoryStat!
  images: FileCategoryStat!
  media: FileCategoryStat!
  quotaBytes: Float!
  totalCount: Int!
  trashedCount: Int!
  usedBytes: Float!
}

enum FileSort {
  NAME_ASC
  OLDEST
  RECENT
  SIZE_DESC
}

type InviteLinkInfo {
  createdAt: DateTime!
  expiresAt: DateTime!
  joinEmailDomains: [String!]!
  role: WorkspaceRole!
}

input InviteToWorkspaceInput {
  invitations: [WorkspaceInvitationEntry!]!
  message: String
  workspaceId: ID!
}

type InviteToWorkspaceResult {
  alreadyMembers: Int!
  sent: Int!
}

input JoinEmailDomainsInput {
  domains: [String!]!
  workspaceId: ID!
}

input LoginInput {
  email: String!
  password: String!
  rememberMe: Boolean
}

type MemberDepartmentRef {
  id: ID!
  name: String!
}

input MemberDirectoryInput {
  departmentId: ID
  page: Int! = 1
  pageSize: Int! = 10
  role: WorkspaceRole
  search: String
  status: MemberStatus
}

type MemberDirectorySummary {
  canManage: Boolean!
  departmentCount: Int!
  distribution: [DepartmentShare!]!
  expiringInvitations: Int!
  guestCount: Int!
  joinedThisWeek: Int!
  onlineCount: Int!
  pendingInvitations: Int!
  totalCount: Int!
  twoFactor: TwoFactorCompliance
}

enum MemberRole {
  ADMIN
  MEMBER
  OWNER
}

enum MemberStatus {
  OFFLINE
  ONLINE
  TWO_FACTOR_MISSING
}

type MemberTwoFactor {
  enabled: Boolean!
  method: TwoFactorMethod
}

input MessageAttachmentInput {
  contentType: String!
  fileName: String!
  key: String!
  size: Int!
}

type MessageAttachmentView {
  contentType: String!
  fileName: String!
  id: ID!
  size: Int!
}

type MessagePage {
  endCursor: String
  hasNextPage: Boolean!
  nodes: [MessageView!]!
}

type MessageSummary {
  content: String
  deletedAt: DateTime
  id: ID!
  senderId: ID!
}

enum MessageType {
  SYSTEM
  TEXT
}

type MessageView {
  attachments: [MessageAttachmentView!]!
  clientMessageId: String!
  content: String
  conversationId: ID!
  createdAt: DateTime!
  deletedAt: DateTime
  id: ID!
  reactions: [ReactionSummary!]!
  replyTo: MessageSummary
  replyToMessageId: ID
  senderId: ID!
  sequence: Int!
  type: MessageType!
  updatedAt: DateTime!
}

type Mutation {
  addChannelMember(conversationId: ID!, memberId: ID!): ConversationView!
  addReaction(emoji: String!, messageId: ID!): MessageView!
  assignMemberDepartment(departmentId: ID, userId: ID!, workspaceId: ID!): DirectoryMember!
  changeWorkspaceMemberRole(role: WorkspaceRole!, userId: ID!, workspaceId: ID!): DirectoryMember!
  clearReadNotifications: Int!
  createChannel(input: CreateChannelInput!): ConversationView!
  createDepartment(input: DepartmentInput!, workspaceId: ID!): DepartmentView!
  createDirectConversation(participantId: ID!, workspaceId: ID!): ConversationView!
  createFileFolder(name: String!, parentId: ID, workspaceId: ID!): FileFolderView!
  createUploadUrl(input: CreateUploadUrlInput!): UploadUrl!
  createWorkspace(input: CreateWorkspaceInput!): Workspace!
  createWorkspaceInviteLink(role: WorkspaceRole!, workspaceId: ID!): WorkspaceInviteLink!
  deleteDepartment(id: ID!, workspaceId: ID!): ID!
  deleteMessage(id: ID!): MessageView!
  deleteStoredFilePermanently(id: ID!): ID!
  editMessage(content: String!, id: ID!): MessageView!
  exchangeSocialToken(input: ExchangeSocialTokenInput!): AuthPayload!
  inviteToWorkspace(input: InviteToWorkspaceInput!): InviteToWorkspaceResult!
  joinChannel(conversationId: ID!): ConversationView!
  joinWorkspace(token: String!): Workspace!
  login(input: LoginInput!): AuthPayload!
  loginWithOAuth(input: OAuthLoginInput!): AuthPayload!
  logout(refreshToken: String!): Boolean!
  markAllNotificationsRead: Int!
  markConversationAsRead(conversationId: ID!, sequence: Int!): ConversationView!
  markNotificationRead(id: ID!): Boolean!
  moveStoredFile(folderId: ID, id: ID!): FileEntryView!
  refreshToken(refreshToken: String!): AuthPayload!
  register(input: RegisterInput!): Boolean!
  registerStoredFile(input: RegisterStoredFileInput!): FileEntryView!
  removeReaction(emoji: String!, messageId: ID!): MessageView!
  removeWorkspaceMember(userId: ID!, workspaceId: ID!): ID!
  renameStoredFile(fileName: String!, id: ID!): FileEntryView!
  resendVerificationEmail(email: String!): Boolean!
  restoreStoredFile(id: ID!): FileEntryView!
  sendMessage(input: SendMessageInput!): MessageView!
  setConversationMuted(conversationId: ID!, muted: Boolean!): ConversationView!
  setConversationPinned(conversationId: ID!, pinned: Boolean!): ConversationView!
  setStoredFilePinned(id: ID!, pinned: Boolean!): FileEntryView!
  setTyping(active: Boolean!, conversationId: ID!): Boolean!
  setWorkspaceJoinEmailDomains(input: JoinEmailDomainsInput!): [String!]!
  trashStoredFile(id: ID!): FileEntryView!
  updateAvatar(key: String): UserProfile!
  updateConversation(input: UpdateConversationInput!): ConversationView!
  updateDepartment(id: ID!, input: DepartmentInput!, workspaceId: ID!): DepartmentView!
  updateWorkspace(input: UpdateWorkspaceInput!): Workspace!
  verifyEmail(token: String!): Boolean!
}

type Notification {
  actor: NotificationActor
  category: NotificationCategory!
  conversation: NotificationConversation
  createdAt: DateTime!
  id: ID!
  messageId: ID
  readAt: DateTime
  snippet: String
  type: NotificationType!
  workspace: NotificationWorkspace
}

type NotificationActor {
  avatarUrl: String
  displayName: String!
  id: ID!
}

enum NotificationCategory {
  MEETINGS
  MENTIONS
  SYSTEM
}

type NotificationConversation {
  id: ID!
  title: String
  type: ConversationType!
}

type NotificationDayActivity {
  date: String!
  mentions: Int!
  replied: Int!
}

type NotificationPage {
  endCursor: String
  hasNextPage: Boolean!
  nodes: [Notification!]!
}

type NotificationSummary {
  total: Int!
  unread: Int!
  unreadMeetings: Int!
  unreadMentions: Int!
  unreadSystem: Int!
}

enum NotificationType {
  MENTION
  WORKSPACE_JOINED
}

type NotificationWorkspace {
  id: ID!
  name: String!
}

input OAuthAuthorizationUrlInput {
  codeChallenge: String!
  provider: OAuthProviderName!
  state: String!
}

input OAuthLoginInput {
  code: String!
  codeVerifier: String!
  provider: OAuthProviderName!
}

enum OAuthProviderName {
  GOOGLE
}

type PendingWorkspaceInvitation {
  createdAt: DateTime!
  email: String!
  expiresAt: DateTime!
  id: ID!
  invitedByName: String!
  role: WorkspaceRole!
}

type Query {
  attachmentDownloadUrl(attachmentId: ID!): String!
  attachmentPreviewUrl(attachmentId: ID!): String!
  browseChannels(after: String, first: Int! = 30, workspaceId: ID!): ChannelSummaryPage!
  conversation(id: ID!): ConversationView!
  conversations(after: String, first: Int! = 30, workspaceId: ID!): ConversationPage!
  departments(workspaceId: ID!): [DepartmentView!]!
  exportWorkspaceMembersCsv(workspaceId: ID!): String!
  fileFolders(workspaceId: ID!): [FileFolderView!]!
  fileLibrary(input: FileLibraryInput = {}, workspaceId: ID!): FileLibraryPage!
  fileLibrarySummary(workspaceId: ID!): FileLibrarySummary!
  generateSlug(name: String!): String!

  """Process liveness; database readiness is exposed at /ready."""
  health: String!
  me: UserProfile!
  memberDirectory(input: MemberDirectoryInput = {}, workspaceId: ID!): DirectoryPage!
  memberDirectorySummary(workspaceId: ID!): MemberDirectorySummary!
  messages(aroundMessageId: ID, before: String, conversationId: ID!, first: Int! = 30): MessagePage!
  messagesSince(afterSequence: Int!, conversationId: ID!, first: Int! = 50): MessagePage!
  notificationActivity: [NotificationDayActivity!]!
  notificationSummary: NotificationSummary!
  notifications(after: String, first: Int! = 30): NotificationPage!
  oauthAuthorizationUrl(input: OAuthAuthorizationUrlInput!): String!
  oauthProviders: [OAuthProviderName!]!
  pendingWorkspaceInvitations(workspaceId: ID!): [PendingWorkspaceInvitation!]!
  storedFileDownloadUrl(id: ID!): String!
  storedFilePreviewUrl(id: ID!): String!
  workspace(id: ID!): Workspace!
  workspaceInviteLinkInfo(workspaceId: ID!): InviteLinkInfo
  workspaceSearch(input: WorkspaceSearchInput!, workspaceId: ID!): WorkspaceSearchResults!
  workspaces: [Workspace!]!
}

type ReactionSummary {
  emoji: String!
  userIds: [ID!]!
}

input RegisterInput {
  displayName: String!
  email: String!
  password: String!
  username: String!
}

input RegisterStoredFileInput {
  allowDownload: Boolean! = true
  contentType: String!
  conversationId: ID
  fileName: String!
  folderId: ID
  key: String!
  size: Int!
  visibility: WorkspaceFileVisibility!
  workspaceId: ID!
}

type SearchChannel {
  description: String
  id: ID!
  isMember: Boolean!
  memberCount: Int!
  title: String!
  visibility: ConversationVisibility!
}

enum SearchKind {
  CHANNELS
  FILES
  MESSAGES
  PEOPLE
}

type SearchMessage {
  conversationId: ID!
  conversationLabel: String!
  conversationType: ConversationType!
  createdAt: DateTime!
  id: ID!
  senderName: String!
  snippet: String!
}

type SearchPerson {
  avatarUrl: String
  displayName: String!
  email: String!
  isOnline: Boolean!
  jobTitle: String
  role: WorkspaceRole!
  userId: ID!
  username: String!
}

input SendMessageInput {
  attachments: [MessageAttachmentInput!]
  clientMessageId: String!
  content: String!
  conversationId: ID!
  replyToMessageId: ID
  sharedFileIds: [ID!]
}

enum SocialProviderName {
  APPLE
  GOOGLE
}

type Subscription {
  messageCreated(conversationId: ID!): MessageView!
  messageDeleted(conversationId: ID!): MessageView!
  messageUpdated(conversationId: ID!): MessageView!
  notificationReceived: Notification!
  presenceChanged(conversationId: ID!): EphemeralState!
  typingChanged(conversationId: ID!): EphemeralState!
}

type TwoFactorCompliance {
  missingCount: Int!
  percent: Float!
  protectedCount: Int!
  total: Int!
}

enum TwoFactorMethod {
  APP
  FIDO2
  HARDWARE
  YUBIKEY
}

input UpdateConversationInput {
  description: String
  id: ID!
  title: String
}

input UpdateWorkspaceInput {
  iconKey: String
  id: ID!
  name: String
  purposes: [WorkspacePurpose!]
  slug: String
  teamSize: WorkspaceTeamSize
}

enum UploadScope {
  PRIVATE
  PUBLIC
}

type UploadUrl {
  expiresAt: DateTime!
  key: String!
  publicUrl: String
  uploadUrl: String!
}

type UserProfile {
  avatarUrl: String
  displayName: String!
  email: String!
  id: ID!
  username: String!
}

type Workspace {
  createdAt: DateTime!
  iconUrl: String
  id: ID!
  isOwner: Boolean!
  membersCount: Int!
  name: String!
  pendingInvitations: Int!
  purposes: [WorkspacePurpose!]!
  slug: String!
  teamSize: WorkspaceTeamSize
  updatedAt: DateTime!
}

enum WorkspaceFileVisibility {
  CHANNEL
  WORKSPACE
}

input WorkspaceInvitationEntry {
  conversationId: ID
  email: String!
  role: WorkspaceRole!
}

type WorkspaceInviteLink {
  expiresAt: DateTime!
  role: WorkspaceRole!
  token: String!
}

enum WorkspacePurpose {
  DESIGN
  ENGINEERING
  OPERATIONS_HR
  SALES
}

enum WorkspaceRole {
  ADMIN
  GUEST
  MEMBER
  OWNER
}

input WorkspaceSearchInput {
  kinds: [SearchKind!]
  limit: Int! = 5
  query: String!
}

type WorkspaceSearchResults {
  channels: [SearchChannel!]!
  files: [FileEntryView!]!
  messages: [SearchMessage!]!
  people: [SearchPerson!]!
}

enum WorkspaceTeamSize {
  TEAM_1_10
  TEAM_11_50
  TEAM_51_250
  TEAM_250_PLUS
}