first commit
This commit is contained in:
34
internal/datastore/mock_coffee_repository.go
Normal file
34
internal/datastore/mock_coffee_repository.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/repositories"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
)
|
||||
|
||||
type MockCoffeeRepository struct {
|
||||
coffees []entities.Coffee
|
||||
}
|
||||
|
||||
func NewMockCoffeeRepository() repositories.CoffeeRepository {
|
||||
return &MockCoffeeRepository{
|
||||
coffees: []entities.Coffee{
|
||||
{ID: 1, Name: "Эспрессо", Description: "Крепкий черный кофе", Price: 120.0, Size: "S"},
|
||||
{ID: 2, Name: "Капучино", Description: "Кофе с молочной пенкой", Price: 180.0, Size: "M"},
|
||||
// ... остальные данные
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MockCoffeeRepository) FindAll() ([]entities.Coffee, error) {
|
||||
return r.coffees, nil
|
||||
}
|
||||
|
||||
func (r *MockCoffeeRepository) FindByID(id int) (*entities.Coffee, error) {
|
||||
for _, coffee := range r.coffees {
|
||||
if coffee.ID == id {
|
||||
return &coffee, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.NewNotFoundError("coffee not found")
|
||||
}
|
||||
82
internal/datastore/mock_order_repository.go
Normal file
82
internal/datastore/mock_order_repository.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/repositories"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
)
|
||||
|
||||
type MockOrderRepository struct {
|
||||
orders []entities.Order
|
||||
nextID int
|
||||
}
|
||||
|
||||
func NewMockOrderRepository() repositories.OrderRepository {
|
||||
return &MockOrderRepository{
|
||||
orders: []entities.Order{
|
||||
{
|
||||
ID: 1,
|
||||
Items: []entities.Item{
|
||||
{ProductID: 1, Quantity: 1},
|
||||
{ProductID: 1, Quantity: 2},
|
||||
},
|
||||
Total: 320.0,
|
||||
Status: "completed",
|
||||
Timestamp: "2024-01-15 10:30:00",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Items: []entities.Item{
|
||||
{ProductID: 2, Quantity: 1},
|
||||
{ProductID: 3, Quantity: 1},
|
||||
},
|
||||
Total: 380.0,
|
||||
Status: "preparing",
|
||||
Timestamp: "2024-01-15 11:15:00",
|
||||
},
|
||||
},
|
||||
nextID: 3,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MockOrderRepository) FindAll() ([]entities.Order, error) {
|
||||
return r.orders, nil
|
||||
}
|
||||
|
||||
func (r *MockOrderRepository) FindByID(id int) (*entities.Order, error) {
|
||||
for _, order := range r.orders {
|
||||
if order.ID == id {
|
||||
return &order, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.NewNotFoundError("order not found")
|
||||
}
|
||||
|
||||
func (r *MockOrderRepository) Save(order *entities.Order) error {
|
||||
if order == nil {
|
||||
return errors.NewInvalidError("order cannot be nil")
|
||||
}
|
||||
|
||||
// Если это новый заказ (ID = 0), присваиваем следующий ID
|
||||
if order.ID == 0 {
|
||||
order.ID = r.nextID
|
||||
order.Timestamp = time.Now().Format("2006-01-02 15:04:05")
|
||||
if order.Status == "" {
|
||||
order.Status = "created"
|
||||
}
|
||||
r.orders = append(r.orders, *order)
|
||||
r.nextID++
|
||||
} else {
|
||||
// Обновление существующего заказа
|
||||
for i, existingOrder := range r.orders {
|
||||
if existingOrder.ID == order.ID {
|
||||
r.orders[i] = *order
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
51
internal/datastore/mock_pastry_repository.go
Normal file
51
internal/datastore/mock_pastry_repository.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/repositories"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
)
|
||||
|
||||
type MockPastryRepository struct {
|
||||
pastries []entities.Pastry
|
||||
}
|
||||
|
||||
func NewMockPastryRepository() repositories.PastryRepository {
|
||||
return &MockPastryRepository{
|
||||
pastries: []entities.Pastry{
|
||||
{ID: 1, Name: "Круассан", Description: "Слоеная выпечка с маслом", Price: 80.0, Category: "Выпечка"},
|
||||
{ID: 2, Name: "Тирамису", Description: "Итальянский десерт", Price: 150.0, Category: "Десерты"},
|
||||
{ID: 3, Name: "Чизкейк", Description: "Сырный торт", Price: 130.0, Category: "Десерты"},
|
||||
{ID: 4, Name: "Маффин", Description: "Шоколадный кекс", Price: 70.0, Category: "Выпечка"},
|
||||
{ID: 5, Name: "Печенье", Description: "Домашнее овсяное печенье", Price: 50.0, Category: "Печенье"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MockPastryRepository) FindAll() ([]entities.Pastry, error) {
|
||||
return r.pastries, nil
|
||||
}
|
||||
|
||||
func (r *MockPastryRepository) FindByID(id int) (*entities.Pastry, error) {
|
||||
for _, pastry := range r.pastries {
|
||||
if pastry.ID == id {
|
||||
return &pastry, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.NewNotFoundError("pastry not found")
|
||||
}
|
||||
|
||||
func (r *MockPastryRepository) FindByCategory(category string) ([]entities.Pastry, error) {
|
||||
var filtered []entities.Pastry
|
||||
for _, pastry := range r.pastries {
|
||||
if pastry.Category == category {
|
||||
filtered = append(filtered, pastry)
|
||||
}
|
||||
}
|
||||
|
||||
if len(filtered) == 0 {
|
||||
return nil, errors.NewNotFoundError("no pastries found for category")
|
||||
}
|
||||
|
||||
return filtered, nil
|
||||
}
|
||||
9
internal/domain/entities/coffee.go
Normal file
9
internal/domain/entities/coffee.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package entities
|
||||
|
||||
type Coffee struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Price float64 `json:"price"`
|
||||
Size string `json:"size"`
|
||||
}
|
||||
14
internal/domain/entities/order.go
Normal file
14
internal/domain/entities/order.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package entities
|
||||
|
||||
type Order struct {
|
||||
ID int `json:"id"`
|
||||
Items []Item `json:"items"`
|
||||
Total float64 `json:"total"`
|
||||
Status string `json:"status"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
ProductID int `json:"product_id"`
|
||||
Quantity int `json:"quantity"`
|
||||
}
|
||||
9
internal/domain/entities/pastry.go
Normal file
9
internal/domain/entities/pastry.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package entities
|
||||
|
||||
type Pastry struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Price float64 `json:"price"`
|
||||
Category string `json:"category"`
|
||||
}
|
||||
8
internal/domain/repositories/coffee_repository.go
Normal file
8
internal/domain/repositories/coffee_repository.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package repositories
|
||||
|
||||
import "code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
|
||||
type CoffeeRepository interface {
|
||||
FindAll() ([]entities.Coffee, error)
|
||||
FindByID(id int) (*entities.Coffee, error)
|
||||
}
|
||||
9
internal/domain/repositories/order_repository.go
Normal file
9
internal/domain/repositories/order_repository.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package repositories
|
||||
|
||||
import "code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
|
||||
type OrderRepository interface {
|
||||
FindAll() ([]entities.Order, error)
|
||||
FindByID(id int) (*entities.Order, error)
|
||||
Save(order *entities.Order) error
|
||||
}
|
||||
9
internal/domain/repositories/pastry_repository.go
Normal file
9
internal/domain/repositories/pastry_repository.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package repositories
|
||||
|
||||
import "code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
|
||||
type PastryRepository interface {
|
||||
FindAll() ([]entities.Pastry, error)
|
||||
FindByID(id int) (*entities.Pastry, error)
|
||||
FindByCategory(category string) ([]entities.Pastry, error)
|
||||
}
|
||||
45
internal/handler/coffee_handler.go
Normal file
45
internal/handler/coffee_handler.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/service"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type CoffeeHandler struct {
|
||||
coffeeService *service.CoffeeService
|
||||
}
|
||||
|
||||
func NewCoffeeHandler(coffeeService *service.CoffeeService) *CoffeeHandler {
|
||||
return &CoffeeHandler{coffeeService: coffeeService}
|
||||
}
|
||||
|
||||
func (h *CoffeeHandler) GetCoffees(c *gin.Context) {
|
||||
coffees, err := h.coffeeService.GetAllCoffees()
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, coffees)
|
||||
}
|
||||
|
||||
func (h *CoffeeHandler) GetCoffeeByID(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
Error(c, errors.NewInvalidError("invalid coffee ID format"))
|
||||
return
|
||||
}
|
||||
|
||||
coffee, err := h.coffeeService.GetCoffeeByID(id)
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, coffee)
|
||||
}
|
||||
62
internal/handler/order_handler.go
Normal file
62
internal/handler/order_handler.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/service"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type OrderHandler struct {
|
||||
orderService *service.OrderService
|
||||
}
|
||||
|
||||
func NewOrderHandler(orderService *service.OrderService) *OrderHandler {
|
||||
return &OrderHandler{orderService: orderService}
|
||||
}
|
||||
|
||||
func (h *OrderHandler) GetOrders(c *gin.Context) {
|
||||
orders, err := h.orderService.GetAllOrders()
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, orders)
|
||||
}
|
||||
|
||||
func (h *OrderHandler) GetOrderByID(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
Error(c, errors.NewInvalidError("invalid order ID format"))
|
||||
return
|
||||
}
|
||||
|
||||
order, err := h.orderService.GetOrderByID(id)
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, order)
|
||||
}
|
||||
|
||||
func (h *OrderHandler) CreateOrder(c *gin.Context) {
|
||||
var order entities.Order
|
||||
if err := c.ShouldBindJSON(&order); err != nil {
|
||||
Error(c, errors.NewInvalidError("invalid order data"))
|
||||
return
|
||||
}
|
||||
|
||||
err := h.orderService.CreateOrder(&order)
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Created(c, order)
|
||||
}
|
||||
61
internal/handler/pastry_handler.go
Normal file
61
internal/handler/pastry_handler.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/service"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type PastryHandler struct {
|
||||
pastryService *service.PastryService
|
||||
}
|
||||
|
||||
func NewPastryHandler(pastryService *service.PastryService) *PastryHandler {
|
||||
return &PastryHandler{pastryService: pastryService}
|
||||
}
|
||||
|
||||
func (h *PastryHandler) GetPastries(c *gin.Context) {
|
||||
pastries, err := h.pastryService.GetAllPastries()
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, pastries)
|
||||
}
|
||||
|
||||
func (h *PastryHandler) GetPastryByID(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
Error(c, errors.NewInvalidError("invalid pastry ID format"))
|
||||
return
|
||||
}
|
||||
|
||||
pastry, err := h.pastryService.GetPastryByID(id)
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, pastry)
|
||||
}
|
||||
|
||||
func (h *PastryHandler) GetPastriesByCategory(c *gin.Context) {
|
||||
category := c.Param("category")
|
||||
if category == "" {
|
||||
Error(c, errors.NewInvalidError("category parameter is required"))
|
||||
return
|
||||
}
|
||||
|
||||
pastries, err := h.pastryService.GetPastriesByCategory(category)
|
||||
if err != nil {
|
||||
Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, pastries)
|
||||
}
|
||||
55
internal/handler/response.go
Normal file
55
internal/handler/response.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
appErr "code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Success bool `json:"success"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func Success(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusOK, Response{
|
||||
Success: true,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
func Created(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusCreated, Response{
|
||||
Success: true,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
func Error(c *gin.Context, err error) {
|
||||
var appErr *appErr.AppError
|
||||
if errors.As(err, &appErr) {
|
||||
statusCode := appErr.Code
|
||||
if statusCode == 0 {
|
||||
statusCode = http.StatusInternalServerError
|
||||
}
|
||||
|
||||
c.JSON(statusCode, Response{
|
||||
Success: false,
|
||||
Error: appErr.Message,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Ошибка по умолчанию
|
||||
c.JSON(http.StatusInternalServerError, Response{
|
||||
Success: false,
|
||||
Error: "Internal server error",
|
||||
})
|
||||
}
|
||||
|
||||
// Аналогично для PastryHandler и OrderHandler...
|
||||
39
internal/service/coffee_service.go
Normal file
39
internal/service/coffee_service.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/repositories"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
)
|
||||
|
||||
type CoffeeService struct {
|
||||
repo repositories.CoffeeRepository
|
||||
}
|
||||
|
||||
func NewCoffeeService(repo repositories.CoffeeRepository) *CoffeeService {
|
||||
return &CoffeeService{repo: repo}
|
||||
}
|
||||
|
||||
func (s *CoffeeService) GetAllCoffees() ([]entities.Coffee, error) {
|
||||
coffees, err := s.repo.FindAll()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get coffees")
|
||||
}
|
||||
return coffees, nil
|
||||
}
|
||||
|
||||
func (s *CoffeeService) GetCoffeeByID(id int) (*entities.Coffee, error) {
|
||||
if id <= 0 {
|
||||
return nil, errors.NewInvalidError("invalid coffee ID")
|
||||
}
|
||||
|
||||
coffee, err := s.repo.FindByID(id)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, errors.NewNotFoundError("coffee not found")
|
||||
}
|
||||
return nil, errors.Wrap(err, "failed to get coffee")
|
||||
}
|
||||
|
||||
return coffee, nil
|
||||
}
|
||||
57
internal/service/order_service.go
Normal file
57
internal/service/order_service.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// internal/service/order_service.go
|
||||
package service
|
||||
|
||||
import (
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/repositories"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
)
|
||||
|
||||
type OrderService struct {
|
||||
orderRepo repositories.OrderRepository
|
||||
}
|
||||
|
||||
func NewOrderService(orderRepo repositories.OrderRepository) *OrderService {
|
||||
return &OrderService{orderRepo: orderRepo}
|
||||
}
|
||||
|
||||
func (s *OrderService) GetAllOrders() ([]entities.Order, error) {
|
||||
orders, err := s.orderRepo.FindAll()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get orders")
|
||||
}
|
||||
return orders, nil
|
||||
}
|
||||
|
||||
func (s *OrderService) GetOrderByID(id int) (*entities.Order, error) {
|
||||
if id <= 0 {
|
||||
return nil, errors.NewInvalidError("invalid order ID")
|
||||
}
|
||||
|
||||
order, err := s.orderRepo.FindByID(id)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, errors.NewNotFoundError("order not found")
|
||||
}
|
||||
return nil, errors.Wrap(err, "failed to get order")
|
||||
}
|
||||
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (s *OrderService) CreateOrder(order *entities.Order) error {
|
||||
if order == nil {
|
||||
return errors.NewInvalidError("order cannot be nil")
|
||||
}
|
||||
|
||||
if len(order.Items) == 0 {
|
||||
return errors.NewInvalidError("order must contain at least one item")
|
||||
}
|
||||
|
||||
err := s.orderRepo.Save(order)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create order")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
52
internal/service/pastry_service.go
Normal file
52
internal/service/pastry_service.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/entities"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/internal/domain/repositories"
|
||||
"code.linberg.su/linberg/awesome-cli/awesome-back/pkg/errors"
|
||||
)
|
||||
|
||||
type PastryService struct {
|
||||
repo repositories.PastryRepository
|
||||
}
|
||||
|
||||
func NewPastryService(repo repositories.PastryRepository) *PastryService {
|
||||
return &PastryService{repo: repo}
|
||||
}
|
||||
|
||||
func (s *PastryService) GetAllPastries() ([]entities.Pastry, error) {
|
||||
pastries, err := s.repo.FindAll()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get pastries")
|
||||
}
|
||||
return pastries, nil
|
||||
}
|
||||
|
||||
func (s *PastryService) GetPastryByID(id int) (*entities.Pastry, error) {
|
||||
if id <= 0 {
|
||||
return nil, errors.NewInvalidError("invalid pastry ID")
|
||||
}
|
||||
|
||||
pastry, err := s.repo.FindByID(id)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, errors.NewNotFoundError("pastry not found")
|
||||
}
|
||||
return nil, errors.Wrap(err, "failed to get pastry")
|
||||
}
|
||||
|
||||
return pastry, nil
|
||||
}
|
||||
|
||||
func (s *PastryService) GetPastriesByCategory(category string) ([]entities.Pastry, error) {
|
||||
if category == "" {
|
||||
return nil, errors.NewInvalidError("category cannot be empty")
|
||||
}
|
||||
|
||||
pastries, err := s.repo.FindByCategory(category)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get pastries by category")
|
||||
}
|
||||
|
||||
return pastries, nil
|
||||
}
|
||||
Reference in New Issue
Block a user