Files
2025-09-12 12:38:11 +02:00

126 lines
3.9 KiB
Go

package models
import (
"time"
"gorm.io/gorm"
)
type Task struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
Title string `json:"title" gorm:"not null"`
Description string `json:"description"`
Status string `json:"status" gorm:"default:'todo'"` // todo, in_progress, review, done
Priority string `json:"priority" gorm:"default:'medium'"` // low, medium, high, urgent
DueDate *time.Time `json:"due_date"`
CompletedAt *time.Time `json:"completed_at"`
Position int `json:"position" gorm:"default:0"` // For ordering in kanban board
// Foreign Keys
ProjectID uint `json:"project_id" gorm:"not null"`
AssignedToID *uint `json:"assigned_to_id"`
CreatedByID uint `json:"created_by_id" gorm:"not null"`
// Relationships
Project Project `json:"project" gorm:"foreignKey:ProjectID"`
AssignedTo *User `json:"assigned_to" gorm:"foreignKey:AssignedToID"`
CreatedBy User `json:"created_by" gorm:"foreignKey:CreatedByID"`
Comments []Comment `json:"comments" gorm:"foreignKey:TaskID"`
Files []FileUpload `json:"files" gorm:"foreignKey:TaskID"`
Subtasks []Subtask `json:"subtasks" gorm:"foreignKey:ParentTaskID"`
Labels []Label `json:"labels" gorm:"many2many:task_labels"`
}
type Subtask struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
Title string `json:"title" gorm:"not null"`
Description string `json:"description"`
Status string `json:"status" gorm:"default:'todo'"` // todo, in_progress, done
Position int `json:"position" gorm:"default:0"`
CompletedAt *time.Time `json:"completed_at"`
// Foreign Keys
ParentTaskID uint `json:"parent_task_id" gorm:"not null"`
AssignedToID *uint `json:"assigned_to_id"`
// Relationships
ParentTask Task `json:"parent_task" gorm:"foreignKey:ParentTaskID"`
AssignedTo *User `json:"assigned_to" gorm:"foreignKey:AssignedToID"`
}
type Label struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
Name string `json:"name" gorm:"not null"`
Color string `json:"color" gorm:"default:'#6b7280'"` // Hex color
// Foreign Keys
ProjectID uint `json:"project_id" gorm:"not null"`
// Relationships
Project Project `json:"project" gorm:"foreignKey:ProjectID"`
Tasks []Task `json:"tasks" gorm:"many2many:task_labels"`
}
type Comment struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
Content string `json:"content" gorm:"not null"`
// Foreign Keys
TaskID uint `json:"task_id" gorm:"not null"`
UserID uint `json:"user_id" gorm:"not null"`
// Relationships
Task Task `json:"task" gorm:"foreignKey:TaskID"`
User User `json:"user" gorm:"foreignKey:UserID"`
}
// IsOverdue checks if the task is overdue
func (t *Task) IsOverdue() bool {
if t.DueDate == nil {
return false
}
return t.Status != "done" && t.DueDate.Before(time.Now())
}
// GetCompletionPercentage returns the completion percentage based on subtasks
func (t *Task) GetCompletionPercentage() int {
if len(t.Subtasks) == 0 {
if t.Status == "done" {
return 100
}
return 0
}
completed := 0
for _, subtask := range t.Subtasks {
if subtask.Status == "done" {
completed++
}
}
return (completed * 100) / len(t.Subtasks)
}
// MarkAsCompleted marks the task as completed
func (t *Task) MarkAsCompleted() {
t.Status = "done"
now := time.Now()
t.CompletedAt = &now
}