All checks were successful
Build and Push App Image / build-and-push (push) Successful in 1m55s
186 lines
5.7 KiB
Go
186 lines
5.7 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"gitea.hostxtra.co.uk/mrhid6/notely/backend/internal/domain/entities"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
)
|
|
|
|
// TaskRepository implements task data access.
|
|
type TaskRepository struct {
|
|
collection *mongo.Collection
|
|
}
|
|
|
|
// NewTaskRepository creates a new task repository.
|
|
func NewTaskRepository(db *mongo.Database) *TaskRepository {
|
|
return &TaskRepository{collection: db.Collection("tasks")}
|
|
}
|
|
|
|
func (r *TaskRepository) CreateTask(ctx context.Context, task *entities.Task) error {
|
|
task.ID = bson.NewObjectID()
|
|
task.CreatedAt = time.Now()
|
|
task.UpdatedAt = time.Now()
|
|
if task.NoteLinks == nil {
|
|
task.NoteLinks = []bson.ObjectID{}
|
|
}
|
|
_, err := r.collection.InsertOne(ctx, task)
|
|
return err
|
|
}
|
|
|
|
func (r *TaskRepository) GetTaskByID(ctx context.Context, id bson.ObjectID) (*entities.Task, error) {
|
|
var task entities.Task
|
|
err := r.collection.FindOne(ctx, bson.M{"_id": id}).Decode(&task)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return nil, errors.New("task not found")
|
|
}
|
|
return nil, err
|
|
}
|
|
return &task, nil
|
|
}
|
|
|
|
func (r *TaskRepository) ListTasks(ctx context.Context, spaceID bson.ObjectID, filters map[string]any) ([]*entities.Task, error) {
|
|
query := bson.M{"space_id": spaceID}
|
|
for k, v := range filters {
|
|
query[k] = v
|
|
}
|
|
|
|
opts := options.Find().SetSort(bson.D{{Key: "updated_at", Value: -1}})
|
|
cursor, err := r.collection.Find(ctx, query, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var tasks []*entities.Task
|
|
if err := cursor.All(ctx, &tasks); err != nil {
|
|
return nil, err
|
|
}
|
|
return tasks, nil
|
|
}
|
|
|
|
func (r *TaskRepository) SearchTasks(ctx context.Context, spaceID bson.ObjectID, query string) ([]*entities.Task, error) {
|
|
cursor, err := r.collection.Find(ctx, bson.M{
|
|
"space_id": spaceID,
|
|
"$or": []bson.M{
|
|
{"title": bson.M{"$regex": query, "$options": "i"}},
|
|
{"description": bson.M{"$regex": query, "$options": "i"}},
|
|
},
|
|
}, options.Find().SetSort(bson.D{{Key: "updated_at", Value: -1}}).SetLimit(30))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var tasks []*entities.Task
|
|
if err := cursor.All(ctx, &tasks); err != nil {
|
|
return nil, err
|
|
}
|
|
return tasks, nil
|
|
}
|
|
|
|
func (r *TaskRepository) UpdateTask(ctx context.Context, task *entities.Task) error {
|
|
task.UpdatedAt = time.Now()
|
|
_, err := r.collection.ReplaceOne(ctx, bson.M{"_id": task.ID}, task)
|
|
return err
|
|
}
|
|
|
|
func (r *TaskRepository) DeleteTask(ctx context.Context, id bson.ObjectID) error {
|
|
_, err := r.collection.DeleteOne(ctx, bson.M{"_id": id})
|
|
return err
|
|
}
|
|
|
|
func (r *TaskRepository) DeleteTasksBySpaceID(ctx context.Context, spaceID bson.ObjectID) error {
|
|
_, err := r.collection.DeleteMany(ctx, bson.M{"space_id": spaceID})
|
|
return err
|
|
}
|
|
|
|
func (r *TaskRepository) CountChildren(ctx context.Context, parentTaskID bson.ObjectID) (int64, error) {
|
|
return r.collection.CountDocuments(ctx, bson.M{"parent_task_id": parentTaskID})
|
|
}
|
|
|
|
func (r *TaskRepository) EnsureIndexes(ctx context.Context) error {
|
|
_, err := r.collection.Indexes().CreateMany(ctx, []mongo.IndexModel{
|
|
{Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "updated_at", Value: -1}}},
|
|
{Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "status_id", Value: 1}}},
|
|
{Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "category_id", Value: 1}}},
|
|
{Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "parent_task_id", Value: 1}}},
|
|
{Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "note_links", Value: 1}}},
|
|
})
|
|
return err
|
|
}
|
|
|
|
// TaskStatusRepository implements task status data access.
|
|
type TaskStatusRepository struct {
|
|
collection *mongo.Collection
|
|
}
|
|
|
|
// NewTaskStatusRepository creates a new task status repository.
|
|
func NewTaskStatusRepository(db *mongo.Database) *TaskStatusRepository {
|
|
return &TaskStatusRepository{collection: db.Collection("task_statuses")}
|
|
}
|
|
|
|
func (r *TaskStatusRepository) CreateStatus(ctx context.Context, status *entities.TaskStatus) error {
|
|
status.ID = bson.NewObjectID()
|
|
status.CreatedAt = time.Now()
|
|
status.UpdatedAt = time.Now()
|
|
_, err := r.collection.InsertOne(ctx, status)
|
|
return err
|
|
}
|
|
|
|
func (r *TaskStatusRepository) GetStatusByID(ctx context.Context, id bson.ObjectID) (*entities.TaskStatus, error) {
|
|
var status entities.TaskStatus
|
|
err := r.collection.FindOne(ctx, bson.M{"_id": id}).Decode(&status)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return nil, errors.New("task status not found")
|
|
}
|
|
return nil, err
|
|
}
|
|
return &status, nil
|
|
}
|
|
|
|
func (r *TaskStatusRepository) ListStatuses(ctx context.Context, spaceID bson.ObjectID) ([]*entities.TaskStatus, error) {
|
|
cursor, err := r.collection.Find(ctx, bson.M{"space_id": spaceID}, options.Find().SetSort(bson.D{{Key: "order", Value: 1}}))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var statuses []*entities.TaskStatus
|
|
if err := cursor.All(ctx, &statuses); err != nil {
|
|
return nil, err
|
|
}
|
|
return statuses, nil
|
|
}
|
|
|
|
func (r *TaskStatusRepository) UpdateStatus(ctx context.Context, status *entities.TaskStatus) error {
|
|
status.UpdatedAt = time.Now()
|
|
_, err := r.collection.ReplaceOne(ctx, bson.M{"_id": status.ID}, status)
|
|
return err
|
|
}
|
|
|
|
func (r *TaskStatusRepository) DeleteStatus(ctx context.Context, id bson.ObjectID) error {
|
|
_, err := r.collection.DeleteOne(ctx, bson.M{"_id": id})
|
|
return err
|
|
}
|
|
|
|
func (r *TaskStatusRepository) EnsureIndexes(ctx context.Context) error {
|
|
_, err := r.collection.Indexes().CreateMany(ctx, []mongo.IndexModel{
|
|
{
|
|
Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "name", Value: 1}},
|
|
Options: options.Index().SetUnique(true),
|
|
},
|
|
{
|
|
Keys: bson.D{{Key: "space_id", Value: 1}, {Key: "order", Value: 1}},
|
|
Options: options.Index().SetUnique(true),
|
|
},
|
|
})
|
|
return err
|
|
}
|