package orders import ( "context" "errors" "github.com/google/uuid" "gorm.io/gorm" ) var ErrNotFound = errors.New("order not found") type Repository interface { Create(ctx context.Context, order *Order, items []*OrderItem) error FindByID(ctx context.Context, id uuid.UUID) (*Order, []*OrderItem, error) List(ctx context.Context, status string) ([]*Order, error) UpdateStatus(ctx context.Context, id uuid.UUID, status string) (*Order, error) } type gormRepository struct { db *gorm.DB } func NewRepository(db *gorm.DB) Repository { return &gormRepository{db: db} } func (r *gormRepository) Create(ctx context.Context, order *Order, items []*OrderItem) error { return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Create(order).Error; err != nil { return err } for _, item := range items { item.OrderID = order.ID } if len(items) > 0 { if err := tx.Create(&items).Error; err != nil { return err } } return nil }) } func (r *gormRepository) FindByID(ctx context.Context, id uuid.UUID) (*Order, []*OrderItem, error) { var order Order if err := r.db.WithContext(ctx).Where("id = ?", id).First(&order).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil, ErrNotFound } return nil, nil, err } var items []*OrderItem if err := r.db.WithContext(ctx).Where("order_id = ?", id).Order("created_at asc").Find(&items).Error; err != nil { return nil, nil, err } return &order, items, nil } func (r *gormRepository) List(ctx context.Context, status string) ([]*Order, error) { q := r.db.WithContext(ctx).Order("created_at desc") if status != "" { q = q.Where("status = ?", status) } var list []*Order if err := q.Find(&list).Error; err != nil { return nil, err } return list, nil } func (r *gormRepository) UpdateStatus(ctx context.Context, id uuid.UUID, status string) (*Order, error) { res := r.db.WithContext(ctx).Model(&Order{}).Where("id = ?", id).Update("status", status) if res.Error != nil { return nil, res.Error } if res.RowsAffected == 0 { return nil, ErrNotFound } var order Order if err := r.db.WithContext(ctx).Where("id = ?", id).First(&order).Error; err != nil { return nil, err } return &order, nil }