> be fist commit

This commit is contained in:
2020-04-13 23:38:41 +02:00
commit 4cce632708
69 changed files with 7852 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
package models
// Activity is an activity within a project that can be measured and estimated, for example "writing" or "developing".
// The points are for the "gamified" aspect of this.
type Activity struct {
ID string `db:"activity_id"`
ProjectID string `db:"project_id"`
Countable bool `db:"countable"`
UnitName string `db:"unit_name"`
UnitValue float64 `db:"unit_value"`
BaseValue float64 `db:"base_value"`
}
+21
View File
@@ -0,0 +1,21 @@
package models
import "time"
// An Goal denotes a goal for a project or an activity within a project.
// It can ask for one or more of the time, unit or score. If there is no
// activity ID provided, all activities within the project should contribute.
// If there are no activity, a non-zero unit amount is not allowed.
type Goal struct {
ActivityGoalID string `db:"goal_id"`
ProjectID string `db:"project_id"`
ActivityID string `db:"activity_id"`
UserID string `db:"user_id"`
TimeAmount time.Duration `db:"time_amount"`
AllRequired bool `db:"all_required"`
UnitAmount int `db:"unit_amount"`
ScoreAmount int `db:"score_amount"`
TaskAmount int `db:"task_amount"`
StartTime time.Time `db:"start_time"`
EndTime time.Time `db:"end_time"`
}
+39
View File
@@ -0,0 +1,39 @@
package models
import "time"
type Issue struct {
ID string `db:"issue_id"`
ProjectID string `db:"project_id"`
OwnerID string `db:"owner_id"`
AssigneeID string `db:"assignee_id"`
StatusStage int `db:"status_stage"`
StatusName string `db:"status_name"`
CreatedTime time.Time `db:"created_time"`
UpdatedTime time.Time `db:"updated_time"`
DueTime time.Time `db:"due_time"`
Name string `db:"name"`
Title string `db:"title"`
Description string `db:"description"`
}
type IssueFilter struct {
IssueIDs []string
ProjectIDs []string
OwnerIDs []string
AssigneeIDs []string
Search *string
MinStage *int
MaxStage *int
Limit *int
}
const (
IssueStageInactive = 0
IssueStagePending = 1
IssueStageActive = 2
IssueStageReview = 3
IssueStageCompleted = 4
IssueStageFailed = 5
IssueStagePostponed = 6
)
+9
View File
@@ -0,0 +1,9 @@
package models
// An IssueTask is a task within an issue.
type IssueItem struct {
ID string `db:"issue_item_id"`
IssueID string `db:"issue_id"`
ItemID string `db:"item_id"`
Quantity int `db:"quantity"`
}
+20
View File
@@ -0,0 +1,20 @@
package models
import "time"
// An IssueTask is a task within an issue.
type IssueTask struct {
TaskID string `db:"task_id"`
IssueID string `db:"issue_id"`
ActivityID string `db:"activity_id"`
CreatedTime time.Time `db:"created_time"`
UpdatedTime time.Time `db:"updated_time"`
DueTime time.Time `db:"due_time"`
StatusStage int `db:"status_stage"`
StatusName string `db:"status_name"`
Name string `db:"name"`
Description string `db:"description"`
EstimatedTime time.Duration `db:"estimated_time"`
EstimatedUnits int `db:"estimated_units"`
PointsMultiplier float64 `db:"points_multiplier"`
}
+21
View File
@@ -0,0 +1,21 @@
package models
type Item struct {
ID string `db:"item_id"`
Name string `db:"name"`
Description string `db:"description"`
Tags []string `db:"tags"`
ImageURL *string `db:"image_url"`
}
type ItemFilter struct {
ItemIDs []string
Tags []string
}
/*
SELECT i.item_id, i.name FROM item i
LEFT JOIN tag AS t ON t.item_id = i.item_id
WHERE t.tag_name IN ("Groceries")
GROUP by i.item_id;
*/
+6
View File
@@ -0,0 +1,6 @@
package models
type Log struct {
ID string `db:"log_id"`
IssueID string `db:"issue_id"`
}
+40
View File
@@ -0,0 +1,40 @@
package models
// A Project is a vague category for issues. It's use depend on the user's judgement, as it could represent
// an entire hobby/job or a single project within one.
type Project struct {
ID string `db:"project_id"`
Name string `db:"name"`
Description string `db:"description"`
DailyPoints int `db:"daily_points"`
}
type ProjectFilter struct {
ProjectIDs []string
Search *string
Permission *ProjectFilterPermission
}
type ProjectFilterPermission struct {
UserID string
MinLevel int
MaxLevel int
}
func (project *Project) ValidKey() bool {
if len(project.ID) < 1 || len(project.ID) > 16 {
return false
}
for _, r := range project.ID {
if r < 'A' && r > 'Z' {
return false
}
}
return true
}
func (pfp *ProjectFilterPermission) Valid() bool {
return pfp.UserID != "" && pfp.MinLevel > 0
}
+36
View File
@@ -0,0 +1,36 @@
package models
// ProjectPermission is a structure that associates a user with a project.
type ProjectPermission struct {
ProjectID string `db:"project_id"`
UserID string `db:"user_id"`
Level int `db:"access_level"`
}
const (
ProjectPermissionLevelNoAccess int = 0
ProjectPermissionLevelObserver int = 1
ProjectPermissionLevelMember int = 2
ProjectPermissionLevelAdmin int = 3
ProjectPermissionLevelOwner int = 4
)
func (permission *ProjectPermission) CanViewAnyIssue() bool {
return permission.Level >= ProjectPermissionLevelObserver
}
func (permission *ProjectPermission) CanViewOwnIssue() bool {
return permission.Level >= ProjectPermissionLevelObserver
}
func (permission *ProjectPermission) CanManageOwnIssue() bool {
return permission.Level >= ProjectPermissionLevelMember
}
func (permission *ProjectPermission) CanManageAnyIssue() bool {
return permission.Level >= ProjectPermissionLevelAdmin
}
func (permission *ProjectPermission) CanManagePermissions() bool {
return permission.Level >= ProjectPermissionLevelOwner
}
+9
View File
@@ -0,0 +1,9 @@
package models
// ProjectStatus is an entry denoting a status a project's issues can have.
type ProjectStatus struct {
ProjectID string `db:"project_id"`
Stage int `db:"status_stage"`
Name string `db:"status_name"`
Description string `db:"description"`
}
+9
View File
@@ -0,0 +1,9 @@
package models
import "time"
type Session struct {
ID string `db:"session_id"`
UserID string `db:"user_id"`
ExpiryTime time.Time `db:"expiry_time"`
}
+39
View File
@@ -0,0 +1,39 @@
package models
import (
"errors"
"golang.org/x/crypto/bcrypt"
)
type User struct {
ID string `db:"user_id"`
Name string `db:"name"`
Active bool `db:"active"`
Admin bool `db:"admin"`
Hash []byte `db:"hash"`
}
func (user *User) CheckPassword(password string) bool {
return bcrypt.CompareHashAndPassword(user.Hash, []byte(password)) == nil
}
func (user *User) SetPassword(password string) error {
if len(password) < 6 {
return errors.New("password too short (min: 6)")
}
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return err
}
user.Hash = hash
return nil
}
type UserFilter struct {
UserIDs []string
Active *bool
Admin *bool
Limit *int
}