Skip to content

danielmsatiro/babyshower

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

API - BabyShower (python*)

Este é um dos backends da aplicação BabyShower - É uma plataforma em que os pais podem se cadastrar e interagir com outros pais que passam por fases de vida similares as suas. Nessa plataforma eles se cadastram e também cadastram produtos que não precisam mais.

Também é possível fazer uso de recursos de geolocalização para localizar os pais que estão mais próximos ao usuário de modo que o negócio tenha mais chances de ser concretizado.

*IMPORTANTE: Esta api foi desenvolvida em Python e funciona em conjunto com outra api desenvolvida em Node.js que é utilizada para cadastro de empresas e anúncios, upload de imagens na AWS, banco de dados para chat com socket.io e cadastro de administradores de sistema da babyshower. Entretanto, as rotas para chat inicialmente desenvolvidas em python também foram mantidas nesta api.

O url base da API-python no heroku: baseUrl

O url base da API-node no heroku: baseUrlNode

Repositório da api complementar em Node.js:Api_Babyshower_nodejs

Devs participantes:

  • Allan Verde Rodrigues (Product Owner),
  • Daniel Mateus Satiro (Tech Lead),
  • Felipe Foster (Scrum Master),
  • Guilherme Couto,
  • Hirton Silva Evangelista Santos,
  • Pedro Basilio.

Tecnologias Utilizadas

  • FlaskSQLAlchemy;
  • ORM e PostgreSQL para relacionamentos entre tabelas;
  • Criptografia e hashing;
  • Extensão Postgis para tratamento da geolocalização;
  • Serviço de envio de email (temporariamente indisponível devido a mudanças no serviço smtp do gmail).

Documentação

Rotas Products

Obs.: Alterações e deleções somente pode ser realizadas pelo parent que publicou o produto.

Rotas que não precisam de autenticação

Obter todos os produtos

GET /api/products - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/products - FORMATO DA RESPOSTA - STATUS 200

[
  {
    "id": 429,
    "title": "bebê-conforto",
    "price": 350.0,
    "parent_id": 460,
    "description": "Fugiat expedita eum qui dolorem a temporibus deserunt optio veritatis eius fuga blanditiis veniam ratione recusandae placeat nam atque aliquam impedit nisi dolorum.",
    "image1": "https://imagem/320x240",
	"image2": null,
	"image3": null,
	"image4": null,
    "sold": false,
    "categories": [
    	"segurança para bebê",
    	"0 a 3 meses",
    	"4 a 6 meses",
    	"7 a 9 meses",
    	"10 meses a 1 ano",
    	"2 anos"
    ],
    "city/state": "Balneário Arroio do Silva/Santa Catarina",
    "questions": "/api/questions/by_product/429"
  },
  (...)
]

Realizando filtros nesta rota:

Podem ser realizados filtros de duas formas a seguir:

  • Via Query Params: Para paginações utilizando 'page'(deault=1) e/ou 'per_page' (default=8)
  • Via Body da requisição:
    • Para título do produto (podendo ser parcial);
    • Para lista de categorias do produto;
    • Para preços máximos e mínimos;
    • Para cidade/estado referência para geolocalização;
    • Para latitude/longitude referência também para geolocalização;
    • Para raio de cobertura geográfica a partir do local de referência.

Obs.: Essa forma de paginar resultados via query params também pode ser utilizada nas rotas para obter todos os parents(usuários) ou para obter todas as perguntas por id de produto.

Via Query Params sem body na requisição:

GET /api/products?perPage=2&page=1 - FORMATO DA REQUISIÇÃO

Caso dê tudo certo, a resposta será assim:

GET /api/products?perPage=2&page=1 - FORMATO DA RESPOSTA - STATUS 200

