Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2f24abb
feat: Criar service de autenticação e erro
lucaslinyker Jun 18, 2025
a7eaef8
build: Adicionar @fastify/cookie e @fastify/jwt
lucaslinyker Jun 24, 2025
df746fb
chore(env): Adicionar verificação do secret JWT
lucaslinyker Jun 24, 2025
bae9298
chore(types): Adicionar interface user para o @fastify/jwt
lucaslinyker Jun 24, 2025
d28cc6b
feat: Configurar fastifyJwt e cookie no fastify
lucaslinyker Jun 24, 2025
b9a2bf6
feat: Criar factory de autenticação
lucaslinyker Jun 24, 2025
5c3b31e
feat: Criar controller de autenticação
lucaslinyker Jun 24, 2025
1e8052c
feat: Criar controller de refresh token
lucaslinyker Jun 24, 2025
f5f0b93
feat: Criar controller de logout
lucaslinyker Jun 24, 2025
3f053c8
feat: Adicionar rotas para os controllers de autenticação
lucaslinyker Jun 24, 2025
c43649e
feat: Criar middleware para verificar jwt
lucaslinyker Jun 24, 2025
21f12ae
feat: Criar middleware para verificar role do user
lucaslinyker Jun 24, 2025
ad83d51
feat: Adicionar middlewares para algumas rotas
lucaslinyker Jun 24, 2025
a43c76c
refact: Remover a necessidade de passar o email para buscar o profile
lucaslinyker Jun 24, 2025
709b4fe
refact: Passar o id do usuário pelo token jwt
lucaslinyker Jun 25, 2025
8873b2b
refact: Passar o id pelo jwt
lucaslinyker Jun 25, 2025
94e366a
refact: Adicionar logout ao deletar a conta
lucaslinyker Jun 26, 2025
3877547
refact: Adicionar verificação para o token existir
lucaslinyker Jun 26, 2025
5096e2b
feat: Habilitar CORS
lucaslinyker Jun 28, 2025
cccac75
Merge pull request #18 from MLKP1/feat/make-db
lucaslinyker Jun 30, 2025
39c6adb
Merge pull request #19 from MLKP1/main
lucaslinyker Jun 30, 2025
a2bf7cc
fix: Melhorar mensagem de erro para origem não permitida no CORS
lucaslinyker Jun 30, 2025
fec64c9
Merge pull request #20 from MLKP1/feat/auth
lucaslinyker Jun 30, 2025
711569f
fix: Remover barra extra de origem permitida no CORS
lucaslinyker Jun 30, 2025
2b6d300
Merge pull request #21 from MLKP1/feat/auth
lucaslinyker Jun 30, 2025
d2779a3
docs: Adicionar seções ao README.md
lucaslinyker Jul 1, 2025
c59afc4
Merge pull request #22 from MLKP1/dev
lucaslinyker Jul 1, 2025
104dc5e
refact: Colocar factories de users dentro de pasta users
lucaslinyker Jul 14, 2025
072915e
chore: Tornar campo zipCode Int e complement opcional
lucaslinyker Jul 24, 2025
5a07e5f
feat: Implementar repositórios de address
lucaslinyker Jul 25, 2025
8388f48
feat: Criar classes de erros para address
lucaslinyker Jul 25, 2025
666accf
feat: Criar services de address
lucaslinyker Jul 25, 2025
3422254
feat: Implementar factories de address
lucaslinyker Jul 25, 2025
bf61d34
feat: Criar utils de obter address pelo zipCode
lucaslinyker Jul 26, 2025
bba90f4
fix: Implementar tratativa correta para alterar o address
lucaslinyker Jul 26, 2025
8d0f8ea
feat: Criar utils de validar address
lucaslinyker Jul 26, 2025
9b876b6
feat: Criar controllers de address
lucaslinyker Jul 26, 2025
1bf6f77
feat: Implementar rotas de address
lucaslinyker Jul 26, 2025
08e7a55
Merge pull request #23 from MLKP1/dev
lucaslinyker Jul 26, 2025
7238ec6
Merge pull request #24 from MLKP1/main
lucaslinyker Jul 26, 2025
0045f8a
Merge pull request #25 from MLKP1/dev
lucaslinyker Jul 26, 2025
2c977fb
feat: Implementar tratativa para o banco
lucaslinyker Jul 26, 2025
8312e31
chore: Adicionar configurações ao .vscode/settings
lucaslinyker Jul 26, 2025
e27bd3b
Merge branch 'dev' of github.com:MLKP1/Back into dev
lucaslinyker Jul 26, 2025
5ef78c8
Merge pull request #26 from MLKP1/dev
lucaslinyker Jul 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"files.eol": "\r\n",
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"files.autoSave": "off",
Expand All @@ -8,5 +9,6 @@
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma",
"editor.formatOnSave": true
}
},
"cSpell.words": ["bitnami", "zipcode"]
}
276 changes: 274 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,275 @@
# TCC - Pizzaria
# 🍕 Pizza Stars - API Backend

