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) ([]*Order, error) ListByCustomer(ctx context.Context, customerID uuid.UUID) ([]*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) ([]*Order, error) { var list []*Order if err := r.db.WithContext(ctx).Order("created_at desc").Find(&list).Error; err != nil { return nil, err } return list, nil } func (r *gormRepository) ListByCustomer(ctx context.Context, customerID uuid.UUID) ([]*Order, error) { var list []*Order if err := r.db.WithContext(ctx).Where("customer_id = ?", customerID).Order("created_at desc").Find(&list).Error; err != nil { return nil, err } return list, nil }