stufflog graphql server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

345 lines
9.5 KiB

package resolvers
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
import (
"context"
"errors"
"fmt"
"time"
"git.aiterp.net/stufflog/server/graph/graphcore"
"git.aiterp.net/stufflog/server/internal/slerrors"
"git.aiterp.net/stufflog/server/models"
)
func (r *mutationResolver) CreateProject(ctx context.Context, input graphcore.ProjectCreateInput) (*models.Project, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
project := &models.Project{
ID: input.ID,
Name: input.Name,
Description: input.Description,
DailyPoints: input.DailyPoints,
}
if !project.ValidKey() {
return nil, errors.New("the project must have a valid ID (only uppercase allowed)")
}
if project.Name == "" || project.Description == "" {
return nil, errors.New("name and description cannot be left empty")
}
project, err := r.Database.Projects().Insert(ctx, *project)
if err != nil {
return nil, err
}
err = r.Database.Projects().SetPermission(ctx, models.ProjectPermission{
ProjectID: project.ID,
UserID: user.ID,
Level: models.ProjectPermissionLevelOwner,
})
return project, nil
}
func (r *mutationResolver) CreateActivity(ctx context.Context, input graphcore.ActivityCreateInput) (*models.Activity, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
project, err := r.Database.Projects().Find(ctx, input.ProjectID)
if err != nil {
return nil, err
}
if perm, err := r.Auth.ProjectPermission(ctx, *project); err != nil || !perm.CanManageActivities() {
return nil, slerrors.PermissionDenied
}
activity := &models.Activity{
ProjectID: project.ID,
Name: input.Name,
Countable: input.Countable != nil && *input.Countable,
UnitIsTimeSpent: input.UnitIsTimeSpent != nil && *input.UnitIsTimeSpent,
BaseValue: input.BaseValue,
}
if !activity.UnitIsTimeSpent && activity.Countable {
if input.UnitName != nil {
activity.UnitName = *input.UnitName
} else {
return nil, errors.New("unit name is required for countable non-time-spent activities")
}
}
if activity.UnitIsTimeSpent || activity.Countable {
if input.UnitValue != nil {
activity.UnitValue = *input.UnitValue
}
}
return r.Database.Activities().Insert(ctx, *activity)
}
func (r *mutationResolver) EditActivity(ctx context.Context, input graphcore.ActivityEditInput) (*models.Activity, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
activity, err := r.Database.Activities().Find(ctx, input.ActivityID)
if err != nil {
return nil, err
}
project, err := r.Database.Projects().Find(ctx, activity.ProjectID)
if err != nil {
return nil, err
}
if perm, err := r.Auth.ProjectPermission(ctx, *project); err != nil || !perm.CanManageActivities() {
return nil, slerrors.PermissionDenied
}
if input.SetName != nil {
activity.Name = *input.SetName
}
if input.SetBaseValue != nil {
activity.BaseValue = *input.SetBaseValue
}
if input.SetUnitName != nil {
activity.UnitName = *input.SetUnitName
}
if input.SetUnitValue != nil {
activity.UnitValue = *input.SetUnitValue
}
err = r.Database.Activities().Save(ctx, *activity)
if err != nil {
return nil, err
}
return activity, nil
}
func (r *mutationResolver) CreateItem(ctx context.Context, input *graphcore.ItemCreateInput) (*models.Item, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
if input.Name == "" {
return nil, errors.New("name cannot be blank")
}
if input.Description == "" {
return nil, errors.New("name cannot be blank")
}
if len(input.Tags) == 0 {
return nil, errors.New("at least one tag is required")
}
if input.Image != nil {
panic("todo: implement image upload")
}
item := models.Item{
Name: input.Name,
Description: input.Description,
Tags: input.Tags,
QuantityUnit: input.QuantityUnit,
ImageURL: nil,
}
return r.Database.Items().Insert(ctx, item)
}
func (r *mutationResolver) EditItem(ctx context.Context, input *graphcore.ItemEditInput) (*models.Item, error) {
panic(fmt.Errorf("not implemented"))
}
func (r *mutationResolver) CreateIssue(ctx context.Context, input graphcore.IssueCreateInput) (*models.Issue, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
project, err := r.Database.Projects().Find(ctx, input.ProjectID)
if err != nil {
return nil, err
}
if perm, err := r.Auth.ProjectPermission(ctx, *project); err != nil || !perm.CanManageOwnIssue() {
return nil, slerrors.PermissionDenied
}
status, err := r.Database.ProjectStatuses().Find(ctx, project.ID, input.StatusName)
if err != nil {
return nil, err
}
issue := &models.Issue{
ProjectID: project.ID,
OwnerID: user.ID,
AssigneeID: "",
StatusStage: status.Stage,
StatusName: status.Name,
Name: input.Name,
Title: input.Name, // Title set below if it's in the input.
Description: input.Description,
}
if input.Title != nil && *input.Title != "" {
issue.Title = *input.Title
}
if input.DueTime != nil && !input.DueTime.IsZero() {
issue.DueTime = *input.DueTime
}
if input.AssigneeID != nil && *input.AssigneeID != "" {
issue.AssigneeID = *input.AssigneeID
}
issue, err = r.Database.Issues().Insert(ctx, *issue)
if err != nil {
return nil, err
}
return issue, nil
}
func (r *mutationResolver) CreateIssueTask(ctx context.Context, input graphcore.IssueTaskCreateInput) (*models.IssueTask, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
issue, err := r.Database.Issues().Find(ctx, input.IssueID)
if err != nil {
return nil, err
}
if perm, err := r.Auth.IssuePermission(ctx, *issue); err != nil || !perm.CanManageOwnIssue() {
return nil, slerrors.PermissionDenied
}
status, err := r.Database.ProjectStatuses().Find(ctx, issue.ProjectID, input.StatusName)
if err != nil {
return nil, err
}
activity, err := r.Database.Activities().Find(ctx, input.ActivityID)
if err != nil {
return nil, err
} else if activity.ProjectID != issue.ProjectID {
return nil, slerrors.NotFound("Activity")
}
issueTask := &models.IssueTask{
IssueID: issue.ID,
ActivityID: activity.ID,
CreatedTime: time.Now(),
UpdatedTime: time.Now(),
StatusStage: status.Stage,
StatusName: status.Name,
Name: input.Name,
Description: input.Description,
PointsMultiplier: 1.0,
}
if input.EstimatedUnits != nil && activity.Countable && !activity.UnitIsTimeSpent {
issueTask.EstimatedUnits = *input.EstimatedUnits
}
if input.PointsMultiplier != nil && *input.PointsMultiplier > 0 {
issueTask.PointsMultiplier = *input.PointsMultiplier
}
issueTask, err = r.Database.IssueTasks().Insert(ctx, *issueTask)
if err != nil {
return nil, err
}
return issueTask, nil
}
func (r *mutationResolver) EditIssueTask(ctx context.Context, input graphcore.IssueTaskEditInput) (*models.IssueTask, error) {
user := r.Auth.UserFromContext(ctx)
if user == nil {
return nil, slerrors.PermissionDenied
}
task, err := r.Database.IssueTasks().Find(ctx, input.IssueTaskID)
if err != nil {
return nil, err
}
issue, err := r.Database.Issues().Find(ctx, task.IssueID)
if err != nil {
return nil, err
}
if perm, err := r.Auth.IssuePermission(ctx, *issue); err != nil || !perm.CanManageOwnIssue() {
return nil, slerrors.PermissionDenied
}
if input.SetName != nil {
task.Name = *input.SetName
}
if input.SetDescription != nil {
task.Description = *input.SetDescription
}
if input.SetDueTime != nil {
task.DueTime = input.SetDueTime
}
if input.SetEstimatedTime != nil {
task.EstimatedTime = *input.SetEstimatedTime
}
if input.SetEstimatedUnits != nil {
activity, err := r.Database.Activities().Find(ctx, task.ActivityID)
if err != nil {
return nil, err
}
if activity.Countable && !activity.UnitIsTimeSpent {
task.EstimatedUnits = *input.SetEstimatedUnits
}
}
if input.SetPointsMultiplier != nil && *input.SetPointsMultiplier > 0 {
task.PointsMultiplier = *input.SetPointsMultiplier
}
if input.SetStatusName != nil {
status, err := r.Database.ProjectStatuses().Find(ctx, issue.ProjectID, *input.SetStatusName)
if err != nil {
return nil, err
}
task.StatusName = status.Name
task.StatusStage = status.Stage
}
err = r.Database.IssueTasks().Save(ctx, *task)
if err != nil {
return nil, err
}
return task, nil
}
func (r *mutationResolver) LoginUser(ctx context.Context, input graphcore.UserLoginInput) (*models.User, error) {
return r.Auth.Login(ctx, input.Username, input.Password)
}
func (r *mutationResolver) LogoutUser(ctx context.Context) (*models.User, error) {
return r.Auth.Logout(ctx)
}
func (r *mutationResolver) CreateUser(ctx context.Context, input graphcore.UserCreateInput) (*models.User, error) {
active := input.Active == nil || *input.Active
admin := input.Admin != nil && *input.Admin
return r.Auth.CreateUser(ctx, input.Username, input.Password, input.Name, active, admin)
}
func (r *mutationResolver) EditUser(ctx context.Context, input graphcore.UserEditInput) (*models.User, error) {
return r.Auth.EditUser(ctx, input.Username, input.SetName, input.CurrentPassword, input.SetPassword)
}
// Mutation returns graphcore.MutationResolver implementation.
func (r *Resolver) Mutation() graphcore.MutationResolver { return &mutationResolver{r} }
type mutationResolver struct{ *Resolver }