Esse é o back-end de um projeto de tcc, na qual estamos desenvolvendo para uma pizzaria.
> Sistema de gerenciamento para pizzaria desenvolvido como Trabalho de Conclusão de Curso (TCC)

Este é o backend de um sistema completo para pizzaria, oferecendo funcionalidades de autenticação, gerenciamento de usuários, produtos e pedidos.

## 📋 Sumário

- [Funcionalidades](#-funcionalidades)
- [Tecnologias](#-tecnologias)
- [Pré-requisitos](#-pré-requisitos)
- [Instalação](#-instalação)
- [Configuração](#-configuração)
- [Uso](#-uso)
- [API Endpoints](#-api-endpoints)
- [Banco de Dados](#-banco-de-dados)
- [Scripts Disponíveis](#-scripts-disponíveis)
- [Estrutura do Projeto](#-estrutura-do-projeto)
- [Contribuição](#-contribuição)

## 🚀 Funcionalidades

### Autenticação e Autorização
- ✅ Registro de usuários
- ✅ Login com JWT
- ✅ Refresh token
- ✅ Logout
- ✅ Controle de acesso por roles (CUSTOMER, EMPLOYEE, ADMIN)

### Gerenciamento de Usuários
- ✅ Perfil do usuário
- ✅ Atualização de dados
- ✅ Remoção de conta
- ✅ Listagem de usuários (Admin)

### Sistema de Produtos
- 🍕 **Pizzas**: Diferentes tamanhos (Média, Grande, Família) e tipos (Doce, Salgada)
- 🥤 **Bebidas**: Categorias (Refrigerante, Suco, Alcoólica) com volume
- 🧁 **Sobremesas**: Tipos variados (Doce, Salgada)

### Sistema de Pedidos
- 🛒 Carrinho de compras
- 📦 Gerenciamento de pedidos
- 📍 Sistema de endereços
- 🔄 Status de pedidos (Pendente, Processando, Entregando, Entregue, Cancelado)

## 🛠 Tecnologias

- **Runtime**: Node.js 20
- **Framework**: Fastify
- **Database**: PostgreSQL
- **ORM**: Prisma
- **Autenticação**: JWT (@fastify/jwt)
- **Validação**: Zod
- **Criptografia**: bcryptjs
- **Linguagem principal**: TypeScript
- **Build**: tsup
- **Dev Tools**: tsx, biome (linting)

## 📋 Pré-requisitos

- Node.js 20 ou superior
- Docker e Docker Compose
- PostgreSQL (via Docker)

## 🔧 Instalação

1. **Clone o repositório**
```bash
git clone https://github.com/MLKP1/Back.git
cd Back
```

2. **Instale as dependências**
```bash
npm install
```

3. **Configuração do banco de dados**
```bash
# Suba o container PostgreSQL
docker-compose up -d
```

## ⚙️ Configuração

### Variáveis de Ambiente

Crie um arquivo `.env` na raiz do projeto:

```env
# Database
DATABASE_URL="postgresql://lucas:lucas123@localhost:5432/pizza-stars"

# Server
PORT=3333
NODE_ENV="dev"

# JWT
JWT_SECRET="sua-chave-secreta-super-segura"

# Token de exemplo (opcional)
TOKEN="seu-token-de-teste"
```

### Configuração do Banco

```bash
# Execute as migrações
npx prisma migrate dev

# Opcional: Popular com dados de exemplo
npx prisma db seed
```

## 🚀 Uso

### Desenvolvimento
```bash
npm run dev
```
O servidor será iniciado em `http://localhost:3333`

### Produção
```bash
# Build
npm run build

# Start
npm start
```

### Outros comandos úteis
```bash
# Linting
npm run lint

# Commit padronizado
npm run commit

# Visualizar banco de dados
npx prisma studio
```

## 📚 API Endpoints

### Autenticação
| Método | Endpoint | Descrição | Auth |
|--------|----------|-----------|------|
| `POST` | `/auth/login` | Login | ❌ |
| `PATCH` | `/auth/refresh` | Renovar token | ✅ |
| `DELETE` | `/auth/logout` | Logout | ✅ |

### Usuários
| Método | Endpoint | Descrição | Auth |
|--------|----------|-----------|------|
| `POST` | `/users` | Registrar usuário | ❌ |
| `GET` | `/user` | Perfil do usuário | ✅ |
| `PATCH` | `/user` | Atualizar perfil | ✅ |
| `DELETE` | `/user` | Remover conta | ✅ |
| `GET` | `/users` | Listar usuários | 👑 Admin |

### Headers de Autenticação
```http
Authorization: Bearer <seu-jwt-token>
```

### Exemplo de Requisição

```javascript
// Registro de usuário
POST /users
Content-Type: application/json

{
"name": "Lucas",
"email": "lucas@gmail.com",
"password": "senha123"
}
```

## 💾 Banco de Dados

### Modelos Principais

- **User**: Usuários do sistema com roles
- **Address**: Endereços dos usuários
- **Pizza**: Produtos pizza com tamanhos e tipos
- **Drink**: Bebidas com categorias e volumes
- **Dessert**: Sobremesas variadas
- **Order**: Pedidos dos clientes
- **Cart**: Carrinho de compras

### Diagrama ER

#### Entidades e Relacionamentos Principais

**Usuário (User)**
- → Tem um Endereço (Address) [1:1]
- → Tem um Carrinho (Cart) [1:1]
- → Realiza vários Pedidos (Order) [1:N]

**Pedido (Order)**
- ← Pertence a um Usuário (User) [N:1]
- → Contém várias Pizzas (Pizza) [N:N]
- → Contém várias Bebidas (Drink) [N:N]
- → Contém várias Sobremesas (Dessert) [N:N]

**Carrinho (Cart)**
- ← Pertence a um Usuário (User) [1:1]
- → Contém várias Pizzas (Pizza) [N:N]
- → Contém várias Bebidas (Drink) [N:N]
- → Contém várias Sobremesas (Dessert) [N:N]

## 📜 Scripts Disponíveis

| Script | Descrição |
|--------|-----------|
| `npm run dev` | Inicia servidor de desenvolvimento |
| `npm run build` | Build para produção |
| `npm start` | Inicia servidor de produção |
| `npm run lint` | Executa linting |
| `npm run commit` | Commit padronizado |

## 📁 Estrutura do Projeto

```
prisma/
├── schema.prisma # Schema do banco
├── seed.ts # Dados iniciais
└── migrations/ # Histórico de migrações

src/
└── @types/ # Definições de tipos TypeScript
├── env/ # Configuração de variáveis
├── http/
│ ├── controllers/ # Controladores das rotas
│ │ └── users/ # Rotas de usuários
│ └── middlewares/ # Middlewares de autenticação
├── lib/ # Bibliotecas e configurações
├── repositories/ # Camada de dados
├── services/ # Lógica de negócio
│ ├── errors/ # Classes de erro customizadas
│ ├── factories/ # Factory pattern para services
│ └── users/ # Serviços de usuário
├── app.ts # Configuração do Fastify
├── server.ts # Servidor principal
```

## 🎯 Roadmap

- [ ] API de produtos (CRUD pizzas, bebidas, sobremesas)
- [ ] Sistema completo de pedidos
- [ ] Integração com pagamentos
- [ ] Sistema de delivery
- [ ] Dashboard administrativo
- [ ] Notificações em tempo real
- [ ] Relatórios e analytics

## 🤝 Contribuição

1. Fork o projeto
2. Crie uma branch para sua feature (`git checkout -b feat/funcionalidade-legal`)
3. Faça linting e formatação (`npx biome check --write`)
4. Commit suas mudanças (`git commit -m 'feat: Adicionar uma funcionalidade legal'`)
5. Push para a branch (`git push origin feat/funcionalidade-legal`)
6. Abra um Pull Request

## 📝 Licença

Este projeto é desenvolvido como Trabalho de Conclusão de Curso (TCC).

---

⭐ **Pizza Stars** - Transformando a experiência da sua pizzaria favorita!
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
Warnings:

- Changed the type of `zip_code` on the `addresses` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.

*/
-- AlterTable
ALTER TABLE "addresses" ALTER COLUMN "complement" DROP NOT NULL,
DROP COLUMN "zip_code",
ADD COLUMN "zip_code" INTEGER NOT NULL;
10 changes: 5 additions & 5 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ datasource db {
}

model Address {
id String @id @default(cuid())
id String @id @default(cuid())
number Int
street String
neighborhood String
complement String
complement String?
city String
state String @default("SP")
country String @default("BR")
zipCode String @map("zip_code")
state String @default("SP")
country String @default("BR")
zipCode Int @map("zip_code")
latitude Float
longitude Float

Expand Down
2 changes: 1 addition & 1 deletion prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ async function seed() {
street: faker.location.street(),
neighborhood: faker.location.secondaryAddress(),
number: Number.parseInt(faker.location.buildingNumber()),
zipCode: faker.location.zipCode(),
zipCode: Number.parseInt(faker.location.zipCode()),
latitude: faker.location.latitude(),
longitude: faker.location.longitude(),
userId: randomUser.id,
Expand Down
11 changes: 6 additions & 5 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ export const app = fastify()

app.register(fastifyCors, {
origin: (origin, cb) => {
const allowedOrigins = [
'http://localhost:5500',
'https://mlkp1.github.io/Front2/',
]
const allowedOrigins = ['http://localhost:5500', 'https://mlkp1.github.io']
if (!origin || allowedOrigins.includes(origin)) {
cb(null, true)
return
}
cb(new Error('Not allowed'), false)
cb(new Error(`Not allowed from origin ${origin}`), false)
},
credentials: true,
methods: '*',
Expand Down Expand Up @@ -53,6 +50,10 @@ app.setErrorHandler((error, _, reply) => {
.send({ message: 'Validation error.', issues: error.format() })
}

if (error.message.includes("Can't reach database server")) {
return reply.status(503).send({ message: 'Database error.' })
}

if (env.NODE_ENV !== 'prod') {
console.error(error)
} else {
Expand Down
23 changes: 23 additions & 0 deletions src/http/controllers/address/getAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { FastifyReply, FastifyRequest } from 'fastify'

import { AddressNotExistsError } from '@/services/errors/address-not-exists-error'
import { makeGetAddressService } from '@/services/factories/addresses/make-get-address-service'

export async function getAddress(request: FastifyRequest, reply: FastifyReply) {
const userId = request.user.sub

let address = null
try {
const getAddressService = makeGetAddressService()

address = await getAddressService.execute({ userId })
} catch (err) {
if (err instanceof AddressNotExistsError) {
return reply.status(404).send({ message: err.message })
}

throw err
}

return reply.status(200).send(address)
}
Loading