cleanup: refactor api architecture & add user roles

This commit is contained in:
Jordan Knott
2020-07-04 18:02:57 -05:00
parent a3958595cd
commit eaffaa70df
141 changed files with 12487 additions and 3792 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
package graph
import (
"context"
"net/http"
"os"
"time"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/99designs/gqlgen/graphql/handler/lru"
"github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/google/uuid"
"github.com/jordanknott/project-citadel/api/internal/db"
)
// NewHandler returns a new graphql endpoint handler.
func NewHandler(repo db.Repository) http.Handler {
srv := handler.New(NewExecutableSchema(Config{
Resolvers: &Resolver{
Repository: repo,
},
}))
srv.AddTransport(transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
})
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.AddTransport(transport.MultipartForm{})
srv.SetQueryCache(lru.New(1000))
srv.Use(extension.AutomaticPersistedQuery{
Cache: lru.New(100),
})
if isProd := os.Getenv("PRODUCTION") == "true"; isProd {
srv.Use(extension.FixedComplexityLimit(10))
} else {
srv.Use(extension.Introspection{})
}
return srv
}
// NewPlaygroundHandler returns a new GraphQL Playground handler.
func NewPlaygroundHandler(endpoint string) http.Handler {
return playground.Handler("GraphQL Playground", endpoint)
}
func GetUserID(ctx context.Context) (uuid.UUID, bool) {
userID, ok := ctx.Value("userID").(uuid.UUID)
return userID, ok
}

View File