[
  {
    "id": 317,
    "title": "Nanina",
    "price": 15.0,
    "parent_id": 339,
    "description": "Ab in neque earum odio quia molestias minima eaque ratione eos illum.",
    "image1": "https://imagem/320x240",
	"image2": null,
	"image3": null,
	"image4": null,
    "sold": false,
    "categories": [
    	"brinquedos"
    ],
    "city/state": "Araranguá/Santa Catarina",
    "questions": "/api/questions/by_product/317"
  },
  {
  	"id": 360,
  	"title": "body tamanho M",
  	"price": 36.0,
  	(...)
  }
]

Via Body na na requisição:

Obs.: Pode ter query params para a paginação em conjunto.

GET /api/products?page=1&per_page=3 - FORMATO DA REQUISIÇÃO

{
  "categories": ["roupas", "0 a 3 meses"],
  "min_price": 30.0,
  "max_price": 60.0,
  "title_product": "",
  "city": "Cocal do Sul",
  "state": "Santa catar",
  "distance": 50000
}

Obs.: Para categories, title_product, city e state é busca é por aproximação. Exemplo: Pode-se buscar "Santa Catarina" como "santa c" ou "catarina" na informação state.

GET /api/products?page=1&per_page=3 - FORMATO DA RESPOSTA - STATUS 200

[
	{
		"id": 2780,
		"title": "Tênis tam 16",
		"price": 36.0,
		"parent_id": 2987,
		"description": "Accusamus nisi aspernatur nulla fuga enim velit quibusdam maxime voluptates vitae mollitia dolorum dolorum.",
		"image1": "https://imagem/320x240",
		"image2": null,
		"image3": null,
		"image4": null,
		"sold": false,
		"categories": [
			"roupas",
			"0 a 3 meses"
		],
		"city/state": "Meleiro/Santa Catarina",
		"questions": "/api/questions/by_product/2780"
	},
  (...)
]

Outras informações sobre a geolocalização

Sobre a rota anterior, caso seja fornecido o Token Bearer no head da requisição a localização de referência para o raio de alcance da pesquisa serão a cidade e o estado no cadastro do usuário. Caso o usuário não esteja autenticado, ou não seja fornecido o token a pesquisa não considerará aspectos geográficos.

Como mencionado anteriormente, podem ser fornecidos no body da requisição como referência para o raio de alcance:

  • Cidade E estado; OU
  • Latitude E Longitude

Raio de alcance:

O raio de alcance quando não fornecido possui o valor padrão de 50 mil km. Deve-se utilizar a chave "distance" no body da requisição.

Obs.:: Esta área de cobertura só será utilizada se houver um ponto de referênica obtido pelos dados do usuário ou pelo body da requisição.

Obter produto por id

GET /api/products/<product_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/products/2 - FORMATO DA RESPOSTA - STATUS 200

{
	"id": 2,
	"title": "Nanina",
	"price": 15.0,
	"parent_id": 2,
	"description": "Repellat deserunt eum necessitatibus nam consequuntur vero harum asperiores excepturi tenetur voluptatem voluptate commodi ratione suscipit quibusdam quibusdam quas illo atque incidunt commodi.",
	"image1": "https://imagem/320x240",
	"image2": null,
	"image3": null,
	"image4": null,
	"sold": false,
	"categories": [
		"brinquedos"
	],
	"city/state": "Abadia dos Dourados/Minas Gerais",
	"questions": "/api/questions/by_product/2"
}

Obter produto pelo id do parent

GET /api/products/by_parent/<parent_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/products/by_parent/2 - FORMATO DA RESPOSTA - STATUS 200

{
  "products": [
	{
		"id": 2,
		"title": "Nanina",
		"price": 15.0,
		"parent_id": 2,
		"description": "Repellat deserunt eum necessitatibus nam consequuntur vero harum asperiores excepturi tenetur voluptatem voluptate commodi ratione suscipit quibusdam quibusdam quas illo atque incidunt commodi.",
		"image1": "https://imagem/320x240",
		"image2": null,
		"image3": null,
		"image4": null,
		"sold": false,
		"categories": [
			"brinquedos"
		],
		"city/state": "Abadia dos Dourados/Minas Gerais",
		"questions": "/api/questions/by_product/2"
	},
  (...)
  ]
}

