Skip to content

Instantly share code, notes, and snippets.

@neuberoliveira
Last active May 5, 2020 14:51
Show Gist options
  • Save neuberoliveira/e47481732946d12b57c5fa5a0fea8827 to your computer and use it in GitHub Desktop.
Save neuberoliveira/e47481732946d12b57c5fa5a0fea8827 to your computer and use it in GitHub Desktop.
Primeira Mesa - Delivery

Ambiente

Sem muitas exigencias, somente Docker com docker-compose ja resolve

Padrao de resposta

tudo retorna http 200, nao é restfull ainda, temos um padrao de resposta que dever ser seguido para facilitar a o gerenciamento no front, seja app, site ou painel

Login

Para nao ter mais um painel, tanto para parceiro quanto para os restaurantes, vamos usar algo no sentido de um login mais unificado, ja temos algo nesse sentido, ainda rudimentar.

Ate por que muito provavelmente sera preciso consumir mais da nosssa api restrita a parceiros

IResponse
sucesso
{
    "error": false,
    "response": {
      "qualquer": "coisa"
    }
}
erro
{
    "error": true,
    "response": [
      "erro 1",
      "erro 2",
      "erro 3"
    ]
}

Fluxo Basico

  • Add itens no carrinho/sacola
  • Ver sumario da compra
    • pratos escolhidos
    • valor da entrega (delivery)
    • endereco do restaurante (take_away)
    • total da compra
    • etc.....
  • Pagamento
    • obter valores dos itens via API
    • validar endereco

Banco de dados

Modificar

booking

incluir reservation_type que pode ser:

  • in_place: compra normal que ja temos hoje
  • take_away retirar no estabelecimento
  • delivery

deixar datetime e peoples nullable, por que no caso de delivery nao sera usado, e assim nao atrapalha outras possivis metricas

Criar Tabelas

menu_item

  • id: int unsigned
  • id_restaurant: int unsigned
  • id_menu_category: int unsigned nullable
  • name: string
  • price: double - valor real, sem os 50% aplicado
  • price_discount: double
    • valor com 50% de desconto, caso de bebida vai ser o mesmo valor de price.
    • Ideal e que na hora do cadastro ele seja preenchioo automaticamente com baso no price e is_drink
    • assim na hora de calcular o total do carrinho e so somar esse campo.
  • is_drink: boolean - se é bebida, logo o valor do desconto nao e aplicado, e tambem vai ser usado para criar a secao de bebidas no front
  • description: text
  • media: string - imagem do prato acredito que da pra seguir ifood numa boa que tem so 1 imagem

menu_category

  • id: int unsigned
  • name: string
  • order: tinyint unsigned

menu_option_group

  • id: int unsigned
  • name: string
  • id_menu_item: int unsigned
  • multiple: boolean - 0=somente uma opcao | 1=varias opcoes
  • required: boolean - 0=opcional | 1=obrigatorio

menu_option

  • id: int unsigned
  • id_option_group: int unsigned
  • name: string
  • default: boolean - 0=opcional | 1=obrigatorio indica que este e o item paadrao/pre-selecionado

booking_menu (pivot)

  • id_booking: int unsigned
  • id_menu: int unsigned

API

Alem dos itens abaixo vai ser necessario um CRUD basico para os dados das tabelas acima. Principalmente as referentes ao menu.

Respeitando os padroes de resposta nao vamos microgerenciar a esse nivel, nome de endpoints, paylodas de envio e resposta fica a criterio de voce.

Os nomes de endpoints que usei abaixo estao mais para exemplos, pode haver alteracao da sua parte sem problemas

Menu

GET menu/{restaurant_id}

Retorna o cardapio do restaurante

