180 lines
4.4 KiB
Markdown
180 lines
4.4 KiB
Markdown
# 🛠️ Stack Tecnológica — ReservaMesa
|
|
|
|
## Stack Principal
|
|
|
|
### Frontend Framework
|
|
**Next.js 14** (App Router)
|
|
- Server Components para performance
|
|
- Client Components para interatividade em tempo real
|
|
- API Routes para webhooks e integrações externas
|
|
- Middleware para proteção de rotas
|
|
|
|
### Linguagem
|
|
**TypeScript** — tipagem estática, melhor DX, menos bugs em produção
|
|
|
|
### Estilização
|
|
**Tailwind CSS v3** + **Shadcn/UI**
|
|
- Design system consistente
|
|
- Componentes como: Calendar, Table, Dialog, Toast, Tabs
|
|
- Dark/Light mode nativo
|
|
|
|
### Animações
|
|
**Framer Motion** — transições de página, animações de estado
|
|
|
|
---
|
|
|
|
## Firebase (Base de Dados Existente)
|
|
|
|
### Serviços Utilizados
|
|
| Serviço | Uso no Projeto |
|
|
|---|---|
|
|
| **Firestore** | Base de dados principal (reservas, mesas, restaurantes) |
|
|
| **Firebase Auth** | Autenticação de restaurantes |
|
|
| **Firebase Storage** | Imagens de restaurantes, logos |
|
|
| **Firebase Functions** | Triggers automáticos (confirmação de reserva, notificações) |
|
|
| **Firebase Hosting** | (opcional, substituível por Vercel) |
|
|
|
|
### Estrutura do Firestore (Proposta)
|
|
|
|
```
|
|
/restaurants/{restaurantId}
|
|
- name: string
|
|
- email: string
|
|
- phone: string
|
|
- address: string
|
|
- capacity: number
|
|
- openingHours: map
|
|
- logoUrl: string
|
|
- settings: map
|
|
|
|
/restaurants/{restaurantId}/tables/{tableId}
|
|
- number: number
|
|
- capacity: number
|
|
- zone: "interior" | "exterior" | "vip"
|
|
- isActive: boolean
|
|
|
|
/restaurants/{restaurantId}/reservations/{reservationId}
|
|
- clientName: string
|
|
- clientPhone: string
|
|
- clientEmail: string
|
|
- date: timestamp
|
|
- timeSlot: string (ex: "19:00-21:00")
|
|
- partySize: number
|
|
- tableId: string (ref)
|
|
- status: "pending" | "confirmed" | "seated" | "completed" | "cancelled" | "no-show"
|
|
- notes: string
|
|
- createdAt: timestamp
|
|
- updatedAt: timestamp
|
|
|
|
/restaurants/{restaurantId}/timeslots/{slotId}
|
|
- time: string
|
|
- duration: number (minutos)
|
|
- maxCapacity: number
|
|
- isActive: boolean
|
|
|
|
/users/{userId}
|
|
- restaurantId: string
|
|
- role: "owner" | "manager" | "staff"
|
|
- name: string
|
|
- email: string
|
|
```
|
|
|
|
---
|
|
|
|
## Real-Time Architecture
|
|
|
|
```
|
|
App Mobile (Cliente) ──┐
|
|
├──▶ Firestore ◀──▶ Dashboard Web (Restaurante)
|
|
Admin Dashboard ────────┘
|
|
```
|
|
|
|
- `onSnapshot()` listeners para atualizações em tempo real
|
|
- Sem necessidade de polling ou WebSockets adicionais
|
|
- Latência < 500ms para atualizações
|
|
|
|
---
|
|
|
|
## Deploy & CI/CD
|
|
|
|
| Ferramenta | Papel |
|
|
|---|---|
|
|
| **Vercel** | Hosting + Deploy automático |
|
|
| **GitHub** | Repositório de código |
|
|
| **GitHub Actions** | CI: lint, type-check, testes |
|
|
| **Firebase CLI** | Deploy de Functions e Rules |
|
|
|
|
### Variáveis de Ambiente Necessárias
|
|
```env
|
|
NEXT_PUBLIC_FIREBASE_API_KEY=
|
|
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
|
|
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
|
|
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
|
|
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
|
|
NEXT_PUBLIC_FIREBASE_APP_ID=
|
|
```
|
|
|
|
---
|
|
|
|
## Segurança — Firebase Rules
|
|
|
|
```javascript
|
|
rules_version = '2';
|
|
service cloud.firestore {
|
|
match /databases/{database}/documents {
|
|
|
|
// Restaurante só acede aos seus próprios dados
|
|
match /restaurants/{restaurantId} {
|
|
allow read, write: if request.auth != null
|
|
&& request.auth.uid == restaurantId;
|
|
|
|
match /reservations/{reservationId} {
|
|
allow read, write: if request.auth != null
|
|
&& get(/databases/$(database)/documents/users/$(request.auth.uid))
|
|
.data.restaurantId == restaurantId;
|
|
}
|
|
|
|
match /tables/{tableId} {
|
|
allow read, write: if request.auth != null
|
|
&& get(/databases/$(database)/documents/users/$(request.auth.uid))
|
|
.data.restaurantId == restaurantId;
|
|
}
|
|
}
|
|
|
|
// App mobile pode criar reservas e ler disponibilidade
|
|
match /restaurants/{restaurantId}/reservations/{reservationId} {
|
|
allow create: if request.auth != null;
|
|
allow read: if request.auth != null
|
|
&& resource.data.clientId == request.auth.uid;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Dependências Principais
|
|
|
|
```json
|
|
{
|
|
"dependencies": {
|
|
"next": "14.x",
|
|
"react": "18.x",
|
|
"typescript": "5.x",
|
|
"firebase": "10.x",
|
|
"tailwindcss": "3.x",
|
|
"@shadcn/ui": "latest",
|
|
"framer-motion": "11.x",
|
|
"date-fns": "3.x",
|
|
"recharts": "2.x",
|
|
"react-hook-form": "7.x",
|
|
"zod": "3.x",
|
|
"lucide-react": "latest"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
*Versão: 1.0.0 | Maio 2026*
|