first commit

This commit is contained in:
domrichardson
2026-03-24 16:03:04 +00:00
commit df40cc57e1
80 changed files with 16766 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
package database
import (
"context"
"errors"
"strings"
"time"
"github.com/noteapp/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"
)
// PermissionGroupRepository implements permission group data access.
type PermissionGroupRepository struct {
collection *mongo.Collection
}
// NewPermissionGroupRepository creates a new group repository.
func NewPermissionGroupRepository(db *mongo.Database) *PermissionGroupRepository {
return &PermissionGroupRepository{collection: db.Collection("permission_groups")}
}
// CreateGroup creates a new permission group.
func (r *PermissionGroupRepository) CreateGroup(ctx context.Context, group *entities.PermissionGroup) error {
group.ID = bson.NewObjectID()
group.Name = strings.TrimSpace(group.Name)
group.NameKey = strings.ToLower(group.Name)
group.CreatedAt = time.Now()
group.UpdatedAt = time.Now()
_, err := r.collection.InsertOne(ctx, group)
return err
}
// GetGroupByID retrieves a group by ID.
func (r *PermissionGroupRepository) GetGroupByID(ctx context.Context, id bson.ObjectID) (*entities.PermissionGroup, error) {
var group entities.PermissionGroup
err := r.collection.FindOne(ctx, bson.M{"_id": id}).Decode(&group)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, errors.New("group not found")
}
return nil, err
}
return &group, nil
}
// GetGroupByName retrieves a group by case-insensitive name.
func (r *PermissionGroupRepository) GetGroupByName(ctx context.Context, name string) (*entities.PermissionGroup, error) {
normalized := strings.ToLower(strings.TrimSpace(name))
var group entities.PermissionGroup
err := r.collection.FindOne(ctx, bson.M{"name_key": normalized}).Decode(&group)
if err != nil {
if err == mongo.ErrNoDocuments {
return nil, errors.New("group not found")
}
return nil, err
}
return &group, nil
}
// GetGroupsByIDs retrieves groups by IDs.
func (r *PermissionGroupRepository) GetGroupsByIDs(ctx context.Context, ids []bson.ObjectID) ([]*entities.PermissionGroup, error) {
if len(ids) == 0 {
return []*entities.PermissionGroup{}, nil
}
cursor, err := r.collection.Find(ctx, bson.M{"_id": bson.M{"$in": ids}})
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
var groups []*entities.PermissionGroup
if err := cursor.All(ctx, &groups); err != nil {
return nil, err
}
return groups, nil
}
// ListGroups retrieves all groups sorted by name.
func (r *PermissionGroupRepository) ListGroups(ctx context.Context) ([]*entities.PermissionGroup, error) {
opts := options.Find().SetSort(bson.D{{Key: "name", Value: 1}})
cursor, err := r.collection.Find(ctx, bson.M{}, opts)
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
var groups []*entities.PermissionGroup
if err := cursor.All(ctx, &groups); err != nil {
return nil, err
}
return groups, nil
}
// UpdateGroup updates an existing group.
func (r *PermissionGroupRepository) UpdateGroup(ctx context.Context, group *entities.PermissionGroup) error {
group.UpdatedAt = time.Now()
_, err := r.collection.UpdateOne(ctx, bson.M{"_id": group.ID}, bson.M{
"$set": bson.M{
"name": strings.TrimSpace(group.Name),
"name_key": strings.ToLower(strings.TrimSpace(group.Name)),
"description": group.Description,
"permissions": group.Permissions,
"is_system": group.IsSystem,
"updated_at": group.UpdatedAt,
},
})
return err
}
// DeleteGroup deletes a group.
func (r *PermissionGroupRepository) DeleteGroup(ctx context.Context, id bson.ObjectID) error {
_, err := r.collection.DeleteOne(ctx, bson.M{"_id": id})
return err
}
// EnsureIndexes creates indexes for the permission groups collection.
func (r *PermissionGroupRepository) EnsureIndexes(ctx context.Context) error {
_, err := r.collection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.D{{Key: "name_key", Value: 1}},
Options: options.Index().SetUnique(true),
},
})
return err
}