first commit
This commit is contained in:
249
backend/internal/infrastructure/database/space_repository.go
Normal file
249
backend/internal/infrastructure/database/space_repository.go
Normal file
@@ -0,0 +1,249 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||
|
||||
"github.com/noteapp/backend/internal/domain/entities"
|
||||
)
|
||||
|
||||
// SpaceRepository implements the space repository interface
|
||||
type SpaceRepository struct {
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
// NewSpaceRepository creates a new space repository
|
||||
func NewSpaceRepository(db *mongo.Database) *SpaceRepository {
|
||||
return &SpaceRepository{
|
||||
collection: db.Collection("spaces"),
|
||||
}
|
||||
}
|
||||
|
||||
// CreateSpace creates a new space
|
||||
func (r *SpaceRepository) CreateSpace(ctx context.Context, space *entities.Space) error {
|
||||
space.ID = bson.NewObjectID()
|
||||
space.CreatedAt = time.Now()
|
||||
space.UpdatedAt = time.Now()
|
||||
|
||||
_, err := r.collection.InsertOne(ctx, space)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSpaceByID retrieves a space by ID
|
||||
func (r *SpaceRepository) GetSpaceByID(ctx context.Context, id bson.ObjectID) (*entities.Space, error) {
|
||||
var space entities.Space
|
||||
err := r.collection.FindOne(ctx, bson.M{"_id": id}).Decode(&space)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, errors.New("space not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &space, nil
|
||||
}
|
||||
|
||||
// GetSpacesByUserID retrieves all spaces for a user (via memberships)
|
||||
func (r *SpaceRepository) GetSpacesByUserID(ctx context.Context, userID bson.ObjectID) ([]*entities.Space, error) {
|
||||
var spaces []*entities.Space
|
||||
|
||||
// Query spaces where user is a member
|
||||
opts := options.Find().SetSort(bson.M{"created_at": -1})
|
||||
cursor, err := r.collection.Find(ctx, bson.M{}, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
// This would typically be joined with membership collection
|
||||
// For now, returning all spaces - in production, filter by membership
|
||||
if err = cursor.All(ctx, &spaces); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return spaces, nil
|
||||
}
|
||||
|
||||
// UpdateSpace updates a space
|
||||
func (r *SpaceRepository) UpdateSpace(ctx context.Context, space *entities.Space) error {
|
||||
space.UpdatedAt = time.Now()
|
||||
_, err := r.collection.ReplaceOne(ctx, bson.M{"_id": space.ID}, space)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteSpace deletes a space
|
||||
func (r *SpaceRepository) DeleteSpace(ctx context.Context, id bson.ObjectID) error {
|
||||
_, err := r.collection.DeleteOne(ctx, bson.M{"_id": id})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetAllSpaces retrieves all spaces sorted by creation date descending
|
||||
func (r *SpaceRepository) GetAllSpaces(ctx context.Context) ([]*entities.Space, error) {
|
||||
opts := options.Find().SetSort(bson.D{bson.E{Key: "created_at", Value: -1}})
|
||||
cursor, err := r.collection.Find(ctx, bson.M{}, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
var spaces []*entities.Space
|
||||
if err := cursor.All(ctx, &spaces); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return spaces, nil
|
||||
}
|
||||
|
||||
// GetPublicSpaces retrieves all spaces marked as public
|
||||
func (r *SpaceRepository) GetPublicSpaces(ctx context.Context) ([]*entities.Space, error) {
|
||||
opts := options.Find().SetSort(bson.D{bson.E{Key: "created_at", Value: -1}})
|
||||
cursor, err := r.collection.Find(ctx, bson.M{"is_public": true}, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
var spaces []*entities.Space
|
||||
if err := cursor.All(ctx, &spaces); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return spaces, nil
|
||||
}
|
||||
|
||||
// EnsureIndexes creates necessary indexes
|
||||
func (r *SpaceRepository) EnsureIndexes(ctx context.Context) error {
|
||||
indexModel := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{bson.E{Key: "owner_id", Value: 1}},
|
||||
},
|
||||
{
|
||||
Keys: bson.D{bson.E{Key: "created_at", Value: -1}},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := r.collection.Indexes().CreateMany(ctx, indexModel)
|
||||
return err
|
||||
}
|
||||
|
||||
// ========== MEMBERSHIP REPOSITORY ==========
|
||||
|
||||
// MembershipRepository implements the membership repository interface
|
||||
type MembershipRepository struct {
|
||||
collection *mongo.Collection
|
||||
}
|
||||
|
||||
// NewMembershipRepository creates a new membership repository
|
||||
func NewMembershipRepository(db *mongo.Database) *MembershipRepository {
|
||||
return &MembershipRepository{
|
||||
collection: db.Collection("memberships"),
|
||||
}
|
||||
}
|
||||
|
||||
// CreateMembership creates a new membership
|
||||
func (r *MembershipRepository) CreateMembership(ctx context.Context, membership *entities.Membership) error {
|
||||
membership.ID = bson.NewObjectID()
|
||||
membership.JoinedAt = time.Now()
|
||||
|
||||
_, err := r.collection.InsertOne(ctx, membership)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetMembershipByID retrieves a membership by ID
|
||||
func (r *MembershipRepository) GetMembershipByID(ctx context.Context, id bson.ObjectID) (*entities.Membership, error) {
|
||||
var membership entities.Membership
|
||||
err := r.collection.FindOne(ctx, bson.M{"_id": id}).Decode(&membership)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, errors.New("membership not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &membership, nil
|
||||
}
|
||||
|
||||
// GetUserMembership retrieves a membership for a user in a space
|
||||
func (r *MembershipRepository) GetUserMembership(ctx context.Context, userID, spaceID bson.ObjectID) (*entities.Membership, error) {
|
||||
var membership entities.Membership
|
||||
err := r.collection.FindOne(ctx, bson.M{
|
||||
"user_id": userID,
|
||||
"space_id": spaceID,
|
||||
}).Decode(&membership)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, errors.New("membership not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &membership, nil
|
||||
}
|
||||
|
||||
// GetSpaceMembers retrieves all members in a space
|
||||
func (r *MembershipRepository) GetSpaceMembers(ctx context.Context, spaceID bson.ObjectID) ([]*entities.Membership, error) {
|
||||
var memberships []*entities.Membership
|
||||
|
||||
cursor, err := r.collection.Find(ctx, bson.M{"space_id": spaceID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
if err = cursor.All(ctx, &memberships); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return memberships, nil
|
||||
}
|
||||
|
||||
// GetUserMemberships retrieves all memberships for a user
|
||||
func (r *MembershipRepository) GetUserMemberships(ctx context.Context, userID bson.ObjectID) ([]*entities.Membership, error) {
|
||||
var memberships []*entities.Membership
|
||||
|
||||
cursor, err := r.collection.Find(ctx, bson.M{"user_id": userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
if err = cursor.All(ctx, &memberships); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return memberships, nil
|
||||
}
|
||||
|
||||
// UpdateMembership updates a membership
|
||||
func (r *MembershipRepository) UpdateMembership(ctx context.Context, membership *entities.Membership) error {
|
||||
_, err := r.collection.ReplaceOne(ctx, bson.M{"_id": membership.ID}, membership)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteMembership deletes a membership
|
||||
func (r *MembershipRepository) DeleteMembership(ctx context.Context, id bson.ObjectID) error {
|
||||
_, err := r.collection.DeleteOne(ctx, bson.M{"_id": id})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteMembershipsBySpaceID deletes all memberships for a space
|
||||
func (r *MembershipRepository) DeleteMembershipsBySpaceID(ctx context.Context, spaceID bson.ObjectID) error {
|
||||
_, err := r.collection.DeleteMany(ctx, bson.M{"space_id": spaceID})
|
||||
return err
|
||||
}
|
||||
|
||||
// EnsureIndexes creates necessary indexes
|
||||
func (r *MembershipRepository) EnsureIndexes(ctx context.Context) error {
|
||||
indexModel := []mongo.IndexModel{
|
||||
{
|
||||
Keys: bson.D{bson.E{Key: "user_id", Value: 1}, bson.E{Key: "space_id", Value: 1}},
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{bson.E{Key: "space_id", Value: 1}},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := r.collection.Indexes().CreateMany(ctx, indexModel)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user