package types import ( "time" "github.com/google/uuid" "gorm.io/gorm" ) type UUID_ID struct { ID uuid.UUID `gorm:"type:uuid;primaryKey"` } func (u *UUID_ID) BeforeCreate(tx *gorm.DB) (err error) { if u.ID == uuid.Nil { u.ID, _ = uuid.NewV7() } return } // admin / regular. DO NOT SET DIRECTLY. Use RoleAdmin and RoleUser. type Role int const ( RoleUser Role = iota // 0 RoleAdmin // 1 ) type User struct { UUID_ID Handle string `gorm:"uniqueIndex;not null"` Name string Email string `gorm:"uniqueIndex;not null"` Bio string Role Role `gorm:"default:0"` // default is RoleUser (0) PasswordHash string `gorm:"not null"` HackatimeToken string Config UserConfig Sessions []Session SSHPubKeys []SSHPubKey Repos []Repo Gists []Gist } type UserConfig struct { UUID_ID UserID uuid.UUID `gorm:"index;not null"` User *User `gorm:"not null;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` GitDefaultBranch string `gorm:"default:master;not null"` } type SSHPubKey struct { UUID_ID UserID uuid.UUID `gorm:"not null;index;uniqueIndex:idx_user_ssh_name"` User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` Name string `gorm:"not null;uniqueIndex:idx_user_ssh_name"` PublicKey string `gorm:"not null"` Fingerprint string `gorm:"uniqueIndex;not null"` Algorithm string `gorm:"not null"` } type Session struct { UUID_ID UserID *uuid.UUID User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` CreatedAt ISOTime `gorm:"autoCreateTime"` } type Repo struct { UUID_ID CreatedAt ISOTime `gorm:"autoCreateTime"` UserID *uuid.UUID `gorm:"not null;uniqueIndex:idx_user_repo_name"` User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` Name string `gorm:"uniqueIndex:idx_user_repo_name"` // idx_user_repo_name prevents two user's repos from having the same name. HackatimeName string Description string BaseBranch string `gorm:"default:master"` IsPrivate bool `gorm:"not null"` Config RepoConfig `gorm:"foreignKey:RepoID"` Issues []Issue `gorm:"foreignKey:RepoID"` NextIssueID uint `gorm:"not null;default:1"` } type RepoConfig struct { UUID_ID RepoID uuid.UUID `gorm:"index;not null"` Repo *Repo `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` AllowAnonymousIssues bool `gorm:"default:true"` AllowNewIssues bool `gorm:"default:true"` } type Issue struct { UUID_ID IssueID uint CreatedAt ISOTime `gorm:"autoCreateTime"` RepoID *uuid.UUID Repo *Repo `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` UserID *uuid.UUID User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` Title string `gorm:"not null;"` Description string `gorm:"not null;"` Status string `gorm:"default:open"` // open / close Tags []IssueTag // bug / suggestiom / etc } type IssueTag struct { UUID_ID IssueID uuid.UUID // the actual ID. Issue *Issue // the actual ID. Name string } type IssueComment struct { UUID_ID IssueID *uuid.UUID Issue *Issue `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` // deleting an issue deletes its comments UserID *uuid.UUID User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` // deleting a user anonymizes their comments instead of deleting them Comment string `gorm:"not null;"` CreatedAt ISOTime `gorm:"autoCreateTime"` } type OAuthState struct { UUID_ID UserID uuid.UUID `gorm:"not null;"` User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` State string `gorm:"uniqueIndex;size:64;not null"` Verifier string `gorm:"size:128;not null"` ExpiresAt time.Time `gorm:"index;not null"` CreatedAt ISOTime `gorm:"autoCreateTime"` } type Invite struct { UUID_ID UserID *uuid.UUID // optional due to possible cli-issued admin invite. User *User Role uint `gorm:"default:0;"` // role to assign once it's exchanged. defaults to normie. Token string `gorm:"default:8;not null"` ExpiresAt time.Time `gorm:"index;not null"` CreatedAt ISOTime `gorm:"autoCreateTime"` } type Gist struct { UUID_ID UserID uuid.UUID `gorm:"not null"` User *User Title string Content string `gorm:"not null"` CreatedAt ISOTime `gorm:"autoCreateTime"` }