@ -0,0 +1,418 @@
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
package graph
import (
"fmt"
"io"
"strconv"
"time"
"github.com/google/uuid"
"github.com/jordanknott/project-citadel/api/internal/db"
)
type AddTaskLabelInput struct {
TaskID uuid.UUID `json:"taskID"`
ProjectLabelID uuid.UUID `json:"projectLabelID"`
}
type AssignTaskInput struct {
TaskID uuid.UUID `json:"taskID"`
UserID uuid.UUID `json:"userID"`
}
type ChecklistBadge struct {
Complete int `json:"complete"`
Total int `json:"total"`
}
type CreateProjectMember struct {
ProjectID uuid.UUID `json:"projectID"`
UserID uuid.UUID `json:"userID"`
}
type CreateProjectMemberPayload struct {
Ok bool `json:"ok"`
Member *Member `json:"member"`
}
type CreateTaskChecklist struct {
TaskID uuid.UUID `json:"taskID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type CreateTaskChecklistItem struct {
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type CreateTeamMember struct {
UserID uuid.UUID `json:"userID"`
TeamID uuid.UUID `json:"teamID"`
}
type CreateTeamMemberPayload struct {
Team *db.Team `json:"team"`
TeamMember *Member `json:"teamMember"`
}
type DeleteProject struct {
ProjectID uuid.UUID `json:"projectID"`
}
type DeleteProjectLabel struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
}
type DeleteProjectMember struct {
ProjectID uuid.UUID `json:"projectID"`
UserID uuid.UUID `json:"userID"`
}
type DeleteProjectMemberPayload struct {
Ok bool `json:"ok"`
Member *Member `json:"member"`
ProjectID uuid.UUID `json:"projectID"`
}
type DeleteProjectPayload struct {
Ok bool `json:"ok"`
Project *db.Project `json:"project"`
}
type DeleteTaskChecklist struct {
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
}
type DeleteTaskChecklistItem struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
}
type DeleteTaskChecklistItemPayload struct {
Ok bool `json:"ok"`
TaskChecklistItem *db.TaskChecklistItem `json:"taskChecklistItem"`
}
type DeleteTaskChecklistPayload struct {
Ok bool `json:"ok"`
TaskChecklist *db.TaskChecklist `json:"taskChecklist"`
}
type DeleteTaskGroupInput struct {
TaskGroupID uuid.UUID `json:"taskGroupID"`
}
type DeleteTaskGroupPayload struct {
Ok bool `json:"ok"`
AffectedRows int `json:"affectedRows"`
TaskGroup *db.TaskGroup `json:"taskGroup"`
}
type DeleteTaskInput struct {
TaskID string `json:"taskID"`
}
type DeleteTaskPayload struct {
TaskID string `json:"taskID"`
}
type DeleteTeam struct {
TeamID uuid.UUID `json:"teamID"`
}
type DeleteTeamMember struct {
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
}
type DeleteTeamMemberPayload struct {
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
}
type DeleteTeamPayload struct {
Ok bool `json:"ok"`
Team *db.Team `json:"team"`
Projects []db.Project `json:"projects"`
}
type DeleteUserAccount struct {
UserID uuid.UUID `json:"userID"`
}
type DeleteUserAccountPayload struct {
Ok bool `json:"ok"`
UserAccount *db.UserAccount `json:"userAccount"`
}
type FindProject struct {
ProjectID string `json:"projectId"`
}
type FindTask struct {
TaskID uuid.UUID `json:"taskID"`
}
type FindTeam struct {
TeamID uuid.UUID `json:"teamID"`
}
type FindUser struct {
UserID string `json:"userId"`
}
type LogoutUser struct {
UserID string `json:"userID"`
}
type Member struct {
ID uuid.UUID `json:"id"`
Role *db.Role `json:"role"`
FullName string `json:"fullName"`
Username string `json:"username"`
ProfileIcon *ProfileIcon `json:"profileIcon"`
}
type NewProject struct {
UserID uuid.UUID `json:"userID"`
TeamID uuid.UUID `json:"teamID"`
Name string `json:"name"`
}
type NewProjectLabel struct {
ProjectID uuid.UUID `json:"projectID"`
LabelColorID uuid.UUID `json:"labelColorID"`
Name *string `json:"name"`
}
type NewRefreshToken struct {
UserID string `json:"userId"`
}
type NewTask struct {
TaskGroupID string `json:"taskGroupID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type NewTaskGroup struct {
ProjectID string `json:"projectID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type NewTaskGroupLocation struct {
TaskGroupID uuid.UUID `json:"taskGroupID"`
Position float64 `json:"position"`
}
type NewTaskLocation struct {
TaskID uuid.UUID `json:"taskID"`
TaskGroupID uuid.UUID `json:"taskGroupID"`
Position float64 `json:"position"`
}
type NewTeam struct {
Name string `json:"name"`
OrganizationID uuid.UUID `json:"organizationID"`
}
type NewUserAccount struct {
Username string `json:"username"`
Email string `json:"email"`
FullName string `json:"fullName"`
Initials string `json:"initials"`
Password string `json:"password"`
RoleCode string `json:"roleCode"`
}
type ProfileIcon struct {
URL *string `json:"url"`
Initials *string `json:"initials"`
BgColor *string `json:"bgColor"`
}
type ProjectsFilter struct {
TeamID *uuid.UUID `json:"teamID"`
}
type RemoveTaskLabelInput struct {
TaskLabelID uuid.UUID `json:"taskLabelID"`
}
type SetProjectOwner struct {
ProjectID uuid.UUID `json:"projectID"`
OwnerID uuid.UUID `json:"ownerID"`
}
type SetProjectOwnerPayload struct {
Ok bool `json:"ok"`
PrevOwner *Member `json:"prevOwner"`
NewOwner *Member `json:"newOwner"`
}
type SetTaskChecklistItemComplete struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Complete bool `json:"complete"`
}
type SetTaskComplete struct {
TaskID uuid.UUID `json:"taskID"`
Complete bool `json:"complete"`
}
type SetTeamOwner struct {
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
}
type SetTeamOwnerPayload struct {
Ok bool `json:"ok"`
PrevOwner *Member `json:"prevOwner"`
NewOwner *Member `json:"newOwner"`
}
type TaskBadges struct {
Checklist *ChecklistBadge `json:"checklist"`
}
type ToggleTaskLabelInput struct {
TaskID uuid.UUID `json:"taskID"`
ProjectLabelID uuid.UUID `json:"projectLabelID"`
}
type ToggleTaskLabelPayload struct {
Active bool `json:"active"`
Task *db.Task `json:"task"`
}
type UnassignTaskInput struct {
TaskID uuid.UUID `json:"taskID"`
UserID uuid.UUID `json:"userID"`
}
type UpdateProjectLabel struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
LabelColorID uuid.UUID `json:"labelColorID"`
Name string `json:"name"`
}
type UpdateProjectLabelColor struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
LabelColorID uuid.UUID `json:"labelColorID"`
}
type UpdateProjectLabelName struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
Name string `json:"name"`
}
type UpdateProjectMemberRole struct {
ProjectID uuid.UUID `json:"projectID"`
UserID uuid.UUID `json:"userID"`
RoleCode RoleCode `json:"roleCode"`
}
type UpdateProjectMemberRolePayload struct {
Ok bool `json:"ok"`
Member *Member `json:"member"`
}
type UpdateProjectName struct {
ProjectID uuid.UUID `json:"projectID"`
Name string `json:"name"`
}
type UpdateTaskChecklistItemName struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Name string `json:"name"`
}
type UpdateTaskChecklistName struct {
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Name string `json:"name"`
}
type UpdateTaskDescriptionInput struct {
TaskID uuid.UUID `json:"taskID"`
Description string `json:"description"`
}
type UpdateTaskDueDate struct {
TaskID uuid.UUID `json:"taskID"`
DueDate *time.Time `json:"dueDate"`
}
type UpdateTaskGroupName struct {
TaskGroupID uuid.UUID `json:"taskGroupID"`
Name string `json:"name"`
}
type UpdateTaskLocationPayload struct {
PreviousTaskGroupID uuid.UUID `json:"previousTaskGroupID"`
Task *db.Task `json:"task"`
}
type UpdateTaskName struct {
TaskID string `json:"taskID"`
Name string `json:"name"`
}
type UpdateTeamMemberRole struct {
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
RoleCode RoleCode `json:"roleCode"`
}
type UpdateTeamMemberRolePayload struct {
Ok bool `json:"ok"`
Member *Member `json:"member"`
}
type RoleCode string
const (
RoleCodeOwner RoleCode = "owner"
RoleCodeAdmin RoleCode = "admin"
RoleCodeMember RoleCode = "member"
RoleCodeObserver RoleCode = "observer"
)
var AllRoleCode = []RoleCode{
RoleCodeOwner,
RoleCodeAdmin,
RoleCodeMember,
RoleCodeObserver,
}
func (e RoleCode) IsValid() bool {
switch e {
case RoleCodeOwner, RoleCodeAdmin, RoleCodeMember, RoleCodeObserver:
return true
}
return false
}
func (e RoleCode) String() string {
return string(e)
}
func (e *RoleCode) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}
*e = RoleCode(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid RoleCode", str)
}
return nil
}
func (e RoleCode) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}

View File

@ -0,0 +1,14 @@
//go:generate sh ../scripts/genSchema.sh
//go:generate go run github.com/99designs/gqlgen
package graph
import (
"sync"
"github.com/jordanknott/project-citadel/api/internal/db"
)
type Resolver struct {
Repository db.Repository
mu sync.Mutex
}

View File

@ -0,0 +1,23 @@
package graph
import (
"io"
"github.com/99designs/gqlgen/graphql"
"github.com/google/uuid"
"github.com/pkg/errors"
"strconv"
)
func MarshalUUID(uuid uuid.UUID) graphql.Marshaler {
return graphql.WriterFunc(func(w io.Writer) {
w.Write([]byte(strconv.Quote(uuid.String())))
})
}
func UnmarshalUUID(v interface{}) (uuid.UUID, error) {
if uuidRaw, ok := v.(string); ok {
return uuid.Parse(uuidRaw)
}
return uuid.UUID{}, errors.New("uuid must be a string")
}

View File

@ -0,0 +1,567 @@
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 Member {
id: ID!
role: Role!
fullName: String!
username: String!
profileIcon: ProfileIcon!
}
type RefreshToken {
id: ID!
userId: UUID!
expiresAt: Time!
createdAt: Time!
}
type Role {
code: String!
name: String!
}
type UserAccount {
id: ID!
email: String!
createdAt: Time!
fullName: String!
initials: String!
role: Role!
username: String!
profileIcon: ProfileIcon!
}
type Team {
id: ID!
createdAt: Time!
name: String!
members: [Member!]!
}
type Project {
id: ID!
createdAt: Time!
name: String!
team: Team!
owner: Member!
taskGroups: [TaskGroup!]!
members: [Member!]!
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 Task {
id: ID!
taskGroup: TaskGroup!
createdAt: Time!
name: String!
position: Float!
description: String
dueDate: Time
complete: Boolean!
assigned: [Member!]!
labels: [TaskLabel!]!
checklists: [TaskChecklist!]!
badges: TaskBadges!
}
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!]!
}
type Query {
organizations: [Organization!]!
users: [UserAccount!]!
findUser(input: FindUser!): UserAccount!
findProject(input: FindProject!): Project!
findTask(input: FindTask!): Task!
projects(input: ProjectsFilter): [Project!]!
findTeam(input: FindTeam!): Team!
teams: [Team!]!
labelColors: [LabelColor!]!
taskGroups: [TaskGroup!]!
me: UserAccount!
}
type Mutation
input ProjectsFilter {
teamID: UUID
}
input FindUser {
userId: String!
}
input FindProject {
projectId: String!
}
input FindTask {
taskID: UUID!
}
input FindTeam {
teamID: UUID!
}
extend type Mutation {
createProject(input: NewProject!): Project!
deleteProject(input: DeleteProject!): DeleteProjectPayload!
updateProjectName(input: UpdateProjectName): Project!
}
input NewProject {
userID: UUID!
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!
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
}
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 {
createProjectMember(input: CreateProjectMember!): CreateProjectMemberPayload!
deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload!
updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload!
setProjectOwner(input: SetProjectOwner!): SetProjectOwnerPayload!
}
input CreateProjectMember {
projectID: UUID!
userID: UUID!
}
type CreateProjectMemberPayload {
ok: Boolean!
member: Member!
}
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!
}
input SetProjectOwner {
projectID: UUID!
ownerID: UUID!
}
type SetProjectOwnerPayload {
ok: Boolean!
prevOwner: Member!
newOwner: Member!
}
extend type Mutation {
createTask(input: NewTask!): Task!
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
updateTaskName(input: UpdateTaskName!): Task!
setTaskComplete(input: SetTaskComplete!): Task!
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
assignTask(input: AssignTaskInput): Task!
unassignTask(input: UnassignTaskInput): Task!
}
input NewTask {
taskGroupID: String!
name: String!
position: Float!
}
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!
dueDate: Time
}
input SetTaskComplete {
taskID: UUID!
complete: Boolean!
}
input NewTaskLocation {
taskID: UUID!
taskGroupID: UUID!
position: Float!
}
input DeleteTaskInput {
taskID: String!
}
type DeleteTaskPayload {
taskID: String!
}
input UpdateTaskName {
taskID: String!
name: String!
}
extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
}
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 {
createTaskGroup(input: NewTaskGroup!): TaskGroup!
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
}
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: String!
name: String!
position: Float!
}
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskLabelID: UUID!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput): Task!
removeTaskLabel(input: RemoveTaskLabelInput): Task!
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
}
extend type Mutation {
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
createTeam(input: NewTeam!): Team!
}
input NewTeam {
name: String!
organizationID: UUID!
}
input DeleteTeam {
teamID: UUID!
}
type DeleteTeamPayload {
ok: Boolean!
team: Team!
projects: [Project!]!
}
extend type Mutation {
setTeamOwner(input: SetTeamOwner!): SetTeamOwnerPayload!
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload!
deleteTeamMember(input: DeleteTeamMember!): DeleteTeamMemberPayload!
}
input DeleteTeamMember {
teamID: UUID!
userID: UUID!
}
type DeleteTeamMemberPayload {
teamID: UUID!
userID: UUID!
}
input CreateTeamMember {
userID: UUID!
teamID: UUID!
}
type CreateTeamMemberPayload {
team: Team!
teamMember: Member!
}
input UpdateTeamMemberRole {
teamID: UUID!
userID: UUID!
roleCode: RoleCode!
}
type UpdateTeamMemberRolePayload {
ok: Boolean!
member: Member!
}
input SetTeamOwner {
teamID: UUID!
userID: UUID!
}
type SetTeamOwnerPayload {
ok: Boolean!
prevOwner: Member!
newOwner: Member!
}
extend type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
createUserAccount(input: NewUserAccount!): UserAccount!
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
logoutUser(input: LogoutUser!): Boolean!
clearProfileAvatar: UserAccount!
}
input NewRefreshToken {
userId: String!
}
input NewUserAccount {
username: String!
email: String!
fullName: String!
initials: String!
password: String!
roleCode: String!
}
input LogoutUser {
userID: String!
}
input DeleteUserAccount {
userID: UUID!
}
type DeleteUserAccountPayload {
ok: Boolean!
userAccount: UserAccount!
}

View File

@ -0,0 +1,560 @@
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 Member {
id: ID!
role: Role!
fullName: String!
username: String!
profileIcon: ProfileIcon!
}
type RefreshToken {
id: ID!
userId: UUID!
expiresAt: Time!
createdAt: Time!
}
type Role {
code: String!
name: String!
}
type UserAccount {
id: ID!
email: String!
createdAt: Time!
fullName: String!
initials: String!
role: Role!
username: String!
profileIcon: ProfileIcon!
}
type Team {
id: ID!
createdAt: Time!
name: String!
members: [Member!]!
}
type Project {
id: ID!
createdAt: Time!
name: String!
team: Team!
owner: Member!
taskGroups: [TaskGroup!]!
members: [Member!]!
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 Task {
id: ID!
taskGroup: TaskGroup!
createdAt: Time!
name: String!
position: Float!
description: String
dueDate: Time
complete: Boolean!
assigned: [Member!]!
labels: [TaskLabel!]!
checklists: [TaskChecklist!]!
badges: TaskBadges!
}
input ProjectsFilter {
teamID: UUID
}
input FindUser {
userId: String!
}
input FindProject {
projectId: String!
}
input FindTask {
taskID: UUID!
}
type Organization {
id: ID!
name: String!
}
input ProjectsFilter {
teamID: UUID
}
input FindUser {
userId: String!
}
input FindProject {
projectId: String!
}
input FindTask {
taskID: UUID!
}
type Organization {
id: ID!
name: String!
}
input FindTeam {
teamID: UUID!
}
type Query {
organizations: [Organization!]!
users: [UserAccount!]!
findUser(input: FindUser!): UserAccount!
findProject(input: FindProject!): Project!
findTask(input: FindTask!): Task!
projects(input: ProjectsFilter): [Project!]!
findTeam(input: FindTeam!): Team!
teams: [Team!]!
labelColors: [LabelColor!]!
taskGroups: [TaskGroup!]!
me: UserAccount!
}
type Mutation {}
extend type Mutation {
createTask(input: NewTask!): Task!
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
updateTaskName(input: UpdateTaskName!): Task!
setTaskComplete(input: SetTaskComplete!): Task!
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
assignTask(input: AssignTaskInput): Task!
unassignTask(input: UnassignTaskInput): Task!
}
input NewRefreshToken {
userId: String!
}
input NewUserAccount {
username: String!
email: String!
fullName: String!
initials: String!
password: String!
roleCode: String!
}
input NewTeam {
name: String!
organizationID: UUID!
}
input NewProject {
userID: UUID!
teamID: UUID!
name: String!
}
input NewTaskGroup {
projectID: String!
name: String!
position: Float!
}
input LogoutUser {
userID: String!
}
input NewTask {
taskGroupID: String!
name: String!
position: Float!
}
input NewTaskLocation {
taskID: UUID!
taskGroupID: UUID!
position: Float!
}
input DeleteTaskInput {
taskID: String!
}
type DeleteTaskPayload {
taskID: String!
}
input UpdateTaskName {
taskID: String!
name: String!
}
input NewTaskGroupLocation {
taskGroupID: UUID!
position: Float!
}
input DeleteTaskGroupInput {
taskGroupID: UUID!
}
type DeleteTaskGroupPayload {
ok: Boolean!
affectedRows: Int!
taskGroup: TaskGroup!
}
type DeleteTaskChecklistItemPayload {
ok: Boolean!
taskChecklistItem: TaskChecklistItem!
}
type TaskChecklistItem {
id: ID!
name: String!
taskChecklistID: UUID!
complete: Boolean!
position: Float!
dueDate: Time!
}
type TaskChecklist {
id: ID!
name: String!
position: Float!
items: [TaskChecklistItem!]!
}
input AssignTaskInput {
taskID: UUID!
userID: UUID!
}
input UnassignTaskInput {
taskID: UUID!
userID: UUID!
}
input UpdateTaskDescriptionInput {
taskID: UUID!
description: String!
}
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskLabelID: UUID!
}
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!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
input UpdateProjectName {
projectID: UUID!
name: String!
}
type UpdateTaskLocationPayload {
previousTaskGroupID: UUID!
task: Task!
}
input UpdateTaskGroupName {
taskGroupID: UUID!
name: String!
}
input UpdateTaskDueDate {
taskID: UUID!
dueDate: Time
}
input SetTaskComplete {
taskID: UUID!
complete: Boolean!
}
input CreateTaskChecklist {
taskID: UUID!
name: String!
position: Float!
}
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 CreateTeamMember {
userID: UUID!
teamID: UUID!
}
type CreateTeamMemberPayload {
team: Team!
teamMember: Member!
}
input DeleteProject {
projectID: UUID!
}
type DeleteProjectPayload {
ok: Boolean!
project: Project!
}
input DeleteTeam {
teamID: UUID!
}
type DeleteTeamPayload {
ok: Boolean!
team: Team!
projects: [Project!]!
}
input DeleteUserAccount {
userID: UUID!
}
type DeleteUserAccountPayload {
ok: Boolean!
userAccount: UserAccount!
}
input UpdateTaskChecklistName {
taskChecklistID: UUID!
name: String!
}
input DeleteTaskChecklist {
taskChecklistID: UUID!
}
type DeleteTaskChecklistPayload {
ok: Boolean!
taskChecklist: TaskChecklist!
}
input CreateProjectMember {
projectID: UUID!
userID: UUID!
}
type CreateProjectMemberPayload {
ok: Boolean!
member: Member!
}
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!
}
input SetProjectOwner {
projectID: UUID!
ownerID: UUID!
}
type SetProjectOwnerPayload {
ok: Boolean!
prevOwner: Member!
newOwner: Member!
}
input UpdateTeamMemberRole {
teamID: UUID!
userID: UUID!
roleCode: RoleCode!
}
type UpdateTeamMemberRolePayload {
ok: Boolean!
member: Member!
}
input SetTeamOwner {
teamID: UUID!
userID: UUID!
}
type SetTeamOwnerPayload {
ok: Boolean!
prevOwner: Member!
newOwner: Member!
}
type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
createUserAccount(input: NewUserAccount!): UserAccount!
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
createTeam(input: NewTeam!): Team!
clearProfileAvatar: UserAccount!
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload!
setTeamOwner(input: SetTeamOwner!): SetTeamOwnerPayload!
createProject(input: NewProject!): Project!
deleteProject(input: DeleteProject!): DeleteProjectPayload!
updateProjectName(input: UpdateProjectName): Project!
createProjectMember(input: CreateProjectMember!): CreateProjectMemberPayload!
deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload!
updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload!
setProjectOwner(input: SetProjectOwner!): SetProjectOwnerPayload!
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
createTaskGroup(input: NewTaskGroup!): TaskGroup!
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
addTaskLabel(input: AddTaskLabelInput): Task!
removeTaskLabel(input: RemoveTaskLabelInput): Task!
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
logoutUser(input: LogoutUser!): Boolean!
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
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 Member {
id: ID!
role: Role!
fullName: String!
username: String!
profileIcon: ProfileIcon!
}
type RefreshToken {
id: ID!
userId: UUID!
expiresAt: Time!
createdAt: Time!
}
type Role {
code: String!
name: String!
}
type UserAccount {
id: ID!
email: String!
createdAt: Time!
fullName: String!
initials: String!
role: Role!
username: String!
profileIcon: ProfileIcon!
}
type Team {
id: ID!
createdAt: Time!
name: String!
members: [Member!]!
}
type Project {
id: ID!
createdAt: Time!
name: String!
team: Team!
owner: Member!
taskGroups: [TaskGroup!]!
members: [Member!]!
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 Task {
id: ID!
taskGroup: TaskGroup!
createdAt: Time!
name: String!
position: Float!
description: String
dueDate: Time
complete: Boolean!
assigned: [Member!]!
labels: [TaskLabel!]!
checklists: [TaskChecklist!]!
badges: TaskBadges!
}
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!]!
}

View File

@ -0,0 +1,35 @@
type Query {
organizations: [Organization!]!
users: [UserAccount!]!
findUser(input: FindUser!): UserAccount!
findProject(input: FindProject!): Project!
findTask(input: FindTask!): Task!
projects(input: ProjectsFilter): [Project!]!
findTeam(input: FindTeam!): Team!
teams: [Team!]!
labelColors: [LabelColor!]!
taskGroups: [TaskGroup!]!
me: UserAccount!
}
type Mutation
input ProjectsFilter {
teamID: UUID
}
input FindUser {
userId: String!
}
input FindProject {
projectId: String!
}
input FindTask {
taskID: UUID!
}
input FindTeam {
teamID: UUID!
}

View File

@ -0,0 +1,26 @@
extend type Mutation {
createProject(input: NewProject!): Project!
deleteProject(input: DeleteProject!): DeleteProjectPayload!
updateProjectName(input: UpdateProjectName): Project!
}
input NewProject {
userID: UUID!
teamID: UUID!
name: String!
}
input UpdateProjectName {
projectID: UUID!
name: String!
}
input DeleteProject {
projectID: UUID!
}
type DeleteProjectPayload {
ok: Boolean!
project: Project!
}

View File

@ -0,0 +1,33 @@
extend type Mutation {
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
}
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!
}

View File

@ -0,0 +1,48 @@
extend type Mutation {
createProjectMember(input: CreateProjectMember!): CreateProjectMemberPayload!
deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload!
updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload!
setProjectOwner(input: SetProjectOwner!): SetProjectOwnerPayload!
}
input CreateProjectMember {
projectID: UUID!
userID: UUID!
}
type CreateProjectMemberPayload {
ok: Boolean!
member: Member!
}
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!
}
input SetProjectOwner {
projectID: UUID!
ownerID: UUID!
}
type SetProjectOwnerPayload {
ok: Boolean!
prevOwner: Member!
newOwner: Member!
}

View File

@ -0,0 +1,68 @@
extend type Mutation {
createTask(input: NewTask!): Task!
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
updateTaskName(input: UpdateTaskName!): Task!
setTaskComplete(input: SetTaskComplete!): Task!
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
assignTask(input: AssignTaskInput): Task!
unassignTask(input: UnassignTaskInput): Task!
}
input NewTask {
taskGroupID: String!
name: String!
position: Float!
}
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!
dueDate: Time
}
input SetTaskComplete {
taskID: UUID!
complete: Boolean!
}
input NewTaskLocation {
taskID: UUID!
taskGroupID: UUID!
position: Float!
}
input DeleteTaskInput {
taskID: String!
}
type DeleteTaskPayload {
taskID: String!
}
input UpdateTaskName {
taskID: String!
name: String!
}

View File

@ -0,0 +1,52 @@
extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
}
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!
}

View File

@ -0,0 +1,32 @@
extend type Mutation {
createTaskGroup(input: NewTaskGroup!): TaskGroup!
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
}
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: String!
name: String!
position: Float!
}

View File

@ -0,0 +1,22 @@
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskLabelID: UUID!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput): Task!
removeTaskLabel(input: RemoveTaskLabelInput): Task!
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
}

View File

@ -0,0 +1,19 @@
extend type Mutation {
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
createTeam(input: NewTeam!): Team!
}
input NewTeam {
name: String!
organizationID: UUID!
}
input DeleteTeam {
teamID: UUID!
}
type DeleteTeamPayload {
ok: Boolean!
team: Team!
projects: [Project!]!
}

View File

@ -0,0 +1,48 @@
extend type Mutation {
setTeamOwner(input: SetTeamOwner!): SetTeamOwnerPayload!
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload!
deleteTeamMember(input: DeleteTeamMember!): DeleteTeamMemberPayload!
}
input DeleteTeamMember {
teamID: UUID!
userID: UUID!
}
type DeleteTeamMemberPayload {
teamID: UUID!
userID: UUID!
}
input CreateTeamMember {
userID: UUID!
teamID: UUID!
}
type CreateTeamMemberPayload {
team: Team!
teamMember: Member!
}
input UpdateTeamMemberRole {
teamID: UUID!
userID: UUID!
roleCode: RoleCode!
}
type UpdateTeamMemberRolePayload {
ok: Boolean!
member: Member!
}
input SetTeamOwner {
teamID: UUID!
userID: UUID!
}
type SetTeamOwnerPayload {
ok: Boolean!
prevOwner: Member!
newOwner: Member!
}

View File

@ -0,0 +1,33 @@
extend type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
createUserAccount(input: NewUserAccount!): UserAccount!
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
logoutUser(input: LogoutUser!): Boolean!
clearProfileAvatar: UserAccount!
}
input NewRefreshToken {
userId: String!
}
input NewUserAccount {
username: String!
email: String!
fullName: String!
initials: String!
password: String!
roleCode: String!
}
input LogoutUser {
userID: String!
}
input DeleteUserAccount {
userID: UUID!
}
type DeleteUserAccountPayload {
ok: Boolean!
userAccount: UserAccount!
}