Rotas que precisam de autenticação

Criar novo produto

POST /api/products - FORMATO DA REQUISIÇÃO

{
	"title": "tiptop",
	"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
	"price": 610.69,
	"image1": "https://imagem/320x240",
	"image2": null,
	"image3": null,
	"image4": null,
	"categories": ["0 a 3 meses", "roupas"]
}

Caso dê tudo certo, a resposta será assim:

POST /api/products - FORMATO DA RESPOSTA - STATUS 201

{
	"id": 5542,
	"title": "tiptop",
	"price": 610.69,
	"parent_id": 5542,
	"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
	"image1": "https://imagem/320x240",
	"image2": null,
	"image3": null,
	"image4": null,
	"sold": false,
	"categories": [
		"0 a 3 meses",
		"roupas"
	],
	"city/state": "Cocal do Sul/Santa Catarina",
	"questions": "/api/questions/by_product/5542"
}

Obs.: Quando o parent cadastra um novo produto, um email de confirmação é enviado para o seu respectivo email cadastrado.

Obs.: Um produto pode ser criado sem categoria. A categoria é buscada pela palavra aproximada na relação de categories desta api. Ao se inserir uma categoria não existente se obterá o seguinte erro:

POST /api/products - FORMATO DA RESPOSTA - STATUS 422

{
  "error": "Categories is invalid",
  "invalid_options": [
  	"teste"
  ],
  "valid_options": "api/categories"
}

Atualizar produto por id

PATCH /api/products/<product_id> - FORMATO DA REQUISIÇÃO

{
  "price": 52.0,
  "categories": ["4 a 6 meses"]
}

Caso dê tudo certo, a resposta será assim:

PATCH /api/products/5542 - FORMATO DA RESPOSTA - STATUS 201

{
	"id": 5542,
	"title": "tiptop",
	"price": 52.0,
	"parent_id": 5542,
	"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.",
	"image1": "https://imagem/320x240",
	"image2": null,
	"image3": null,
	"image4": null,
	"sold": false,
	"categories": [
		"4 a 6 meses"
	],
	"city/state": "Cocal do Sul/Santa Catarina",
	"questions": "/api/questions/by_product/5542"
}

Excluir produto por id

DELETE /api/products/<product_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

DELETE /api/products/1 - FORMATO DA RESPOSTA - STATUS 204

Sem corpo de resposta

Rota Categories

Rota não precisa de autenticação

Obter todas as categories

GET /api/categories - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/categories - FORMATO DA RESPOSTA - STATUS 200

{
  "categories": [
    {
      "id": 1,
      "name": "até 3 meses",
      "description": "Tudo o que o seu bebê precisa até os seus 3 meses"
    },
    {
      "id": 2,
      "name": "até 6 meses",
      "description": "Tudo o que o seu bebê precisa até os seus 6 meses"
    },
    {
      "id": 3,
      "name": "até 9 meses",
      "description": "Tudo o que o seu bebê precisa até os seus 9 meses"
    }
  ]
}

Rotas Questions

Obs.: Todos os parents podem fazer perguntas em quaisquer outros produtos. Inclusive nos próprios produtos.

Rotas que não precisam de autenticação

Obter todas as perguntas por id de produto

GET /api/questions/by_product/<product_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/questions/by_product/3001 - FORMATO DA RESPOSTA - STATUS 200

[
  {
		"id": 3001,
		"question": "teste",
		"created_at": "Wed, 04 May 2022 21:12:02 GMT",
		"updated_at": null,
		"product_id": 301,
		"parent_id": 20,
		"answer": {
			"link": "/api/answers/1",
			"username": "fdddgd5dfd",
			"answer": "teste2"
		},
		"username": "miguel83"
	},
  (...)
]

