projecteps

package
v0.0.0-...-07f0968 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2022 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Eps = []*app.Endpoint{
		{
			Description:  "Create a new project",
			Path:         (&project.Create{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.Create{
					CurrencyCode: "USD",
					HoursPerDay:  nil,
					DaysPerWeek:  nil,
					IsPublic:     false,
				}
			},
			GetExampleArgs: func() interface{} {
				return &project.Create{
					CurrencyCode: "USD",
					HoursPerDay:  ptr.Uint8(8),
					DaysPerWeek:  ptr.Uint8(5),
					StartOn:      ptr.Time(app.ExampleTime()),
					EndOn:        ptr.Time(app.ExampleTime().Add(24 * time.Hour)),
					IsPublic:     false,
					Name:         "My New Project",
				}
			},
			GetExampleResponse: func() interface{} {
				return exampleProject
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*project.Create)
				me := me.AuthedGet(tlbx)
				args.Name = StrTrimWS(args.Name)
				validate.Str("name", args.Name, nameMinLen, nameMaxLen)
				if args.CurrencyCode == "" {
					args.CurrencyCode = "USD"
				}
				validateCurrencyCode(tlbx, args.CurrencyCode)
				app.BadReqIf(args.HoursPerDay != nil && (*args.HoursPerDay < 1 || *args.HoursPerDay > 24), "invalid hoursPerDay must be > 0 and <= 24")
				app.BadReqIf(args.DaysPerWeek != nil && (*args.DaysPerWeek < 1 || *args.DaysPerWeek > 7), "invalid daysPerWeek must be > 0 and <= 7")
				app.BadReqIf((args.HoursPerDay == nil && args.DaysPerWeek != nil) ||
					(args.HoursPerDay != nil && args.DaysPerWeek == nil), "invalid hoursPerDay and daysPerWeek must both be set or not set")
				app.BadReqIf(args.StartOn != nil && args.EndOn != nil && !args.StartOn.Before(*args.EndOn), "invalid startOn must be before endOn")
				p := &project.Project{
					Task: task.Task{
						ID:         tlbx.NewID(),
						Name:       args.Name,
						User:       ptr.ID(me),
						CreatedBy:  me,
						CreatedOn:  tlbx.Start(),
						IsParallel: false,
					},
					Base: project.Base{
						CurrencyCode: args.CurrencyCode,
						HoursPerDay:  args.HoursPerDay,
						DaysPerWeek:  args.DaysPerWeek,
						StartOn:      args.StartOn,
						EndOn:        args.EndOn,
						IsPublic:     args.IsPublic,
					},
					Host:       me,
					IsArchived: false,
				}
				srv := service.Get(tlbx)

				u := &user.User{}
				row := srv.User().QueryRow(`SELECT id, handle, alias, hasAvatar FROM users WHERE id=?`, me)
				PanicOn(row.Scan(&u.ID, &u.Handle, &u.Alias, &u.HasAvatar))

				tx := srv.Data().BeginWrite()
				defer tx.Rollback()
				_, err := tx.Exec(`INSERT INTO projectLocks (host, id) VALUES (?, ?)`, p.Host, p.ID)
				PanicOn(err)
				_, err = tx.Exec(`INSERT INTO users (host, project, id, handle, alias, hasAvatar, isActive, role) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, p.Host, p.ID, me, u.Handle, u.Alias, u.HasAvatar, true, cnsts.RoleAdmin)
				PanicOn(err)
				_, err = tx.Exec(`INSERT INTO projects (host, id, isArchived, name, createdOn, currencyCode, hoursPerDay, daysPerWeek, startOn, endOn, isPublic, fileLimit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, p.Host, p.ID, p.IsArchived, p.Name, p.CreatedOn, p.CurrencyCode, p.HoursPerDay, p.DaysPerWeek, p.StartOn, p.EndOn, p.IsPublic, p.FileLimit)
				PanicOn(err)
				_, err = tx.Exec(`INSERT INTO tasks (host, project, id, parent, firstChild, nextSib, user, name, description, isParallel, createdBy, createdOn, timeEst, timeInc, timeSubMin, timeSubEst, timeSubInc, costEst, costInc, costSubEst, costSubInc, fileN, fileSize, fileSubN, fileSubSize, childN, descN) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, p.Host, p.ID, p.ID, p.Parent, p.FirstChild, p.NextSib, p.User, p.Name, p.Description, p.IsParallel, p.CreatedBy, p.CreatedOn, p.TimeEst, p.TimeInc, p.TimeSubMin, p.TimeSubEst, p.TimeSubInc, p.CostEst, p.CostInc, p.CostSubEst, p.CostSubInc, p.FileN, p.FileSize, p.FileSubN, p.FileSubSize, p.ChildN, p.DescN)
				PanicOn(err)
				epsutil.LogActivity(tlbx, tx, me, p.ID, p.ID, p.ID, cnsts.TypeTask, cnsts.ActionCreated, ptr.String(p.Name), nil, nil, nil)
				tx.Commit()
				return p
			},
		},
		{
			Description:  "Get a project set",
			Path:         (&project.Get{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.Get{
					IsArchived: false,
					Sort:       cnsts.SortCreatedOn,
					Asc:        ptr.Bool(true),
					Limit:      100,
				}
			},
			GetExampleArgs: func() interface{} {
				return &project.Get{
					IsArchived:   false,
					Others:       true,
					NamePrefix:   ptr.String("My Proj"),
					CreatedOnMin: ptr.Time(app.ExampleTime()),
					CreatedOnMax: ptr.Time(app.ExampleTime()),
					After:        ptr.ID(app.ExampleID()),
					Sort:         cnsts.SortName,
					Asc:          ptr.Bool(true),
					Limit:        50,
				}
			},
			GetExampleResponse: func() interface{} {
				return &project.GetRes{
					Set: []*project.Project{
						exampleProject,
					},
					More: true,
				}
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				return getSet(tlbx, a.(*project.Get))
			},
		},
		{
			Description:  "Get latest public projects",
			Path:         (&project.GetLatestPublic{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return nil
			},
			GetExampleArgs: func() interface{} {
				return nil
			},
			GetExampleResponse: func() interface{} {
				return &project.GetLatestPublicRes{
					Set: []*project.Project{
						exampleProject,
					},
				}
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				res := &project.GetLatestPublicRes{}
				tmpRes := getLatestPublicProjects(tlbx)
				if tmpRes != nil {
					res.Set = tmpRes.Set
				}
				return res
			},
		},
		{
			Description:  "Update a project",
			Path:         (&project.Updates{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.Updates{}
			},
			GetExampleArgs: func() interface{} {
				return &project.Updates{
					{
						ID:           app.ExampleID(),
						Name:         &field.String{V: "Renamed Project"},
						CurrencyCode: &field.String{V: "EUR"},
						HoursPerDay:  &field.UInt8Ptr{V: ptr.Uint8(6)},
						DaysPerWeek:  &field.UInt8Ptr{V: ptr.Uint8(4)},
						StartOn:      &field.TimePtr{V: ptr.Time(app.ExampleTime())},
						EndOn:        &field.TimePtr{V: ptr.Time(app.ExampleTime().Add(24 * time.Hour))},
						IsArchived:   &field.Bool{V: false},
						IsPublic:     &field.Bool{V: true},
					},
				}
			},
			GetExampleResponse: func() interface{} {
				return []*project.Project{
					exampleProject,
				}
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := *(a.(*project.Updates))
				if len(args) == 0 {
					return nil
				}
				app.BadReqIf(len(args) > 100, "can not update more than 100 projects at a time")
				me := me.AuthedGet(tlbx)
				ids := make(IDs, 0, len(args))
				namesSet := make([]bool, len(args))
				dupes := map[string]bool{}
				for i := 0; i < len(args); i++ {
					u := args[i]

					if u.Name == nil &&
						u.CurrencyCode == nil &&
						u.HoursPerDay == nil &&
						u.DaysPerWeek == nil &&
						u.StartOn == nil &&
						u.EndOn == nil &&
						u.IsArchived == nil &&
						u.IsPublic == nil {
						copy(args[i:], args[i+1:])
						args[len(args)-1] = nil
						args = args[:len(args)-1]
						i--
					} else {
						idStr := u.ID.String()
						app.BadReqIf(dupes[idStr], "duplicate entry detected")
						dupes[idStr] = true
						ids = append(ids, u.ID)
					}
				}
				ps := getSet(tlbx, &project.Get{Host: me, IDs: ids}).Set
				for i, p := range ps {
					a := args[i]
					if a.CurrencyCode != nil {
						validateCurrencyCode(tlbx, a.CurrencyCode.V)
						p.CurrencyCode = a.CurrencyCode.V
					}

					if a.Name != nil {
						a.Name.V = StrTrimWS(a.Name.V)
						validate.Str("name", a.Name.V, nameMinLen, nameMaxLen)
						p.Name = a.Name.V
						namesSet[i] = true
					}

					switch {
					case a.StartOn != nil && a.EndOn != nil:
						app.BadReqIf(a.StartOn.V != nil && a.EndOn.V != nil && !a.StartOn.V.Before(*a.EndOn.V), "invalid startOn must be before endOn")
					case a.StartOn != nil && p.EndOn != nil:
						app.BadReqIf(a.StartOn.V != nil && p.EndOn != nil && !a.StartOn.V.Before(*p.EndOn), "invalid startOn must be before endOn")
					case a.EndOn != nil && p.StartOn != nil:
						app.BadReqIf(p.StartOn != nil && a.EndOn.V != nil && !p.StartOn.Before(*a.EndOn.V), "invalid startOn must be before endOn")
					}
					if a.StartOn != nil {
						p.StartOn = a.StartOn.V
					}
					if a.EndOn != nil {
						p.EndOn = a.EndOn.V
					}
					if a.HoursPerDay != nil {
						app.BadReqIf(a.HoursPerDay.V != nil && (*a.HoursPerDay.V < 1 || *a.HoursPerDay.V > 24), "invalid hoursPerDay must be > 0 and <= 24")
						p.HoursPerDay = a.HoursPerDay.V
					}
					if a.DaysPerWeek != nil {
						app.BadReqIf(a.DaysPerWeek.V != nil && (*a.DaysPerWeek.V < 1 || *a.DaysPerWeek.V > 7), "invalid daysPerWeek must be > 0 and <= 7")
						p.DaysPerWeek = a.DaysPerWeek.V
					}
					app.BadReqIf(
						(p.HoursPerDay == nil && p.DaysPerWeek != nil) ||
							(p.HoursPerDay != nil && p.DaysPerWeek == nil),
						"invalid hoursPerDay And daysPerWeek must both be either set or not set")
					if a.IsArchived != nil {
						p.IsArchived = a.IsArchived.V
					}
					if a.IsPublic != nil {
						p.IsPublic = a.IsPublic.V
					}
				}
				srv := service.Get(tlbx)
				tx := srv.Data().BeginWrite()
				defer tx.Rollback()
				for i, p := range ps {
					_, err := tx.Exec(`UPDATE projects SET name=?, currencyCode=?, hoursPerDay=?, daysPerWeek=?, startOn=?, endOn=?, isArchived=?, isPublic=? WHERE host=? AND id=?`, p.Name, p.CurrencyCode, p.HoursPerDay, p.DaysPerWeek, p.StartOn, p.EndOn, p.IsArchived, p.IsPublic, me, p.ID)
					PanicOn(err)
					if namesSet[i] {
						_, err = tx.Exec(`UPDATE tasks SET name=? WHERE host=? AND project=? AND id=?`, p.Name, me, p.ID, p.ID)
						PanicOn(err)
						epsutil.ActivityItemRename(tx, me, p.ID, p.ID, p.Name, true)
					}
					epsutil.LogActivity(tlbx, tx, me, p.ID, p.ID, p.ID, cnsts.TypeTask, cnsts.ActionUpdated, ptr.String(p.Name), args[i], nil, nil)
				}
				tx.Commit()
				return ps
			},
		},
		{
			Description:  "delete projects",
			Path:         (&project.Delete{}).Path(),
			Timeout:      0,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.Delete{}
			},
			GetExampleArgs: func() interface{} {
				return &project.Delete{
					app.ExampleID(),
				}
			},
			GetExampleResponse: func() interface{} {
				return nil
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := *(a.(*project.Delete))
				if len(args) == 0 {
					return nil
				}
				app.BadReqIf(len(args) > 100, "can not delete more than 100 projects at a time")
				me := me.AuthedGet(tlbx)
				queryArgs := append([]interface{}{me}, IDs(args).ToIs()...)
				inID := sqlh.InCondition(true, "id", len(args))
				inProject := sqlh.InCondition(true, "project", len(args))
				srv := service.Get(tlbx)
				tx := srv.Data().BeginWrite()
				defer tx.Rollback()
				_, err := tx.Exec(Strf(`DELETE FROM projectLocks WHERE host=? %s`, inID), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM users WHERE host=? %s`, inProject), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM activities WHERE host=? %s`, inProject), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM projects WHERE host=? %s`, inID), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM tasks WHERE host=? %s`, inProject), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM vitems WHERE host=? %s`, inProject), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM files WHERE host=? %s`, inProject), queryArgs...)
				PanicOn(err)
				_, err = tx.Exec(Strf(`DELETE FROM comments WHERE host=? %s`, inProject), queryArgs...)
				PanicOn(err)
				for _, p := range args {
					srv.Store().MustDeletePrefix(cnsts.FileBucket, epsutil.StorePrefix(me, p))
				}
				tx.Commit()
				return nil
			},
		},
		{
			Description:  "add project users",
			Path:         (&project.AddUsers{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.AddUsers{}
			},
			GetExampleArgs: func() interface{} {
				return &project.AddUsers{
					Project: app.ExampleID(),
					Users: []*project.SendUser{
						{
							ID:   app.ExampleID(),
							Role: cnsts.RoleAdmin,
						},
					},
				}
			},
			GetExampleResponse: func() interface{} {
				return nil
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*project.AddUsers)
				lenUsers := len(args.Users)
				if lenUsers == 0 {
					return nil
				}
				app.BadReqIf(lenUsers > 100, "can not add more than 100 users to a project at a time")
				srv := service.Get(tlbx)
				tx := srv.Data().BeginWrite()
				defer tx.Rollback()
				epsutil.IMustHaveAccess(tlbx, tx, args.Host, args.Project, cnsts.RoleAdmin)

				ids := make([]interface{}, 0, 2*lenUsers)
				for i := 0; i < 2; i++ {
					for _, u := range args.Users {
						ids = append(ids, u.ID)
					}
				}

				userTx := srv.User().BeginWrite()
				defer userTx.Rollback()
				users := make([]*project.User, 0, lenUsers)
				PanicOn(userTx.Query(func(rows *sqlx.Rows) {
					for rows.Next() {
						u := &project.User{}
						PanicOn(rows.Scan(&u.ID, &u.Handle, &u.Alias, &u.HasAvatar))
						u.IsActive = true
						users = append(users, u)
					}
				}, Strf(`SELECT id, handle, alias, hasAvatar FROM users WHERE 1=1 %s %s FOR UPDATE`, sqlh.InCondition(true, `id`, lenUsers), sqlh.OrderByField(`id`, lenUsers)), ids...))

				app.BadReqIf(len(users) != lenUsers, "users specified: %d, users found: %d", lenUsers, len(users))

				for i, u := range users {
					app.BadReqIf(u.ID.Equal(args.Host), "can not add host to project")
					u.Role = args.Users[i].Role
					_, err := tx.Exec(`INSERT INTO users (host, project, id, handle, alias, hasAvatar, isActive, role) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, args.Host, args.Project, u.ID, u.Handle, u.Alias, u.HasAvatar, u.IsActive, u.Role)
					PanicOn(err)
					epsutil.LogActivity(tlbx, tx, args.Host, args.Project, args.Project, u.ID, cnsts.TypeUser, cnsts.ActionCreated, nil, u.Role, nil, nil)
				}
				tx.Commit()
				userTx.Commit()
				return nil
			},
		},
		{
			Description:  "get my project user",
			Path:         (&project.GetMe{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.GetMe{}
			},
			GetExampleArgs: func() interface{} {
				return &project.GetMe{
					Host:    app.ExampleID(),
					Project: app.ExampleID(),
				}
			},
			GetExampleResponse: func() interface{} {
				return exampleUser
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				if !me.AuthedExists(tlbx) {
					return nil
				}
				args := a.(*project.GetMe)
				users := getUsers(tlbx, &project.GetUsers{
					Host:    args.Host,
					Project: args.Project,
					IDs:     IDs{me.AuthedGet(tlbx)},
				})
				if len(users.Set) == 0 {
					return nil
				}
				return users.Set[0]
			},
		},
		{
			Description:  "get project users",
			Path:         (&project.GetUsers{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.GetUsers{
					Limit: 100,
				}
			},
			GetExampleArgs: func() interface{} {
				r := cnsts.RoleReader
				return &project.GetUsers{
					Host:         app.ExampleID(),
					Project:      app.ExampleID(),
					IDs:          IDs{app.ExampleID()},
					Role:         &r,
					HandlePrefix: ptr.String("my_frien"),
					After:        ptr.ID(app.ExampleID()),
					Limit:        100,
				}
			},
			GetExampleResponse: func() interface{} {
				return &project.GetUsersRes{
					Set: []*project.User{
						exampleUser,
					},
					More: true,
				}
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				return getUsers(tlbx, a.(*project.GetUsers))
			},
		},
		{
			Description:  "set project user roles",
			Path:         (&project.SetUserRoles{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.SetUserRoles{}
			},
			GetExampleArgs: func() interface{} {
				return &project.SetUserRoles{
					Project: app.ExampleID(),
					Users: []*project.SendUser{
						{
							ID:   app.ExampleID(),
							Role: cnsts.RoleAdmin,
						},
					},
				}
			},
			GetExampleResponse: func() interface{} {
				return nil
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*project.SetUserRoles)
				lenUsers := len(args.Users)
				if lenUsers == 0 {
					return nil
				}
				app.BadReqIf(lenUsers > 100, "can not set more than 100 user roles in a project at a time")
				srv := service.Get(tlbx)
				tx := srv.Data().BeginWrite()
				defer tx.Rollback()
				epsutil.IMustHaveAccess(tlbx, tx, args.Host, args.Project, cnsts.RoleAdmin)
				for _, u := range args.Users {
					app.ReturnIf(u.ID.Equal(args.Host), http.StatusForbidden, "can not set hosts role")
					res, err := tx.Exec(`UPDATE users SET role=? WHERE host=? AND project=? AND id=?`, u.Role, args.Host, args.Project, u.ID)
					PanicOn(err)
					count, err := res.RowsAffected()
					PanicOn(err)
					app.ReturnIf(count != 1, http.StatusNotFound, "user: %s not found", u.ID)
					epsutil.LogActivity(tlbx, tx, args.Host, args.Project, args.Project, u.ID, cnsts.TypeUser, cnsts.ActionUpdated, nil, u.Role, nil, nil)
				}
				tx.Commit()
				return nil
			},
		},
		{
			Description:  "remove project users",
			Path:         (&project.RemoveUsers{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.RemoveUsers{}
			},
			GetExampleArgs: func() interface{} {
				return &project.RemoveUsers{
					Host:    app.ExampleID(),
					Project: app.ExampleID(),
					Users: IDs{
						app.ExampleID(),
					},
				}
			},
			GetExampleResponse: func() interface{} {
				return nil
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*project.RemoveUsers)
				if len(args.Users) == 0 {
					return nil
				}
				me := me.AuthedGet(tlbx)
				srv := service.Get(tlbx)
				tx := srv.Data().BeginWrite()
				defer tx.Rollback()
				if !(len(args.Users) == 1 &&
					me.Equal(args.Users[0]) &&
					!me.Equal(args.Host)) {

					epsutil.IMustHaveAccess(tlbx, tx, args.Host, args.Project, cnsts.RoleAdmin)
				}
				queryArgs := make([]interface{}, 0, len(args.Users)+2)
				queryArgs = append(queryArgs, args.Host, args.Project)
				for _, u := range args.Users {
					app.BadReqIf(u.Equal(args.Host), "can not remove host from project")
					queryArgs = append(queryArgs, u)
				}
				_, err := tx.Exec(Strf(`UPDATE users SET isActive=0 WHERE host=? AND project=? %s`, sqlh.InCondition(true, `id`, len(args.Users))), queryArgs...)
				PanicOn(err)
				_, err = srv.User().Exec(Strf(`DELETE FROM fcmTokens WHERE 1=1 %s`, sqlh.InCondition(true, `user`, len(args.Users))), args.Users.ToIs()...)
				PanicOn(err)
				for _, u := range args.Users {
					epsutil.LogActivity(tlbx, tx, args.Host, args.Project, args.Project, u, cnsts.TypeUser, cnsts.ActionDeleted, nil, nil, nil, nil)
				}
				tx.Commit()
				return nil
			},
		},
		{
			Description:  "get project activities",
			Path:         (&project.GetActivities{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &project.GetActivities{
					ExcludeDeletedItems: false,
					Limit:               100,
				}
			},
			GetExampleArgs: func() interface{} {
				return &project.GetActivities{
					Host:                app.ExampleID(),
					Project:             app.ExampleID(),
					ExcludeDeletedItems: true,
					Task:                ptr.ID(app.ExampleID()),
					Item:                ptr.ID(app.ExampleID()),
					User:                ptr.ID(app.ExampleID()),
					OccuredAfter:        ptr.Time(app.ExampleTime()),
					OccuredBefore:       ptr.Time(app.ExampleTime().Add(24 * time.Hour)),
					Limit:               100,
				}
			},
			GetExampleResponse: func() interface{} {
				return &project.GetActivitiesRes{
					Set: []*project.Activity{
						{
							Task:        ptr.ID(app.ExampleID()),
							OccurredOn:  app.ExampleTime(),
							User:        app.ExampleID(),
							Item:        app.ExampleID(),
							ItemType:    cnsts.TypeTask,
							TaskDeleted: true,
							ItemDeleted: false,
							Action:      cnsts.ActionUpdated,
							ItemName:    ptr.String("my task"),
							ExtraInfo:   json.MustFromString(`{"isParallel":true}`),
						},
					},
				}
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*project.GetActivities)
				args.Limit = sqlh.Limit100(args.Limit)
				app.BadReqIf(args.OccuredAfter != nil && args.OccuredBefore != nil, "only one of occurredBefore or occurredAfter may be used")
				tx := service.Get(tlbx).Data().BeginRead()
				defer tx.Rollback()
				epsutil.IMustHaveAccess(tlbx, tx, args.Host, args.Project, cnsts.RoleReader)
				query := bytes.NewBufferString(`SELECT occurredOn, user, task, item, itemType, taskDeleted, itemDeleted, action, taskName, itemName, extraInfo FROM activities WHERE host=? AND project=?`)
				queryArgs := make([]interface{}, 0, 7)
				queryArgs = append(queryArgs, args.Host, args.Project)
				if args.ExcludeDeletedItems {
					query.WriteString(` AND itemDeleted=0`)
				}
				if args.Item != nil {
					query.WriteString(` AND item=?`)
					queryArgs = append(queryArgs, *args.Item)
				}
				if args.User != nil {
					query.WriteString(` AND user=?`)
					queryArgs = append(queryArgs, *args.User)
				}
				asc := false
				if args.OccuredAfter != nil {
					asc = true
					query.WriteString(` AND occurredOn>?`)
					queryArgs = append(queryArgs, *args.OccuredAfter)
				}
				if args.OccuredBefore != nil {
					query.WriteString(` AND occurredOn<?`)
					queryArgs = append(queryArgs, *args.OccuredBefore)
				}
				query.WriteString(sqlh.OrderLimit100(`occurredOn`, asc, args.Limit))
				res := &project.GetActivitiesRes{
					Set: make([]*project.Activity, 0, args.Limit),
				}
				PanicOn(tx.Query(func(rows *sqlx.Rows) {
					iLimit := int(args.Limit)
					for rows.Next() {
						if len(res.Set)+1 == iLimit {
							res.More = true
							break
						}
						pa := &project.Activity{}
						var extraInfo *string
						PanicOn(rows.Scan(&pa.OccurredOn, &pa.User, &pa.Task, &pa.Item, &pa.ItemType, &pa.TaskDeleted, &pa.ItemDeleted, &pa.Action, &pa.TaskName, &pa.ItemName, &extraInfo))
						if extraInfo != nil {
							pa.ExtraInfo = json.MustFromString(*extraInfo)
						}
						res.Set = append(res.Set, pa)
					}
				}, query.String(), queryArgs...))
				tx.Commit()
				return res
			},
		},
	}
)

Functions

func GetOne

func GetOne(tlbx app.Tlbx, host, id ID) *project.Project

func OnDelete

func OnDelete(tlbx app.Tlbx, me ID)

func OnSetSocials

func OnSetSocials(tlbx app.Tlbx, user *user.User)

func ValidateFCMTopic

func ValidateFCMTopic(tlbx app.Tlbx, topic IDs) (sql.Tx, error)

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL