package repository import ( "context" "strings" app "haixun-backend/internal/library/errors" "haixun-backend/internal/library/errors/code" "haixun-backend/internal/model/style_preset/domain/entity" domrepo "haixun-backend/internal/model/style_preset/domain/repository" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) type mongoRepository struct { collection *mongo.Collection } func NewMongoRepository(db *mongo.Database) domrepo.Repository { if db == nil { return &mongoRepository{} } return &mongoRepository{collection: db.Collection(entity.CollectionName)} } func (r *mongoRepository) 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: "owner_uid", Value: 1}, {Key: "persona_id", Value: 1}, {Key: "create_at", Value: -1}}}, }) return err } func (r *mongoRepository) List(ctx context.Context, tenantID, ownerUID, personaID string) ([]entity.Preset, error) { if r.collection == nil { return nil, app.For(code.Persona).DBUnavailable("Mongo is not configured") } cur, err := r.collection.Find(ctx, personaFilter(tenantID, ownerUID, personaID), options.Find().SetSort(bson.D{{Key: "update_at", Value: -1}})) if err != nil { return nil, err } defer cur.Close(ctx) var out []entity.Preset if err := cur.All(ctx, &out); err != nil { return nil, err } return out, nil } func (r *mongoRepository) Get(ctx context.Context, tenantID, ownerUID, personaID, presetID string) (*entity.Preset, error) { if r.collection == nil { return nil, app.For(code.Persona).DBUnavailable("Mongo is not configured") } filter := personaFilter(tenantID, ownerUID, personaID) filter["_id"] = strings.TrimSpace(presetID) var out entity.Preset err := r.collection.FindOne(ctx, filter).Decode(&out) if err != nil { if err == mongo.ErrNoDocuments { return nil, app.For(code.Persona).ResNotFound("style preset not found") } return nil, err } return &out, nil } func (r *mongoRepository) Upsert(ctx context.Context, preset *entity.Preset) (*entity.Preset, error) { if r.collection == nil { return nil, app.For(code.Persona).DBUnavailable("Mongo is not configured") } if preset == nil { return nil, app.For(code.Persona).InputMissingRequired("preset is required") } filter := personaFilter(preset.TenantID, preset.OwnerUID, preset.PersonaID) filter["_id"] = preset.ID _, err := r.collection.ReplaceOne(ctx, filter, preset, options.Replace().SetUpsert(true)) if err != nil { return nil, err } return preset, nil } func (r *mongoRepository) Delete(ctx context.Context, tenantID, ownerUID, personaID, presetID string) error { if r.collection == nil { return app.For(code.Persona).DBUnavailable("Mongo is not configured") } filter := personaFilter(tenantID, ownerUID, personaID) filter["_id"] = strings.TrimSpace(presetID) res, err := r.collection.DeleteOne(ctx, filter) if err != nil { return err } if res.DeletedCount == 0 { return app.For(code.Persona).ResNotFound("style preset not found") } return nil } func personaFilter(tenantID, ownerUID, personaID string) bson.M { return bson.M{ "tenant_id": strings.TrimSpace(tenantID), "owner_uid": strings.TrimSpace(ownerUID), "persona_id": strings.TrimSpace(personaID), } }