resposta
categories:ICategory[]
exemplo
Expandir
{
  "categories":[
    {
      "id": 1,
      "name": "Entrada",
      "items": [
        {
          "id": 1,
          "name": "Saladinha do chef",
          "price": 50,
          "price_discount": 25,
          "is_drink": false,
          "media": "foto_legal.jpg",
          "description": "varios tons de verde",
          "options_group": []
        }
      ]
    },
    {
      "id": 1,
      "name": "Bebidas",
      "items": [
        {
          "id": 2,
          "name": "Refrigerante",
          "price": 6.50,
          "price_discount": 6.50,
          "is_drink": true,
          "media": "latinha1.jpg",
          "description": "",
          "options_group": [
            {
              "id": 1,
              "name": "Lata 350",
              "multiple": false,
              "required": true,
              "options": [
                {
                  "name": "Coca Cola",
                  "default": false
                },
                {
                  "name": "Sprite",
                  "default": false
                },
                {
                  "name": "Guarana antartica",
                  "default": false
                }
              ]
            }
          ]
        },
        {
          "id": 3,
          "name": "Suco Laranja",
          "price": 9,
          "price_discount": 9,
          "is_drink": true,
          "media": "suco1.jpg",
          "description": "",
          "options_group": [
            {
              "id": 1,
              "name": "Acucar",
              "multiple": false,
              "required": true,
              "options": [
                {
                  "name": "Adocante",
                  "default": false
                },
                {
                  "name": "Sem acucar",
                  "default": false
                },
                {
                  "name": "Pouco acucar",
                  "default": false
                },
                {
                  "name": "Muito acucar",
                  "default": false
                },
                {
                  "name": "Muuuuito mesmo",
                  "default": false
                }
              ]
            }
          ]
        },
        {
          "id": 4,
          "name": "Cerveja 1",
          "price": 8,
          "price_discount": 8,
          "is_drink": true,
          "media": "breja1.jpg",
          "description": "",
          "options_group": []
        },
        {
          "id": 5,
          "name": "Cerveja 2",
          "price": 12,
          "price_discount": 12,
          "is_drink": true,
          "media": "breja1.jpg",
          "description": "",
          "options_group": []
        }
      ]
    }
  ]
}

Items

GET items?ids=1,2,3,4

Retorna a lista de itens, basicamente vamos usar isso para validacao do pagamento e calculo de preco

parametros do envio
  • ids:number[]
resposta
IMenuItem[]
exemplo
Expandir
[
  {
    "id": 1,
    "name": "Saladinha do chef",
    "price": 50,
    "price_discount": 25,
    "is_drink": false,
    "media": "foto_legal.jpg",
    "description": "varios tons de verde"
  },
  {
    "id": 4,
    "name": "Cerveja 1",
    "price": 8,
    "price_discount": 8,
    "is_drink": true,
    "media": "breja1.jpg",
    "description": "",
    "options_group": []
  }
]

Orders

GET orders

Listagem dos pedidos, tem que ter possibilidade de filtrar/ordenar por varios campos, data, regiao(esse e imprencindivel), valor, restaurante, usuario, email, etc....

Ordenacao sempre com o mais recente primeiro como padrao

definicao
IOrder[]

Tipos/Interface

ICategory

  • id:int
  • name:string
  • items: IMenuItem[]

IMenuItem

  • id:int
  • id_restaurant:int
  • name:string
  • price: number
  • price_discount: number
  • is_drink: boolean
  • media: string
  • description: text
  • [options_group: IOptionGroup[]] - opcional em alguns casos

IOptionGroup

  • id:int
  • name: string
  • multiple:boolean
  • required:boolean
  • options: IOption[]

IOption

  • name: string
  • default: boolean

IOrder

  • id:number
  • id_region:number
  • id_booking:number
  • amount: number
  • region_name: string
  • status: string
    • paid
    • canceled
    • failed - por algum motivo qualquer que nao seja o gateway de pagamento
    • refused - recusado por algum motivo, saldo insulficiente etc...
    • refunded - estornada
    • in_transit (caso delivery) a caminho do endereco
    • done (caso take_away) pronto para retirada
    • finished - caso ja tenha sido entregue ou retirado, nao sei como forcar isso, mas e bom ja lidar com ele
  • failed_reson: string - motivo da falha
  • items: IMenuItem[] - aqui pode vir sem o options_group
  • user: IUser
  • restaurant: IRestaurant
  • created_at: date

IUser

  • id: number
  • name:string
  • email:string
  • .......

IRestaurant

  • id: number
  • name: string
  • logo: string
  • .......

IResponse

  • error:boolean
  • response:object | any[] | string[]

somente em caso de erro o response deve ser obrigatoriamente um array de string com os erros

Fim

Altercao, sugestoes e tudo mais sao muito bem vindos, fiquem a vontade para propor suas consideracoes.

Duvidas estamos a disposicao.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment