package repository import ( "context" "haixun-backend/internal/library/clock" app "haixun-backend/internal/library/errors" "haixun-backend/internal/library/errors/code" "haixun-backend/internal/model/permission/domain/entity" domrepo "haixun-backend/internal/model/permission/domain/repository" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type mongoRolePermissionRepository struct { collection *mongo.Collection } func NewMongoRolePermissionRepository(db *mongo.Database) domrepo.RolePermissionRepository { if db == nil { return &mongoRolePermissionRepository{} } return &mongoRolePermissionRepository{collection: db.Collection(entity.RolePermissionCollectionName)} } func (r *mongoRolePermissionRepository) EnsureIndexes(ctx context.Context) error { if r.collection == nil { return nil } _, err := r.collection.Indexes().CreateMany(ctx, []mongo.IndexModel{ {Keys: bson.D{{Key: "tenant_id", Value: 1}, {Key: "role_key", Value: 1}, {Key: "permission_id", Value: 1}}, Options: options.Index().SetUnique(true)}, {Keys: bson.D{{Key: "tenant_id", Value: 1}, {Key: "role_key", Value: 1}}}, }) return err } func (r *mongoRolePermissionRepository) ListByRoles(ctx context.Context, tenantID string, roleKeys []string) ([]*entity.RolePermission, error) { if r.collection == nil { return nil, app.For(code.Permission).DBUnavailable("Mongo is not configured") } if tenantID == "" || len(roleKeys) == 0 { return nil, nil } cursor, err := r.collection.Find(ctx, bson.M{"tenant_id": tenantID, "role_key": bson.M{"$in": roleKeys}}) if err != nil { return nil, err } defer cursor.Close(ctx) var out []*entity.RolePermission if err := cursor.All(ctx, &out); err != nil { return nil, err } return out, nil } func (r *mongoRolePermissionRepository) SetForRole(ctx context.Context, tenantID, roleKey string, permissionIDs []string) error { if r.collection == nil { return app.For(code.Permission).DBUnavailable("Mongo is not configured") } if tenantID == "" || roleKey == "" { return app.For(code.Permission).InputMissingRequired("tenant_id and role_key are required") } if _, err := r.collection.DeleteMany(ctx, bson.M{"tenant_id": tenantID, "role_key": roleKey}); err != nil { return err } if len(permissionIDs) == 0 { return nil } now := clock.NowUnixNano() docs := make([]any, 0, len(permissionIDs)) for _, permissionID := range permissionIDs { docs = append(docs, &entity.RolePermission{ ID: primitive.NewObjectID(), TenantID: tenantID, RoleKey: roleKey, PermissionID: permissionID, CreateAt: now, UpdateAt: now, }) } _, err := r.collection.InsertMany(ctx, docs) if mongo.IsDuplicateKeyError(err) { return nil } return err }