Atelier Commerce es un e-commerce fullstack construido con Next.js, TypeScript, Prisma, PostgreSQL, NextAuth y Stripe.
Está pensado como una base profesional para una tienda online moderna: catálogo, carrito, checkout, órdenes, panel administrativo, autenticación delegada y despliegue en Vercel.
- Autenticación con OAuth usando
NextAuth - Roles de usuario (
CUSTOMER,OPERATIONS,ADMIN) - Catálogo de productos y categorías
- Carrito híbrido:
- anónimo en navegador
- persistente para usuarios autenticados
- Checkout con
Stripe Checkout - Webhooks de Stripe para confirmación y trazabilidad
- Gestión de órdenes
- Reembolsos y devoluciones desde panel interno
- Panel admin para productos, categorías y órdenes
- Base de datos con
PrismasobrePostgreSQL - Preparado para despliegue en
Vercel - Testing unitario/integración y E2E
- Frontend:
Next.js 16conApp Router - Backend: Route Handlers en
app/api/* - Base de datos:
PostgreSQL(Neon en producción) +Prisma - Auth:
NextAuthcon OAuth - Pagos:
Stripe Checkout+ webhooks - Estilos:
Tailwind CSS - Hosting:
Vercel - Testing:
Vitest+Playwright
- El usuario navega catálogo y detalle de producto desde
app/. - El carrito se gestiona desde cliente, pero las validaciones críticas viven en servidor.
- El checkout crea una orden pendiente en base de datos y genera una sesión de Stripe.
- Stripe redirige al usuario y además notifica por webhook.
- El backend confirma el pago, actualiza el estado de la orden y registra eventos operativos.
- Los usuarios autenticados consultan sus órdenes desde la cuenta.
- Los usuarios
ADMINyOPERATIONSoperan órdenes desde el panel interno.
.
├── app/
│ ├── admin/
│ ├── api/
│ ├── auth/
│ ├── cart/
│ ├── catalog/
│ ├── checkout/
│ ├── orders/
│ ├── account/
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ ├── admin/
│ ├── auth/
│ ├── layout/
│ ├── store/
│ └── ui/
├── lib/
│ ├── validators/
│ ├── auth.ts
│ ├── cart.ts
│ ├── catalog.ts
│ ├── db.ts
│ ├── logger.ts
│ ├── observability.ts
│ ├── order-status.ts
│ ├── orders.ts
│ ├── payments.ts
│ ├── permissions.ts
│ └── runtime-config.ts
├── prisma/
│ ├── migrations/
│ ├── schema.prisma
│ ├── schema.postgres.prisma
│ └── seed.ts
├── public/
├── scripts/
├── tests/
├── e2e/
├── package.json
└── next.config.ts
Contiene las pantallas, layouts y Route Handlers del proyecto.
- rutas públicas: home, catálogo, carrito, checkout
- rutas autenticadas: cuenta, órdenes
- rutas administrativas:
/admin/* - API interna:
/api/*
Componentes reutilizables de UI y composición.
store/: catálogo, carrito, checkoutadmin/: tablas, soporte de órdenes, paneles internosauth/: login, estado de sesiónlayout/: header, footerui/: componentes base como notices, dialogs, skeletons, toasts
Lógica de dominio y servicios del sistema.
- acceso a base de datos
- auth y permisos
- pagos
- lifecycle de órdenes
- observabilidad
- validaciones
Fuente de verdad del modelo de datos.
- esquema principal
- migraciones
- seed de desarrollo
Endpoints server-side del sistema:
- auth
- carrito
- órdenes
- checkout con Stripe
- webhooks
- reconciliación
- admin
Usa .env.example o .env.production.example como referencia.
DATABASE_URL="postgresql://USER:PASSWORD@HOST:5432/DB_NAME?schema=public"
DATABASE_URL_POSTGRES="postgresql://USER:PASSWORD@HOST:5432/DB_NAME?schema=public"
NEXTAUTH_URL="https://tu-dominio.com"
NEXTAUTH_SECRET="tu-secreto-largo-y-seguro"
NEXT_PUBLIC_APP_URL="https://tu-dominio.com"
AUTH_GOOGLE_ID="google-oauth-client-id"
AUTH_GOOGLE_SECRET="google-oauth-client-secret"
AUTH_GITHUB_ID="github-oauth-client-id"
AUTH_GITHUB_SECRET="github-oauth-client-secret"
ADMIN_EMAILS="admin@tu-dominio.com"
OPERATIONS_EMAILS="ops@tu-dominio.com"
STRIPE_SECRET_KEY="sk_live_o_sk_test"
STRIPE_WEBHOOK_SECRET="whsec_xxx"
INTERNAL_JOB_SECRET="token-largo-para-jobs-internos"
SENTRY_DSN=""
ALERT_WEBHOOK_URL=""
ALERT_WEBHOOK_BEARER_TOKEN=""
E2E_TEST_SECRET=""DATABASE_URL: conexión principal a PostgreSQLDATABASE_URL_POSTGRES: conexión explícita usada en validaciones/runtime checksNEXTAUTH_URL: URL base usada por NextAuthNEXTAUTH_SECRET: firma segura para sesiones y tokensNEXT_PUBLIC_APP_URL: URL pública usada por frontend y StripeAUTH_GOOGLE_*: credenciales OAuth de GoogleAUTH_GITHUB_*: credenciales OAuth de GitHubADMIN_EMAILS: correos que reciben rolADMINOPERATIONS_EMAILS: correos que reciben rolOPERATIONSSTRIPE_SECRET_KEY: clave privada de StripeSTRIPE_WEBHOOK_SECRET: firma del webhook de StripeINTERNAL_JOB_SECRET: token requerido para reconciliación internaSENTRY_DSN: captura de errores en producciónALERT_WEBHOOK_URL: webhook opcional para alertas operativasALERT_WEBHOOK_BEARER_TOKEN: bearer opcional para el webhook de alertasE2E_TEST_SECRET: secreto para helpers de test end-to-end
El proyecto usa Prisma como ORM y PostgreSQL como base principal.
Archivos principales:
Desarrollo:
npm run db:migrateProducción:
npx prisma migrate deployEl seed carga categorías y productos base.
npm run db:seedLa autenticación está delegada a proveedores OAuth.
Flujo:
- el usuario inicia sesión con Google o GitHub
- si es la primera vez, se crea su cuenta automáticamente
- en ingresos posteriores se reutiliza la cuenta existente
No existe registro manual por formulario ni manejo propio de contraseñas.
El sistema trabaja con estos roles:
CUSTOMER: compra y consulta sus órdenesOPERATIONS: opera órdenes y soporteADMIN: acceso total a panel administrativo
El rol se deriva principalmente del correo autenticado:
- si el correo está en
ADMIN_EMAILS->ADMIN - si el correo está en
OPERATIONS_EMAILS->OPERATIONS - si no, queda como
CUSTOMER
Ejemplo:
ADMIN_EMAILS="admin@tu-dominio.com,otra-admin@tu-dominio.com"- el usuario inicia checkout
- el backend crea una orden pendiente
- el backend crea una sesión de
Stripe Checkout - el usuario paga en Stripe
- Stripe redirige de vuelta a la app
- Stripe también dispara un webhook
- el backend confirma el pago y actualiza la orden
checkout.session.completedcheckout.session.expiredcheckout.session.async_payment_failedpayment_intent.succeeded
sk_test_*: entorno de pruebassk_live_*: producción real
Nunca mezcles secretos test y live con dominios productivos.
El proyecto usa:
/api/payments/webhook
- entra al dashboard de Stripe
- crea un webhook apuntando a:
https://tu-dominio.com/api/payments/webhook
-
selecciona los eventos necesarios:
checkout.session.completedcheckout.session.expiredcheckout.session.async_payment_failedpayment_intent.succeeded
-
copia el signing secret y guárdalo como:
STRIPE_WEBHOOK_SECRET="whsec_xxx"- unit tests con
Vitest - integration tests para rutas y lógica de dominio
- E2E con
Playwright
npm run lint
npm run typecheck
npm run test
npm run build
npm run e2e- conecta el repo en Vercel
- configura las variables de entorno del proyecto
- asegúrate de usar PostgreSQL real (Neon en producción)
- configura OAuth con el dominio real
- configura Stripe con el dominio real y webhook real
Carga al menos:
DATABASE_URLDATABASE_URL_POSTGRESNEXTAUTH_URLNEXTAUTH_SECRETNEXT_PUBLIC_APP_URLAUTH_GOOGLE_IDAUTH_GOOGLE_SECRETSTRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETINTERNAL_JOB_SECRET
GET /api/readinessdevuelve503si el entorno no está listoops:check:envvalida configuración mínima- producción exige HTTPS y secretos fuertes
npm install
cp .env.example .env
docker compose up -d
npm run ops:pg:wait
npm run db:generate
npm run db:migrate
npm run db:seed
npm run devLa app quedará disponible en:
http://localhost:3000
- El proyecto usa
overridesenpackage.jsonpara fijar dependencias transitivas vulnerables sin romper el stack. viteexiste solo en tooling de desarrollo/test, no como runtime productivo del e-commerce.- Stripe puede operar en modo test o live, pero el entorno productivo debe usar claves
live. - El sistema incluye validaciones de readiness para evitar despliegues inseguros.
- Los scripts operativos de PostgreSQL soportan fallback al contenedor Docker local.
- integración formal con Sentry
- alerting más completo y externo
- dashboards de observabilidad más ricos
- más cobertura E2E para flujos administrativos
- mejoras adicionales de UX comercial
- mayor automatización de despliegue y smoke tests
npm run dev
npm run build
npm run start
npm run lint
npm run typecheck
npm run test
npm run e2e
npm run db:generate
npm run db:migrate
npm run db:seed
npm run ops:check:env
npm run ops:pg:backup
npm run ops:pg:restore -- <archivo>
npm run ops:pg:restore:verify -- <archivo>
npm run ops:orders:reconcile
npm run ops:smoke