scalar Time scalar UUID scalar Upload enum RoleCode { owner admin member observer } type ProjectLabel { id: ID! createdDate: Time! labelColor: LabelColor! name: String } type LabelColor { id: ID! name: String! position: Float! colorHex: String! } type TaskLabel { id: ID! projectLabel: ProjectLabel! assignedDate: Time! } type ProfileIcon { url: String initials: String bgColor: String } type OwnersList { projects: [UUID!]! teams: [UUID!]! } type Member { id: ID! role: Role! fullName: String! username: String! profileIcon: ProfileIcon! owned: OwnedList! member: MemberList! } type RefreshToken { id: ID! userId: UUID! expiresAt: Time! createdAt: Time! } type Role { code: String! name: String! } type OwnedList { teams: [Team!]! projects: [Project!]! } type MemberList { teams: [Team!]! projects: [Project!]! } type UserAccount { id: ID! email: String! createdAt: Time! fullName: String! initials: String! bio: String! role: Role! username: String! profileIcon: ProfileIcon! owned: OwnedList! member: MemberList! } type InvitedUserAccount { id: ID! email: String! invitedOn: Time! member: MemberList! } type Team { id: ID! createdAt: Time! name: String! members: [Member!]! } type InvitedMember { email: String! invitedOn: Time! } type Project { id: ID! createdAt: Time! name: String! team: Team taskGroups: [TaskGroup!]! members: [Member!]! invitedMembers: [InvitedMember!]! labels: [ProjectLabel!]! } type TaskGroup { id: ID! projectID: String! createdAt: Time! name: String! position: Float! tasks: [Task!]! } type ChecklistBadge { complete: Int! total: Int! } type TaskBadges { checklist: ChecklistBadge } type CausedBy { id: ID! fullName: String! profileIcon: ProfileIcon } type TaskActivityData { name: String! value: String! } enum ActivityType { TASK_ADDED TASK_MOVED TASK_MARKED_COMPLETE TASK_MARKED_INCOMPLETE TASK_DUE_DATE_CHANGED TASK_DUE_DATE_ADDED TASK_DUE_DATE_REMOVED TASK_CHECKLIST_CHANGED TASK_CHECKLIST_ADDED TASK_CHECKLIST_REMOVED } type TaskActivity { id: ID! type: ActivityType! data: [TaskActivityData!]! causedBy: CausedBy! createdAt: Time! } type Task { id: ID! taskGroup: TaskGroup! createdAt: Time! name: String! position: Float! description: String dueDate: Time hasTime: Boolean! complete: Boolean! completedAt: Time assigned: [Member!]! labels: [TaskLabel!]! checklists: [TaskChecklist!]! badges: TaskBadges! activity: [TaskActivity!]! comments: [TaskComment!]! } type CreatedBy { id: ID! fullName: String! profileIcon: ProfileIcon! } type TaskComment { id: ID! createdAt: Time! updatedAt: Time message: String! createdBy: CreatedBy! pinned: Boolean! } type Organization { id: ID! name: String! } type TaskChecklistItem { id: ID! name: String! taskChecklistID: UUID! complete: Boolean! position: Float! dueDate: Time! } type TaskChecklist { id: ID! name: String! position: Float! items: [TaskChecklistItem!]! } enum ShareStatus { INVITED JOINED } enum RoleLevel { ADMIN MEMBER } enum ActionLevel { ORG TEAM PROJECT } enum ObjectType { ORG TEAM PROJECT TASK TASK_GROUP TASK_CHECKLIST TASK_CHECKLIST_ITEM } directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION type Query { organizations: [Organization!]! users: [UserAccount!]! invitedUsers: [InvitedUserAccount!]! findUser(input: FindUser!): UserAccount! findProject(input: FindProject!): Project! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) findTask(input: FindTask!): Task! projects(input: ProjectsFilter): [Project!]! findTeam(input: FindTeam!): Team! teams: [Team!]! myTasks(input: MyTasks!): MyTasksPayload! labelColors: [LabelColor!]! taskGroups: [TaskGroup!]! me: MePayload! } type Mutation enum MyTasksStatus { ALL INCOMPLETE COMPLETE_ALL COMPLETE_TODAY COMPLETE_YESTERDAY COMPLETE_ONE_WEEK COMPLETE_TWO_WEEK COMPLETE_THREE_WEEK } enum MyTasksSort { NONE PROJECT DUE_DATE } input MyTasks { status: MyTasksStatus! sort: MyTasksSort! } type ProjectTaskMapping { projectID: UUID! taskID: UUID! } type MyTasksPayload { tasks: [Task!]! projects: [ProjectTaskMapping!]! } type TeamRole { teamID: UUID! roleCode: RoleCode! } type ProjectRole { projectID: UUID! roleCode: RoleCode! } type MePayload { user: UserAccount! teamRoles: [TeamRole!]! projectRoles: [ProjectRole!]! } input ProjectsFilter { teamID: UUID } input FindUser { userID: UUID! } input FindProject { projectID: UUID! } input FindTask { taskID: UUID! } input FindTeam { teamID: UUID! } extend type Query { notifications: [Notification!]! } enum EntityType { TASK } enum ActorType { USER } enum ActionType { TASK_MEMBER_ADDED } type NotificationActor { id: UUID! type: ActorType! name: String! } type NotificationEntity { id: UUID! type: EntityType! name: String! } type Notification { id: ID! entity: NotificationEntity! actionType: ActionType! actor: NotificationActor! read: Boolean! createdAt: Time! } extend type Mutation { createProject(input: NewProject!): Project! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) deleteProject(input: DeleteProject!): DeleteProjectPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) updateProjectName(input: UpdateProjectName): Project! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) } input NewProject { teamID: UUID name: String! } input UpdateProjectName { projectID: UUID! name: String! } input DeleteProject { projectID: UUID! } type DeleteProjectPayload { ok: Boolean! project: Project! } extend type Mutation { createProjectLabel(input: NewProjectLabel!): ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) } input NewProjectLabel { projectID: UUID! labelColorID: UUID! name: String } input DeleteProjectLabel { projectLabelID: UUID! } input UpdateProjectLabelName { projectLabelID: UUID! name: String! } input UpdateProjectLabel { projectLabelID: UUID! labelColorID: UUID! name: String! } input UpdateProjectLabelColor { projectLabelID: UUID! labelColorID: UUID! } extend type Mutation { inviteProjectMembers(input: InviteProjectMembers!): InviteProjectMembersPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) deleteInvitedProjectMember(input: DeleteInvitedProjectMember!): DeleteInvitedProjectMemberPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT) } input DeleteInvitedProjectMember { projectID: UUID! email: String! } type DeleteInvitedProjectMemberPayload { invitedMember: InvitedMember! } input MemberInvite { userID: UUID email: String } input InviteProjectMembers { projectID: UUID! members: [MemberInvite!]! } type InviteProjectMembersPayload { ok: Boolean! projectID: UUID! members: [Member!]! invitedMembers: [InvitedMember!]! } input DeleteProjectMember { projectID: UUID! userID: UUID! } type DeleteProjectMemberPayload { ok: Boolean! member: Member! projectID: UUID! } input UpdateProjectMemberRole { projectID: UUID! userID: UUID! roleCode: RoleCode! } type UpdateProjectMemberRolePayload { ok: Boolean! member: Member! } extend type Mutation { createTask(input: NewTask!): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) deleteTask(input: DeleteTaskInput!): DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) updateTaskDescription(input: UpdateTaskDescriptionInput!): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) updateTaskName(input: UpdateTaskName!): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) setTaskComplete(input: SetTaskComplete!): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) updateTaskDueDate(input: UpdateTaskDueDate!): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) assignTask(input: AssignTaskInput): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) unassignTask(input: UnassignTaskInput): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) } input NewTask { taskGroupID: UUID! name: String! position: Float! assigned: [UUID!] } input AssignTaskInput { taskID: UUID! userID: UUID! } input UnassignTaskInput { taskID: UUID! userID: UUID! } input UpdateTaskDescriptionInput { taskID: UUID! description: String! } type UpdateTaskLocationPayload { previousTaskGroupID: UUID! task: Task! } input UpdateTaskDueDate { taskID: UUID! hasTime: Boolean! dueDate: Time } input SetTaskComplete { taskID: UUID! complete: Boolean! } input NewTaskLocation { taskID: UUID! taskGroupID: UUID! position: Float! } input DeleteTaskInput { taskID: UUID! } type DeleteTaskPayload { taskID: UUID! } input UpdateTaskName { taskID: UUID! name: String! } extend type Mutation { createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST) updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST) createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST) updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!): UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST) updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM) setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM) deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM) updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!): UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM) } input UpdateTaskChecklistItemLocation { taskChecklistID: UUID! taskChecklistItemID: UUID! position: Float! } type UpdateTaskChecklistItemLocationPayload { taskChecklistID: UUID! prevChecklistID: UUID! checklistItem: TaskChecklistItem! } input UpdateTaskChecklistLocation { taskChecklistID: UUID! position: Float! } type UpdateTaskChecklistLocationPayload { checklist: TaskChecklist! } input CreateTaskChecklist { taskID: UUID! name: String! position: Float! } type DeleteTaskChecklistItemPayload { ok: Boolean! taskChecklistItem: TaskChecklistItem! } input CreateTaskChecklistItem { taskChecklistID: UUID! name: String! position: Float! } input SetTaskChecklistItemComplete { taskChecklistItemID: UUID! complete: Boolean! } input DeleteTaskChecklistItem { taskChecklistItemID: UUID! } input UpdateTaskChecklistItemName { taskChecklistItemID: UUID! name: String! } input UpdateTaskChecklistName { taskChecklistID: UUID! name: String! } input DeleteTaskChecklist { taskChecklistID: UUID! } type DeleteTaskChecklistPayload { ok: Boolean! taskChecklist: TaskChecklist! } extend type Mutation { createTaskComment(input: CreateTaskComment): CreateTaskCommentPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) deleteTaskComment(input: DeleteTaskComment): DeleteTaskCommentPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) updateTaskComment(input: UpdateTaskComment): UpdateTaskCommentPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) } input CreateTaskComment { taskID: UUID! message: String! } type CreateTaskCommentPayload { taskID: UUID! comment: TaskComment! } input UpdateTaskComment { commentID: UUID! message: String! } type UpdateTaskCommentPayload { taskID: UUID! comment: TaskComment! } input DeleteTaskComment { commentID: UUID! } type DeleteTaskCommentPayload { taskID: UUID! commentID: UUID! } extend type Mutation { createTaskGroup(input: NewTaskGroup!): TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT) updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) duplicateTaskGroup(input: DuplicateTaskGroup!): DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) sortTaskGroup(input: SortTaskGroup!): SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) deleteTaskGroupTasks(input: DeleteTaskGroupTasks!): DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP) } input DeleteTaskGroupTasks { taskGroupID: UUID! } type DeleteTaskGroupTasksPayload { taskGroupID: UUID! tasks: [UUID!]! } input TaskPositionUpdate { taskID: UUID! position: Float! } type SortTaskGroupPayload { taskGroupID: UUID! tasks: [Task!]! } input SortTaskGroup { taskGroupID: UUID! tasks: [TaskPositionUpdate!]! } input DuplicateTaskGroup { projectID: UUID! taskGroupID: UUID! name: String! position: Float! } type DuplicateTaskGroupPayload { taskGroup: TaskGroup! } input NewTaskGroupLocation { taskGroupID: UUID! position: Float! } input UpdateTaskGroupName { taskGroupID: UUID! name: String! } input DeleteTaskGroupInput { taskGroupID: UUID! } type DeleteTaskGroupPayload { ok: Boolean! affectedRows: Int! taskGroup: TaskGroup! } input NewTaskGroup { projectID: UUID! name: String! position: Float! } extend type Mutation { addTaskLabel(input: AddTaskLabelInput): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) removeTaskLabel(input: RemoveTaskLabelInput): Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK) } input AddTaskLabelInput { taskID: UUID! projectLabelID: UUID! } input RemoveTaskLabelInput { taskID: UUID! taskLabelID: UUID! } input ToggleTaskLabelInput { taskID: UUID! projectLabelID: UUID! } type ToggleTaskLabelPayload { active: Boolean! task: Task! } extend type Mutation { deleteTeam(input: DeleteTeam!): DeleteTeamPayload! @hasRole(roles:[ ADMIN], level: TEAM, type: TEAM) createTeam(input: NewTeam!): Team! @hasRole(roles: [ADMIN], level: ORG, type: ORG) } input NewTeam { name: String! organizationID: UUID! } input DeleteTeam { teamID: UUID! } type DeleteTeamPayload { ok: Boolean! team: Team! projects: [Project!]! } extend type Mutation { createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) deleteTeamMember(input: DeleteTeamMember!): DeleteTeamMemberPayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM) } input DeleteTeamMember { teamID: UUID! userID: UUID! newOwnerID: UUID } type DeleteTeamMemberPayload { teamID: UUID! userID: UUID! affectedProjects: [Project!]! } input CreateTeamMember { userID: UUID! teamID: UUID! } type CreateTeamMemberPayload { team: Team! teamMember: Member! } input UpdateTeamMemberRole { teamID: UUID! userID: UUID! roleCode: RoleCode! } type UpdateTeamMemberRolePayload { ok: Boolean! teamID: UUID! member: Member! } extend type Mutation { createRefreshToken(input: NewRefreshToken!): RefreshToken! createUserAccount(input: NewUserAccount!): UserAccount! @hasRole(roles: [ADMIN], level: ORG, type: ORG) deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG) deleteInvitedUserAccount(input: DeleteInvitedUserAccount!): DeleteInvitedUserAccountPayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG) logoutUser(input: LogoutUser!): Boolean! clearProfileAvatar: UserAccount! updateUserPassword(input: UpdateUserPassword!): UpdateUserPasswordPayload! updateUserRole(input: UpdateUserRole!): UpdateUserRolePayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG) updateUserInfo(input: UpdateUserInfo!): UpdateUserInfoPayload! @hasRole(roles: [ADMIN], level: ORG, type: ORG) } extend type Query { searchMembers(input: MemberSearchFilter!): [MemberSearchResult!]! } input DeleteInvitedUserAccount { invitedUserID: UUID! } type DeleteInvitedUserAccountPayload { invitedUser: InvitedUserAccount! } input MemberSearchFilter { searchFilter: String! projectID: UUID } type MemberSearchResult { similarity: Int! id: String! user: UserAccount status: ShareStatus! } type UpdateUserInfoPayload { user: UserAccount! } input UpdateUserInfo { name: String! initials: String! email: String! bio: String! } input UpdateUserPassword { userID: UUID! password: String! } type UpdateUserPasswordPayload { ok: Boolean! user: UserAccount! } input UpdateUserRole { userID: UUID! roleCode: RoleCode! } type UpdateUserRolePayload { user: UserAccount! } input NewRefreshToken { userID: UUID! } input NewUserAccount { username: String! email: String! fullName: String! initials: String! password: String! roleCode: String! } input LogoutUser { userID: UUID! } input DeleteUserAccount { userID: UUID! newOwnerID: UUID } type DeleteUserAccountPayload { ok: Boolean! userAccount: UserAccount! }