Plataforma completa para la gestión de restaurantes con integración híbrida Supabase + Prisma ORM
- Gestión completa de restaurantes: Menús, inventario, empleados, pedidos y más
- Arquitectura híbrida: Supabase para autenticación y tiempo real + Prisma ORM para operaciones de base de datos
- TypeScript: Tipado completo y seguridad en el desarrollo
- Real-time: Actualizaciones en tiempo real usando Supabase subscriptions
- Responsive: Diseño adaptable para móviles y escritorio
- Next.js 14 - Framework de React con App Router
- TypeScript - Tipado estático
- Tailwind CSS - Estilos utilitarios
- Radix UI - Componentes accesibles
- React Hook Form - Gestión de formularios
- Supabase - BaaS para autenticación, storage y real-time
- Prisma ORM - ORM moderno para PostgreSQL con tipado completo
- PostgreSQL - Base de datos principal (hospedada en Supabase)
- Supabase: Autenticación, storage, subscripciones en tiempo real
- Prisma: Operaciones CRUD, consultas complejas, migraciones, tipado TypeScript
git clone https://github.com/AmCode-dev/resto-manage.git
cd resto-managenpm installCrear un archivo .env basado en .env.example:
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL="tu-url-de-supabase"
NEXT_PUBLIC_SUPABASE_ANON_KEY="tu-clave-anonima-de-supabase"
# Database Configuration for Prisma
# Usar la URL de conexión directa de PostgreSQL de Supabase
DATABASE_URL="postgresql://postgres:[PASSWORD]@[HOST]:5432/postgres?schema=public"npm run prisma:pullnpm run prisma:generatenpm run prisma:studionpm run devnpm run dev- Iniciar servidor de desarrollonpm run build- Construir para producciónnpm run start- Iniciar servidor de producciónnpm run lint- Ejecutar linter
npm run prisma:generate- Generar cliente de Prismanpm run prisma:studio- Abrir Prisma Studionpm run prisma:push- Sincronizar esquema con BD (desarrollo)npm run prisma:pull- Generar esquema desde BD existentenpm run prisma:migrate- Crear y aplicar migracionesnpm run prisma:reset- Resetear base de datos
// lib/services/menu-service.ts
import { prisma } from '@/lib/prisma'
export class MenuService {
async getMenusByRestaurant(restauranteId: string) {
return await prisma.menu.findMany({
where: { restaurante_id: restauranteId },
orderBy: { titulo: 'asc' }
})
}
async createMenu(restauranteId: string, menuData: MenuInput) {
return await prisma.menu.create({
data: { ...menuData, restaurante_id: restauranteId }
})
}
}// hooks/use-menus-hybrid.tsx
import { menuService } from '@/lib/services/menu-service'
import { getSupabaseClient } from '@/lib/supabase-client'
export function useMenusHybrid(restauranteId: string) {
// Usar Prisma para operaciones CRUD
const loadMenus = async () => {
const menus = await menuService.getMenusByRestaurant(restauranteId)
setMenus(menus)
}
// Usar Supabase para real-time subscriptions
useEffect(() => {
const subscription = supabase
.channel('menu_changes')
.on('broadcast', { event: 'menu_updated' }, () => {
loadMenus() // Recargar cuando hay cambios
})
.subscribe()
return () => subscription.unsubscribe()
}, [])
}- ✅ Operaciones CRUD complejas
- ✅ Consultas con joins y agregaciones
- ✅ Migraciones de esquema
- ✅ Tipado TypeScript automático
- ✅ Transacciones de base de datos
- ✅ Autenticación de usuarios
- ✅ Subscripciones en tiempo real
- ✅ Storage de archivos
- ✅ Row Level Security (RLS)
- ✅ Funciones Edge
restaurantes- Información de restaurantesempleados- Gestión de empleadosmenus- Menús y platosinventario_comidas- Inventario de comidasinventario_bebidas- Inventario de bebidaspedidos- Gestión de pedidoscajas- Control de cajastransacciones- Registro de transaccionessecciones_sistema- Secciones del sistemapermisos_empleados- Permisos por empleado
model Restaurante {
empleados Empleado[]
menus Menu[]
inventario_comidas InventarioComida[]
// ... más relaciones
}
model Empleado {
restaurante Restaurante @relation(fields: [restaurante_id], references: [id])
permisos PermisoEmpleado[]
}La autenticación se maneja completamente con Supabase:
// hooks/use-auth.tsx
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
})Los permisos se gestionan a nivel de base de datos usando Prisma:
// Verificar permisos con Prisma
const empleado = await prisma.empleado.findFirst({
where: { user_id: userId },
include: { permisos: true }
})- Conectar repositorio a Vercel
- Configurar variables de entorno
- Desplegar automáticamente
NEXT_PUBLIC_SUPABASE_URL=tu-url-de-supabase
NEXT_PUBLIC_SUPABASE_ANON_KEY=tu-clave-publica
DATABASE_URL=postgresql://user:pass@host:port/dbSi tienes código existente que usa solo Supabase, puedes migrar gradualmente:
// Código existente sigue funcionando
const { data } = await supabase.from('menus').select('*')// Nuevo código usa servicios híbridos
const menus = await menuService.getMenusByRestaurant(restauranteId)- Empieza con nuevas funcionalidades
- Migra hooks existentes cuando sea conveniente
- Mantén compatibilidad durante la transición
- Fork el proyecto
- Crear una rama para tu feature (
git checkout -b feature/nueva-funcionalidad) - Commit tus cambios (
git commit -m 'Agregar nueva funcionalidad') - Push a la rama (
git push origin feature/nueva-funcionalidad) - Abrir un Pull Request