Rotas que precisam de autenticação

Criar nova pergunta em um produto por id de produto

POST /api/questions/<product_id> - FORMATO DA REQUISIÇÃO

{
	"question": "Pergunta Teste?"
}

Caso dê tudo certo, a resposta será assim:

POST /api/question/3 - FORMATO DA RESPOSTA - STATUS 201

{
	"id": 3,
	"question": "Pergunta teste?",
	"created_at": "Thu, 05 May 2022 15:41:42 GMT",
	"updated_at": null,
	"product_id": 1,
	"parent_id": 5542,
	"answer": null
}

Obs.: É enviado uma mensagem para o e-mail do dono do produto o alertado sobre a nova pergunta enviado uma pergunta.

Atualizar pergunta por id de pergunta

PATCH /api/questions/<question_id> - FORMATO DA REQUISIÇÃO

{
	"question": "Pergunta Teste Atualizada?"
}

Caso dê tudo certo, a resposta será assim:

PATCH /api/questions/1 - FORMATO DA RESPOSTA - STATUS 200

{
	"id": 1,
	"question": "Pergunta teste atualizada?",
	"created_at": "Thu, 05 May 2022 10:29:22 GMT",
	"updated_at": "Thu, 05 May 2022 15:43:48 GMT",
	"product_id": 1,
	"parent_id": 5542,
	"answer": null
}

Deletar pergunta por id de pergunta

DELETE /api/questions/<question_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

DELETE /api/questions/1 - FORMATO DA RESPOSTA - STATUS 204

Sem corpo de resposta

Rotas Answers

Obs.: Somente o parent que postou o produto pode responder as perguntas que estiverem vinculadas ao seu produto.

Rotas que precisam de autenticação

Criar uma resposta

POST /api/answers/<question_id> - FORMATO DA REQUISIÇÃO

{
  "answer": "Resposta Teste!"
}

Caso tudo dê certo, a resposta será assim:

POST /api/answers/1 - FORMATO DA RESPOSTA - STATUS 201

{
	"id": 1,
	"answer": "Resposta Teste!",
	"created_at": "Wed, 04 May 2022 21:13:16 GMT",
	"updated_at": null,
	"parent_id": 19,
	"question": {
		"link": "/api/questions/by_product/3001",
		"question": "Pergunta Teste Atualizada?",
		"username": "Rita231"
	}
}

Obs.: É enviado uma mensagem para o e-mail do parent que fez a pergunta o alertado sobre a resposta.

Editar uma resposta

PATCH /api/answers/<answer_id> - FORMATO DA REQUISIÇÃO

{
  "answer": "Resposta Teste Editada!"
}

Caso tudo dê certo, a resposta será assim:

PATCH /api/answers/1 - FORMATO DA RESPOSTA - STATUS 200

{
	"id": 1,
	"answer": "Resposta Teste Editada!",
	"created_at": "Wed, 04 May 2022 21:13:16 GMT",
	"updated_at": "Wed, 04 May 2022 21:16:26 GMT",
	"parent_id": 19,
	"question": {
		"link": "/api/questions/by_product/3001",
		"question": "Pergunta Teste Atualizada?",
		"username": "Rita231"
	}
}

Deletar uma resposta

DELETE /api/answers/<answer_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso tudo dê certo, a resposta será assim:

DELETE /api/answers/1 - FORMATO DA RESPOSTA - STATUS 204

Sem corpo de resposta.

Rotas que não precisam de autenticação

Obter uma resposta

GET /api/answers/<answer_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso tudo dê certo, a resposta será assim:

GET /api/answers/1 - FORMATO DA RESPOSTA - STATUS 200

{
  "id": 1,
  "answer": "Resposta Teste Editada!",
  "parent_id": 1,
  "question_id": 1
}

Rotas Parents

Obs.: Rotas de obtenção de dados pessoais sensíveis, deleção e atualização só podem ser realizadas pelo próprio usuário.

Rotas que não precisam de autenticação

Obter todos os parents(informação pública)

Obs.: A rota também permite paginação (page=1 e per_page=8), bem como o param "parent_id" retornando neste caso somente um usuário caso seja encontrado.

GET /api/parents - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/parents - FORMATO DA RESPOSTA - STATUS 200

{
  "users": [
    {
		"id": 1,
		"username": "luiz-miguel90",
		"name": "Luiz Miguel",
		"image": null
    },
    {
		"id": 2,
		"username": "marianacorreia2",
		"name": "Heloísa Da Costa",
		"image": null
	},
	{
		"id": 3,
		"username": "ana-luiza363",
		"name": "Yuri Alves",
		"image": null
	},
  ]
}

Criar novo parent(usuário)

POST /api/parents - FORMATO DA REQUISIÇÃO

{
	"cpf": "12345678910",
	"username": "marcos2345",
	"name": "Marcos",
	"email": ",marcos@yahoo.com.br",
	"password": "123456",
	"phone": "(21) 99999-9999",
	"city": "Cocal do s",
	"state": "Santa Catarina"
}

Caso dê tudo certo, a resposta será assim:

POST /api/parents - FORMATO DA RESPOSTA - STATUS 201

{
	"cpf": "12345678910",
	"username": "marcos2345",
	"name": "Marcos",
	"email": ",marcos@yahoo.com.br",
	"password": "123456",
	"phone": "(21) 99999-9999",
	"city/state": "Cocal do Sul/SC"
}

Obs: Esta api não permite cpf, username ou email repetidos entre os usuários.

Fazer login

POST /api/parents/login - FORMATO DA REQUISIÇÃO

{
  "username": "fulano",
  "password": "k3nz13",
}

Obs: Obrigatórios uma identificação do usuário e seu password. Além de "username" podem ser usados "cpf" ou "email".

Caso dê tudo certo, a resposta será assim:

POST /api/parents - FORMATO DA RESPOSTA - STATUS 201

{
	"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY1MTc3OTAxNywianRpIjoiOWJmOGM2M2QtNmFkYS00YTM1LTkxNDItY2FhNmU1NGIwYWM0IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6eyJpZCI6NTU0MiwidXNlcm5hbWUiOiJkX3NhdGlybzMifSwibmJmIjoxNjUxNzc5MDE3LCJleHAiOjE2NTE3Nzk5MTd9.DT8dcAjeSQnzsEw9DqImwqfF3Nm3Q8YIiLuFUTZ72JE",
	"access_token_node": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MzYwNSwiaWF0IjoxNjU1OTg4MjQ5LCJleHAiOjE2NTU5ODkxNDl9.7ZAFBr7NvKxoQsDieraN-8gFxhrZuZlC8RnmX69Usf0",
	"id": 3605
}

Obs.1: É possível obter o id do usuário através do JWT. Token expira em 15 minutos. Obs.2: Este backend faz um request para a api_node e caso tenha algum problema no servidor o access_token_node virá com este aviso.

Rotas que precisam de autenticação

Get parent by id (usuário)

POST /api/parents/28 - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

POST /api/parents/28 - FORMATO DA RESPOSTA - STATUS 201

{
	"id": 28,
	"cpf": "11111111119",
	"username": "daniel6",
	"email": "daniel6@yahoo.com.br",
	"name": "Daniel",
	"phone": "(21) 99999-9999",
	"image": null,
	"products": "api/products/by_parent/28",
	"city": "Cocal do Sul",
	"state": "Santa Catarina"
}

Update de parent(usuário)

POST /api/parents - FORMATO DA REQUISIÇÃO

{
	"password": "123456789"
}

Obs.: Obrigatório pelo menos um campo que queira modificar.

Caso dê tudo certo, a resposta será assim:

POST /api/parents - FORMATO DA RESPOSTA - STATUS 201

{
	"id": 28,
	"cpf": "12312312313",
	"username": "fulano",
	"email": "fulano@mail.com",
	"name": "Fulano de Tal",
	"phone": "99999999999",
	"image": "http://...",
	"products": "api/products/by_parent/28",
	"city": "Cocal do Sul",
	"state": "Santa Catarina"
}

Deletar parent(usuário)

GET /api/parents - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Obs.: Obrigatório estar logado. Atenção! Trata-se de uma deleção em cascata e todos os produtos, perguntas e respostas, inclusive interações em chats serão deletados.

Caso dê tudo certo, a resposta será assim:

POST /api/parents - FORMATO DA RESPOSTA - STATUS 201

Sem corpo de resposta

Rotas Cities

Obs.: Nesta rota além de query params para paginações ('page'-> deault=1 e/ou 'per_page' -> default=8). Podem ser utilizados "city" e "state" para filtrar os resultados.

Caso dê tudo certo, a resposta será assim:

GET /api/cities?state=Santa Catarina - FORMATO DA RESPOSTA - STATUS 200

{
	"cities": [
		{
			"point_id": 1786,
			"capital": true,
			"uf": "SC",
			"longitude": -48.5477,
			"code_uf": 42,
			"code_ibge": 4205407,
			"city": "Florianópolis",
			"state": "Santa Catarina",
			"latitude": -27.5945
		},
		{
			"point_id": 43,
			"capital": false,
			"uf": "SC",
			"longitude": -49.822,
			"code_uf": 42,
			"code_ibge": 4200200,
			"city": "Agrolândia",
			"state": "Santa Catarina",
			"latitude": -27.4087
		},
		(...)

GET /api/cities?state=<estado>&city=<cidade> - FORMATO DA REQUISIÇÃO

Rotas Chat

Obs: Rotas também dispaníveis na api complementar desenvolvida em node para utilização com socket.io.

Ver todas conversas já iniciadas

GET /api/chat - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Obs: Rota mostra apenas as conversas ligadas ao usuário logado.

Caso dê tudo certo, a resposta será assim:

Obs: Propriedade "read" mostra se a mensagem já foi lida.

GET /api/chat - FORMATO DA RESPOSTA - STATUS 200

{
  "chats": [
    {
      "other_parent_id": 1,
      "messages": "chat/1",
      "read": true
    },
    {
      "other_parent_id": 2,
      "messages": "chat/2",
      "read": true
    }
  ]
}

Enviar uma mensagem

POST /api/chat/<parent_id> - FORMATO DA REQUISIÇÃO

Apenas necessário a mensagem no corpo de requisição.

Obs: Usuário precisa estar logado para enviar a mensagem.

{
  "message": "Boa noite, vi seu anuncio do site. Será que podemos conversar melhor sobre o envio?"
}

Obs: Precisa passar id do parent logado ou de um outro parent existente.

Caso dê tudo certo, a resposta será assim:

POST /api/chat/2 - FORMATO DA RESPOSTA - STATUS 201

{
  "msg": "Mensagem enviada com sucesso!"
}

Ver a conversa de um chat específico

GET /api/chat/<parent_id> - FORMATO DA REQUISIÇÃO

Não é necessário um corpo da requisição.

Caso dê tudo certo, a resposta será assim:

GET /api/chat/2 - FORMATO DA RESPOSTA - STATUS 200

Obs 1 : propriedade "msg_read" mostra se o usuário já leu a mensagem. Obs 2 : propriedade "parent" mostra a quem se destina a mensagem enviada

{
  "messages": [
    {
      "data": "Thu, 05 May 2022 19:20:28 GMT",
      "message": "Boa noite, vi seu anuncio do site. Será que podemos conversar melhor sobre o envio?",
      "msg_read": false,
      "parent": "Hirton Santos"
    }
  ]
}

About

Plataforma para anunciar produtos de bebês para trocar e/ou vender.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages