Skip to content

Modelos de Dados MongoDB

Visão Geral

O sistema utiliza MongoDB como banco de dados. Todos os documentos possuem timestamps automáticos (createdAt, updatedAt).

Collections

Tenant

typescript
interface Tenant {
  name: string;           // Nome do restaurante
  slug: string;           // Identificador único na URL
  email: string;          // Email de contato
  primaryColor: string;   // Cor primária (hex)
  secondaryColor?: string;
  plan: 'free' | 'basic' | 'premium';
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
}

Índice único: { slug: 1 }

User

typescript
interface User {
  email: string;
  password: string;        // Hash bcrypt
  name: string;
  role: 'customer' | 'staff' | 'admin' | 'superadmin';
  tenant?: ObjectId;       // Referência para Tenant (exceto superadmin)
  createdAt: Date;
  updatedAt: Date;
}

Índice único: { email: 1, tenant: 1 }

Category

typescript
interface Category {
  name: string;
  order: number;          // Ordem de exibição
  isActive: boolean;
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}
typescript
interface MenuItem {
  name: string;
  description?: string;
  price: number;
  imageUrl?: string;
  category: ObjectId;
  preparationTime?: number;  // Em minutos
  available: boolean;
  featured: boolean;         // Exibido no destaque do cardápio
  tags: string[];            // 'vegetariano' | 'vegano' | 'semGluten' | 'picante'
  pdv?: ObjectId | null;     // null = global (todas as filiais); ObjectId = filial específica
  inventoryItem?: ObjectId | null;  // Item de estoque vinculado para dedução automática
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

Order

typescript
interface Order {
  orderNumber: string;      // Formato: YYYYMMDD-XXXX
  items: Array<{
    menuItem: ObjectId;
    name: string;
    price: number;
    quantity: number;
    notes?: string;
  }>;
  customerName: string;
  customerPhone: string;
  customerEmail?: string;
  customerCpf?: string;
  type: 'dine_in' | 'takeout';
  table?: ObjectId;
  pdv?: ObjectId;            // Filial que criou o pedido
  notes?: string;
  status: 'pending' | 'confirmed' | 'preparing' | 'ready' | 'delivered' | 'cancelled';
  total: number;
  paymentMethod?: 'cash' | 'credit_card' | 'debit_card' | 'pix' | 'voucher' | 'mixed';
  isSplitBill: boolean;      // Se é parte de conta dividida
  splitBillReference?: string; // Número do pedido pai na divisão
  trackingToken?: string;
  pixPayload?: string;       // Payload PIX para geração do QR code
  pixQrCodeBase64?: string;  // QR code PIX em base64
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

Índices:

  • { orderNumber, tenant } — unique
  • { trackingToken } — sparse

Table

typescript
interface Table {
  number: number;
  capacity: number;
  status: 'available' | 'occupied' | 'reserved';
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

Reservation

typescript
interface Reservation {
  customerName: string;
  customerPhone: string;
  customerEmail?: string;
  date: Date;
  time: string;
  partySize: number;
  table?: ObjectId;
  status: 'pending' | 'confirmed' | 'cancelled';
  notes?: string;
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

InventoryItem

typescript
interface InventoryItem {
  name: string;
  sku: string;
  currentStock: number;
  minStock: number;
  unit: string;
  cost: number;
  expirationDate?: Date;
  status: 'active' | 'inactive';
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

PriceSchedule

typescript
interface PriceSchedule {
  menuItem: ObjectId;        // Item do cardápio a ser alterado
  newPrice: number;          // Novo preço
  scheduledAt: Date;         // Data/hora de aplicação
  appliedAt?: Date;          // Data/hora em que foi de fato aplicado
  status: 'pending' | 'applied' | 'cancelled';
  createdBy?: ObjectId;      // Usuário que criou
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

Índice: { tenant, status, scheduledAt }

Filial (Pdv)

typescript
interface Pdv {
  name: string;
  description: string;
  slug?: string;             // Identificador legível para URLs do cliente
  serviceMode: 'mesa' | 'balcao' | 'auto_atendimento';
  active: boolean;
  isDefault: boolean;        // Filial padrão do tenant
  pin?: string;              // PIN de 4–6 dígitos (armazenado com hash)
  assignedUsers: ObjectId[]; // Usuários autorizados a usar este terminal
  address?: string;
  city?: string;
  phone?: string;
  cnpj?: string;
  cep?: string;
  tenant: ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

Índices:

  • { name, tenant } — unique
  • { slug, tenant } — unique sparse

Lançado sob a licença MIT.