initial commit. Cloned timetracker repository
This commit is contained in:
144
app/model/customer.go
Normal file
144
app/model/customer.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// User represents a user in the system
|
||||
type Customer struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Email string `gorm:"uniqueIndex;not null;size:255" json:"email"`
|
||||
Password string `gorm:"size:255" json:"-"` // Hashed password, not exposed in JSON
|
||||
FirstName string `gorm:"size:100" json:"first_name"`
|
||||
LastName string `gorm:"size:100" json:"last_name"`
|
||||
Role CustomerRole `gorm:"type:varchar(20);default:'user'" json:"role"`
|
||||
Provider AuthProvider `gorm:"type:varchar(20);default:'local'" json:"provider"`
|
||||
ProviderID string `gorm:"size:255" json:"provider_id,omitempty"` // ID from OAuth provider
|
||||
AvatarURL string `gorm:"size:500" json:"avatar_url,omitempty"`
|
||||
IsActive bool `gorm:"default:true" json:"is_active"`
|
||||
EmailVerified bool `gorm:"default:false" json:"email_verified"`
|
||||
EmailVerificationToken string `gorm:"size:255" json:"-"`
|
||||
EmailVerificationExpires *time.Time `json:"-"`
|
||||
PasswordResetToken string `gorm:"size:255" json:"-"`
|
||||
PasswordResetExpires *time.Time `json:"-"`
|
||||
LastPasswordResetRequest *time.Time `json:"-"`
|
||||
LastLoginAt *time.Time `json:"last_login_at,omitempty"`
|
||||
Lang string `gorm:"size:10;default:'en'" json:"lang"` // User's preferred language
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// CustomerRole represents the role of a user
|
||||
type CustomerRole string
|
||||
|
||||
const (
|
||||
RoleUser CustomerRole = "user"
|
||||
RoleAdmin CustomerRole = "admin"
|
||||
)
|
||||
|
||||
// AuthProvider represents the authentication provider
|
||||
type AuthProvider string
|
||||
|
||||
const (
|
||||
ProviderLocal AuthProvider = "local"
|
||||
ProviderGoogle AuthProvider = "google"
|
||||
)
|
||||
|
||||
// TableName specifies the table name for User model
|
||||
func (Customer) TableName() string {
|
||||
return "customers"
|
||||
}
|
||||
|
||||
// IsAdmin checks if the user has admin role
|
||||
func (u *Customer) IsAdmin() bool {
|
||||
return u.Role == RoleAdmin
|
||||
}
|
||||
|
||||
// CanManageUsers checks if the user can manage other users
|
||||
func (u *Customer) CanManageUsers() bool {
|
||||
return u.Role == RoleAdmin
|
||||
}
|
||||
|
||||
// FullName returns the user's full name
|
||||
func (u *Customer) FullName() string {
|
||||
if u.FirstName == "" && u.LastName == "" {
|
||||
return u.Email
|
||||
}
|
||||
return u.FirstName + " " + u.LastName
|
||||
}
|
||||
|
||||
// UserSession represents a user session for JWT claims
|
||||
type UserSession struct {
|
||||
UserID uint `json:"user_id"`
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
Role CustomerRole `json:"role"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Lang string `json:"lang"`
|
||||
}
|
||||
|
||||
// ToSession converts User to UserSession
|
||||
func (u *Customer) ToSession() *UserSession {
|
||||
return &UserSession{
|
||||
UserID: u.ID,
|
||||
Email: u.Email,
|
||||
Role: u.Role,
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
Lang: u.Lang,
|
||||
}
|
||||
}
|
||||
|
||||
// LoginRequest represents the login form data
|
||||
type LoginRequest struct {
|
||||
Email string `json:"email" form:"email"`
|
||||
Password string `json:"password" form:"password"`
|
||||
}
|
||||
|
||||
// RegisterRequest represents the initial registration form data
|
||||
type RegisterRequest struct {
|
||||
ErrorMsg string `form:"error_msg" json:"error_msg"`
|
||||
Email string `json:"email" form:"email"`
|
||||
Password string `json:"password" form:"password"`
|
||||
ConfirmPassword string `json:"confirm_password" form:"confirm_password"`
|
||||
FirstName string `json:"first_name" form:"first_name"`
|
||||
LastName string `json:"last_name" form:"last_name"`
|
||||
Lang string `form:"lang" json:"lang"`
|
||||
}
|
||||
|
||||
// CompleteRegistrationRequest represents the completion of registration with email verification
|
||||
type CompleteRegistrationRequest struct {
|
||||
Token string `json:"token" form:"token"`
|
||||
}
|
||||
|
||||
// ResetPasswordRequest represents the reset password form data
|
||||
type ResetPasswordRequest struct {
|
||||
Token string `json:"token" form:"token"`
|
||||
Password string `json:"password" form:"password"`
|
||||
}
|
||||
|
||||
// AuthResponse represents the authentication response
|
||||
type AuthResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
User *UserSession `json:"user"`
|
||||
}
|
||||
|
||||
// RefreshToken represents an opaque refresh token stored in the database
|
||||
type RefreshToken struct {
|
||||
ID uint `gorm:"primaryKey" json:"-"`
|
||||
CustomerID uint `gorm:"not null;index" json:"-"`
|
||||
TokenHash string `gorm:"size:64;uniqueIndex;not null" json:"-"` // SHA-256 hex of the raw token
|
||||
ExpiresAt time.Time `gorm:"not null" json:"-"`
|
||||
CreatedAt time.Time `json:"-"`
|
||||
}
|
||||
|
||||
// TableName specifies the table name for RefreshToken model
|
||||
func (RefreshToken) TableName() string {
|
||||
return "refresh_tokens"
|
||||
}
|
||||
22
app/model/data.go
Normal file
22
app/model/data.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package model
|
||||
|
||||
// LoginRequest represents the login form data
|
||||
type DataRequest struct {
|
||||
RepoID uint `json:"repoid" form:"repoid"`
|
||||
Step uint `json:"step" form:"step"`
|
||||
}
|
||||
|
||||
type PageMeta struct {
|
||||
Title string
|
||||
Description string
|
||||
}
|
||||
|
||||
type QuarterData struct {
|
||||
Time float64 `json:"time"`
|
||||
Quarter string `json:"quarter"`
|
||||
}
|
||||
|
||||
type DayData struct {
|
||||
Date string `json:"date"`
|
||||
Time float64 `json:"time"`
|
||||
}
|
||||
67
app/model/i18n.go
Normal file
67
app/model/i18n.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// contextKey is a custom type for context keys
|
||||
type contextKey string
|
||||
|
||||
// ContextLanguageID is the key for storing language ID in context
|
||||
const ContextLanguageID contextKey = "languageID"
|
||||
|
||||
type Translation struct {
|
||||
LangID uint `gorm:"primaryKey;column:lang_id"`
|
||||
ScopeID uint `gorm:"primaryKey;column:scope_id"`
|
||||
ComponentID uint `gorm:"primaryKey;column:component_id"`
|
||||
Key string `gorm:"primaryKey;size:255;column:key"`
|
||||
Data *string `gorm:"type:text;column:data"`
|
||||
|
||||
Language Language `gorm:"foreignKey:LangID;references:ID;constraint:OnUpdate:RESTRICT,OnDelete:RESTRICT"`
|
||||
Scope Scope `gorm:"foreignKey:ScopeID;references:ID;constraint:OnUpdate:RESTRICT,OnDelete:RESTRICT"`
|
||||
Component Component `gorm:"foreignKey:ComponentID;references:ID;constraint:OnUpdate:RESTRICT,OnDelete:RESTRICT"`
|
||||
}
|
||||
|
||||
func (Translation) TableName() string {
|
||||
return "translations"
|
||||
}
|
||||
|
||||
type Language struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement;column:id"`
|
||||
CreatedAt time.Time `gorm:"not null;column:created_at"`
|
||||
UpdatedAt *time.Time `gorm:"column:updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index:idx_language_deleted_at;column:deleted_at"`
|
||||
Name string `gorm:"size:128;not null;column:name"`
|
||||
ISOCode string `gorm:"size:2;not null;column:iso_code"`
|
||||
LangCode string `gorm:"size:5;not null;column:lang_code"`
|
||||
DateFormat string `gorm:"size:32;not null;column:date_format"`
|
||||
DateFormatShort string `gorm:"size:32;not null;column:date_format_short"`
|
||||
RTL bool `gorm:"not null;default:0;column:rtl"`
|
||||
IsDefault bool `gorm:"not null;default:0;column:is_default;comment:there should be only one default language"`
|
||||
Active bool `gorm:"not null;default:1;column:active"`
|
||||
Flag string `gorm:"size:16;not null;column:flag"`
|
||||
}
|
||||
|
||||
func (Language) TableName() string {
|
||||
return "language"
|
||||
}
|
||||
|
||||
type Component struct {
|
||||
ID uint64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||
Name string `gorm:"size:255;not null;uniqueIndex:uk_components_name;column:name"`
|
||||
}
|
||||
|
||||
func (Component) TableName() string {
|
||||
return "components"
|
||||
}
|
||||
|
||||
type Scope struct {
|
||||
ID uint64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||
Name string `gorm:"size:255;not null;uniqueIndex:uk_scopes_name;column:name"`
|
||||
}
|
||||
|
||||
func (Scope) TableName() string {
|
||||
return "scopes"
|
||||
}
|
||||
61
app/model/repository.go
Normal file
61
app/model/repository.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package model
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type Repository struct {
|
||||
ID int64 `db:"id"`
|
||||
OwnerID *int64 `db:"owner_id"`
|
||||
OwnerName *string `db:"owner_name"`
|
||||
LowerName string `db:"lower_name"`
|
||||
Name string `db:"name"`
|
||||
Description *string `db:"description"`
|
||||
Website *string `db:"website"`
|
||||
OriginalServiceType *int `db:"original_service_type"`
|
||||
OriginalURL *string `db:"original_url"`
|
||||
DefaultBranch *string `db:"default_branch"`
|
||||
DefaultWikiBranch *string `db:"default_wiki_branch"`
|
||||
|
||||
NumWatches *int `db:"num_watches"`
|
||||
NumStars *int `db:"num_stars"`
|
||||
NumForks *int `db:"num_forks"`
|
||||
NumIssues *int `db:"num_issues"`
|
||||
NumClosedIssues *int `db:"num_closed_issues"`
|
||||
NumPulls *int `db:"num_pulls"`
|
||||
NumClosedPulls *int `db:"num_closed_pulls"`
|
||||
|
||||
NumMilestones int `db:"num_milestones"`
|
||||
NumClosedMilestones int `db:"num_closed_milestones"`
|
||||
NumProjects int `db:"num_projects"`
|
||||
NumClosedProjects int `db:"num_closed_projects"`
|
||||
NumActionRuns int `db:"num_action_runs"`
|
||||
NumClosedActionRuns int `db:"num_closed_action_runs"`
|
||||
|
||||
IsPrivate *bool `db:"is_private"`
|
||||
IsEmpty *bool `db:"is_empty"`
|
||||
IsArchived *bool `db:"is_archived"`
|
||||
IsMirror *bool `db:"is_mirror"`
|
||||
|
||||
Status int `db:"status"`
|
||||
IsFork bool `db:"is_fork"`
|
||||
ForkID *int64 `db:"fork_id"`
|
||||
|
||||
IsTemplate bool `db:"is_template"`
|
||||
TemplateID *int64 `db:"template_id"`
|
||||
|
||||
Size int64 `db:"size"`
|
||||
GitSize int64 `db:"git_size"`
|
||||
LFSSize int64 `db:"lfs_size"`
|
||||
|
||||
IsFsckEnabled bool `db:"is_fsck_enabled"`
|
||||
CloseIssuesViaCommitAnyBranch bool `db:"close_issues_via_commit_in_any_branch"`
|
||||
|
||||
Topics json.RawMessage `db:"topics"`
|
||||
|
||||
ObjectFormatName string `db:"object_format_name"`
|
||||
TrustModel *int `db:"trust_model"`
|
||||
Avatar *string `db:"avatar"`
|
||||
|
||||
CreatedUnix *int64 `db:"created_unix"`
|
||||
UpdatedUnix *int64 `db:"updated_unix"`
|
||||
ArchivedUnix int64 `db:"archived_unix"`
|
||||
}
|
||||
Reference in New Issue
Block a user