Skip to content

About

Plataforma de pedidos y catálogo para Ainoa's Cakes, pastelería en Ecuador.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Ainoa's Cakes

ACakes — Sistema de gestión para Ainoa's Cakes

Aplicación a medida desarrollada para Ainoa's Cakes, pastelería de pasteles personalizados y temáticos en El Empalme, Ecuador. Centraliza la operación diaria del negocio (pedidos, clientes, productos e ingresos) y expone un catálogo público para que los clientes descubran productos y coticen por WhatsApp.

React TypeScript Node.js Prisma PostgreSQL Tailwind CSS Vite

Estado Uso Demo


Ainoa's Cakes

Sobre el proyecto

ACakes es el software interno que usa Ainoa's Cakes para operar su taller de pastelería a diario. No es un menú de precios fijos: cada pastel se cotiza y confecciona a pedido, así que el sistema está construido alrededor de ese flujo real de negocio.

La app tiene dos capas:

Capa Para quién Rutas
Panel administrativo La dueña del negocio, desde el celular /panel, /panel/clientes, /panel/productos, /panel/ingresos, /panel/cuenta
Catálogo público Clientes finales /, /catalogo, /producto/:id, /mis-favoritos
  • Los precios nunca se muestran en el catálogo público: la cotización siempre ocurre por WhatsApp.

  • El catálogo se organiza por temática/ocasión (cumpleaños, quinceañeras, infantil, etc.), no por categoría genérica de producto.

  • Cobertura y entrega: El Empalme, Ecuador.

  • Demo en producción: ainoascakes.netlify.app

  • Repositorio: github.com/eduaardok/acakes-app

Capturas de pantalla

Panel de Pedidos — vista semanal

Panel de Pedidos — vista semanal mobile-first, con estados por pedido (Borrador, Confirmado, En proceso, Listo, Entregado) y acceso rápido a crear un nuevo pedido.

Funcionalidades principales

Pedidos
Crear pedido, ver detalle, actualizar estado. Vista diaria/semanal de operación del día y listados por cliente. Imágenes adjuntas por pedido.
Clientes
Búsqueda con debounce, listado y detalle con historial. Observaciones manuales y automáticas (comportamiento, notas relevantes).
Productos y categorías
Catálogo interno de productos con imágenes (Supabase Storage), organizados por categoría/temática desde el panel.
Ingresos
Reporte por rango de fechas. Regla de negocio explícita: solo los pedidos en estado ENTREGADO cuentan como ingreso.
Catálogo público
Landing + catálogo navegable por temática/ocasión, favoritos (invitado o con cuenta), detalle de producto y cotización directa por WhatsApp. Sin precios visibles.
Cuentas y seguridad
Auth propia con JWT + bcrypt para el panel administrativo, y cuenta de cliente independiente (registro, login, recuperación de contraseña) para el catálogo.

Stack tecnológico (y por qué)

  • Backend: Node.js + Express + TypeScript API REST simple, predecible y rápida de iterar. TypeScript reduce bugs en cambios de reglas de negocio (transiciones de estado, filtros de ingresos, etc.).
  • ORM: Prisma Tipado end-to-end en la capa de datos y migraciones controladas. Modelado claro de relaciones (Cliente → Pedidos → Observaciones, Producto → Categoría).
  • Base de datos: PostgreSQL (Supabase) Postgres por consistencia/transacciones y queries estructuradas. Supabase como Postgres gestionado, con Storage para las imágenes de productos y pedidos.
  • Frontend: React + Vite + React Router React para UI por estados y componentes reutilizables. Vite para DX rápida. Router para separar panel administrativo y catálogo público sin complejidad extra.
  • UI: Tailwind CSS Iteración rápida en UI mobile-first sin depender de librerías de componentes, manteniendo consistencia visual con la identidad de marca.
  • Auth: JWT propio + bcrypt Control explícito del flujo (login/logout, expiración, protección de rutas) sin vendor lock-in, con auth separada para panel y clientes.

Arquitectura del proyecto

Monorepo simple con dos apps:

ACakes/
├── backend/
└── frontend/

Backend (backend/src)

backend/src/
├── routes/        → auth, clientes, pedidos, producto, categorias, usuariosCliente, public
├── controllers/    → auth, clientes, pedidos, producto, categoria, catalogo, interacciones, clienteAuth, pedidoImagenes
├── middleware/     → auth.middleware.ts, auth.cliente.middleware.ts, upload.middleware.ts
├── lib/            → prisma.ts (singleton), transiciones.ts, supabaseStorage.ts, mailer.ts, publicCache.ts
└── index.ts        → rutas públicas (/health, /auth, /public) y protegidas (/clientes, /pedidos, /productos)

Frontend (frontend/src)

frontend/src/
├── pages/          → Dashboard, Clientes, Productos, Categorias, Ingresos, Cuenta, DetallePedido, DetalleCliente...
├── public/          → Landing, Catalogo, ProductoDetalle, login/registro de cliente, favoritos
├── components/      → PedidoCard, BuscadorCliente, BottomNav, Layout, PrivateRoute...
├── hooks/           → usePedidosHoy, usePedido, useClientes, useCliente, useIngresos, useCatalogo...
└── lib/             → api.ts (wrapper fetch con JWT + manejo de 401)

Decisiones técnicas destacadas

  • verbatimModuleSyntax — Fuerza imports consistentes (import type) y evita ambigüedades entre tipos/valores en TS, especialmente en frontend.
  • Singleton de Prisma — Una única instancia del cliente Prisma para evitar múltiples conexiones en desarrollo/hot reload.
  • Debounce en el buscador de clientes — Reduce carga de requests y mejora la UX en mobile; exige mínimo de caracteres para evitar ruido.
  • Skeletons en cargas — Mejor percepción de performance y layout estable vs. spinners genéricos.
  • JWT propio — Control total sobre expiración, payload y manejo de 401 (redirección al login) sin dependencias "mágicas".
  • Fechas con T00:00:00 — Normalización al construir rangos (inicio/fin de día) para minimizar desfasajes por zona horaria al filtrar ingresos.
  • Sin precios en el catálogo público — Regla de negocio aplicada de forma consistente en todo el código público; la cotización siempre pasa por WhatsApp.

Cómo correr localmente

Requisitos

  • Node.js (LTS recomendado)
  • npm
  • Una base Postgres accesible (por ejemplo un proyecto en Supabase)

Variables de entorno

Crear un archivo backend/.env con valores reales:

# Backend
DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DB?schema=public"
JWT_SECRET="cambia-esto-por-un-secreto-largo"
PORT=3000
CORS_ORIGIN="http://localhost:5173"

Crear un archivo frontend/.env:

# Frontend
VITE_API_URL="http://localhost:3000"

Instalar dependencias y ejecutar

Backend:

cd backend
npm install
npx prisma generate
# opcional si usas migraciones en tu entorno local:
# npx prisma migrate dev
npm run dev

Frontend:

cd frontend
npm install
npm run dev

Notas operativas:

  • Si el backend devuelve 401, el frontend maneja el caso y redirige al login.
  • Si tu base devuelve decimales como string (común en ORMs/PG), el frontend normaliza para mostrar importes correctamente.

Deploy

Arquitectura de deploy en producción:

  • Supabase — PostgreSQL gestionado (DATABASE_URL) y Storage para imágenes.
  • Railway — backend (API Express)
    • Variables: DATABASE_URL, JWT_SECRET, CORS_ORIGIN (apuntando al dominio de Netlify), PORT (si aplica).
    • Comandos: build npm run build y start npm run start.
  • Netlify — frontend (Vite) → ainoascakes.netlify.app
    • Variable: VITE_API_URL apuntando al dominio del backend en Railway.
    • Build: npm run build, publish: dist/.

Ainoa's Cakes

Desarrollado a medida para Ainoa's Cakes · El Empalme, Ecuador

About

Plataforma de pedidos y catálogo para Ainoa's Cakes, pastelería en Ecuador.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages