Files
geek-life/repository/postgres/task.go

148 lines
5.6 KiB
Go

package postgres
import (
"strconv"
"time"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
"github.com/ajaxray/geek-life/model"
)
// TaskRepository implements the task repository interface for PostgreSQL
type TaskRepository struct {
db *sqlx.DB
}
// NewTaskRepository creates a new task repository
func NewTaskRepository(db *sqlx.DB) *TaskRepository {
return &TaskRepository{db: db}
}
// GetAll retrieves all tasks for a user
func (r *TaskRepository) GetAll(ctx *model.UserContext) ([]model.Task, error) {
var tasks []model.Task
query := `SELECT id, tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at
FROM tasks WHERE tenant_id = $1 AND user_id = $2 ORDER BY created_at DESC`
err := r.db.Select(&tasks, query, ctx.Tenant.ID, ctx.User.ID)
return tasks, err
}
// GetAllByProject retrieves all tasks for a specific project
func (r *TaskRepository) GetAllByProject(ctx *model.UserContext, project model.Project) ([]model.Task, error) {
var tasks []model.Task
query := `SELECT id, tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at
FROM tasks WHERE tenant_id = $1 AND user_id = $2 AND project_id = $3 ORDER BY created_at DESC`
err := r.db.Select(&tasks, query, ctx.Tenant.ID, ctx.User.ID, project.ID)
return tasks, err
}
// GetAllByDate retrieves all tasks for a specific date
func (r *TaskRepository) GetAllByDate(ctx *model.UserContext, date time.Time) ([]model.Task, error) {
var tasks []model.Task
startOfDay := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
endOfDay := startOfDay.Add(24 * time.Hour)
query := `SELECT id, tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at
FROM tasks WHERE tenant_id = $1 AND user_id = $2 AND due_date >= $3 AND due_date < $4 ORDER BY due_date ASC`
err := r.db.Select(&tasks, query, ctx.Tenant.ID, ctx.User.ID, startOfDay, endOfDay)
return tasks, err
}
// GetAllByDateRange retrieves all tasks within a date range
func (r *TaskRepository) GetAllByDateRange(ctx *model.UserContext, from, to time.Time) ([]model.Task, error) {
var tasks []model.Task
query := `SELECT id, tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at
FROM tasks WHERE tenant_id = $1 AND user_id = $2 AND due_date >= $3 AND due_date <= $4 ORDER BY due_date ASC`
err := r.db.Select(&tasks, query, ctx.Tenant.ID, ctx.User.ID, from, to)
return tasks, err
}
// GetByID retrieves a task by ID (string format for compatibility)
func (r *TaskRepository) GetByID(ctx *model.UserContext, ID string) (model.Task, error) {
var task model.Task
id, err := strconv.ParseInt(ID, 10, 64)
if err != nil {
return task, err
}
query := `SELECT id, tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at
FROM tasks WHERE id = $1 AND tenant_id = $2 AND user_id = $3`
err = r.db.Get(&task, query, id, ctx.Tenant.ID, ctx.User.ID)
return task, err
}
// GetByUUID retrieves a task by UUID
func (r *TaskRepository) GetByUUID(ctx *model.UserContext, UUID string) (model.Task, error) {
var task model.Task
query := `SELECT id, tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at
FROM tasks WHERE uuid = $1 AND tenant_id = $2 AND user_id = $3`
err := r.db.Get(&task, query, UUID, ctx.Tenant.ID, ctx.User.ID)
return task, err
}
// Create creates a new task
func (r *TaskRepository) Create(ctx *model.UserContext, project model.Project, title, details, UUID string, dueDate *int64) (model.Task, error) {
if UUID == "" {
UUID = uuid.New().String()
}
task := model.Task{
TenantID: ctx.Tenant.ID,
UserID: ctx.User.ID,
ProjectID: project.ID,
UUID: UUID,
Title: title,
Details: details,
Completed: false,
DueDate: dueDate,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
query := `INSERT INTO tasks (tenant_id, user_id, project_id, uuid, title, details, completed, due_date, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id`
var dueDateValue interface{}
if dueDate != nil {
dueDateValue = time.Unix(*dueDate, 0)
}
err := r.db.QueryRow(query, task.TenantID, task.UserID, task.ProjectID, task.UUID, task.Title, task.Details, task.Completed, dueDateValue, task.CreatedAt, task.UpdatedAt).Scan(&task.ID)
if err != nil {
return model.Task{}, err
}
return task, nil
}
// Update updates an existing task
func (r *TaskRepository) Update(ctx *model.UserContext, t *model.Task) error {
t.UpdatedAt = time.Now()
var dueDateValue interface{}
if t.DueDate != nil {
dueDateValue = time.Unix(*t.DueDate, 0)
}
query := `UPDATE tasks SET title = $1, details = $2, completed = $3, due_date = $4, updated_at = $5
WHERE id = $6 AND tenant_id = $7 AND user_id = $8`
_, err := r.db.Exec(query, t.Title, t.Details, t.Completed, dueDateValue, t.UpdatedAt, t.ID, ctx.Tenant.ID, ctx.User.ID)
return err
}
// UpdateField updates a specific field of a task
func (r *TaskRepository) UpdateField(ctx *model.UserContext, t *model.Task, field string, value interface{}) error {
t.UpdatedAt = time.Now()
query := `UPDATE tasks SET ` + field + ` = $1, updated_at = $2
WHERE id = $3 AND tenant_id = $4 AND user_id = $5`
_, err := r.db.Exec(query, value, t.UpdatedAt, t.ID, ctx.Tenant.ID, ctx.User.ID)
return err
}
// Delete deletes a task
func (r *TaskRepository) Delete(ctx *model.UserContext, t *model.Task) error {
query := `DELETE FROM tasks WHERE id = $1 AND tenant_id = $2 AND user_id = $3`
_, err := r.db.Exec(query, t.ID, ctx.Tenant.ID, ctx.User.ID)
return err
}