Files
mercadodevida/project/specs-admin/SPEC.md
2026-08-17 22:23:10 +02:00

15 KiB
Raw Blame History

Admin Panel SDD — MercadoDeVida

1. Repository Assessment

1.1 Estructura actual

mercadodevida/
├── project/                 # Backend (Fastify + Node.js)
│   └── src/modules/         # 20 módulos de dominio
├── frontend/                # Storefront (Next.js 16 + Tailwind)
│   └── src/
│       ├── app/            # Rutas Next.js
│       ├── components/      # Componentes React
│       ├── contexts/       # CartContext, AuthContext
│       ├── lib/            # api.ts (fetch functions)
│       └── types/          # API types
├── specs/                   # specs de backend (F-001F-035)
└── work/                    # artefactos por feature

1.2 Ubicación recomendada para Admin

apps/admin/                  # Nueva app Next.js independiente
├── app/
│   ├── (auth)/
│   │   └── login/
│   ├── (dashboard)/
│   │   ├── layout.tsx      # Shell con sidebar
│   │   ├── page.tsx         # Dashboard
│   │   ├── products/
│   │   ├── orders/
│   │   ├── customers/
│   │   ├── categories/
│   │   ├── brands/
│   │   ├── promotions/
│   │   ├── inventory/
│   │   ├── reviews/
│   │   ├── cms/
│   │   └── settings/
│   └── api/                # Proxies al backend (auth)
├── features/               # Feature-sliced modules
│   ├── auth/
│   ├── products/
│   ├── orders/
│   └── ...
├── components/             # Componentes compartidos
│   ├── ui/                 # Primitivos de diseño
│   └── admin/              # Componentes domain-specific
├── lib/
│   ├── api-client.ts       # Cliente HTTP único
│   └── permissions.ts      # can("action")
├── types/                  # Tipos compartidos
└── middleware/             # Auth middleware

1.3 Por qué NO en frontend/src/

  • Admin y Storefront tienen lifecycle diferentes
  • Admin es Desktop-first, Storefront es Mobile-first
  • Admin necesita auth compleja, Storefront no
  • Mezclaría contextos (CartContext no aplica a admin)
  • El Shell de Admin es completamente diferente

1.4 Build system

  • Backend: cd project && npm run builddist/
  • Frontend: cd frontend && npm run build.next/
  • Admin: cd apps/admin && npm run build.next/
  • Monorepo en nivel de scripts (npm run en root)

2. API Capability Assessment

2.1 Endpoints disponibles para Admin

Feature Método Endpoint Auth Admin Notas
Products GET GET /products/search No público, paginado
Products POST POST /products Crear producto
Products PATCH PATCH /products/:id Editar producto
Products GET GET /products/:id/variants No Variantes
Products GET GET /products/:id/images No Imágenes
Products POST POST /products/:id/images Subir imagen
Products DELETE DELETE /products/:id/images/:id Eliminar imagen
Products POST POST /products/:id/variants Crear variante
Products PATCH PATCH /products/:id/variants/:id Editar variante
Products PATCH PATCH /products/:id/rich-data Datos enriquecidos
Brands GET GET /brands No Listado público
Brands GET GET /marca/:slug No Detalle público
Brands POST POST /brands Crear marca
Brands PATCH PATCH /brands/:id Editar marca
Categories GET GET /categories/tree No Árbol categorías
Categories GET GET /categoria/:slug No Detalle público
Categories POST POST /categories Crear categoría
Categories PATCH PATCH /categories/:id Editar categoría
Categories DELETE DELETE /categories/:id Eliminar categoría
Orders GET GET /orders NUEVO — listado admin
Orders GET GET /orders/:id/admin NUEVO — detalle admin
Orders POST POST /orders/:id/transitions/admin NUEVO — transición
Orders GET GET /orders/:id Detalle cliente
Orders POST POST /orders/:id/transitions Transición cliente
Inventory GET GET /inventory/:variantId/availability No Disponibilidad
Inventory PUT PUT /inventory/:variantId/stock Ajustar stock
Inventory POST POST /inventory/:variantId/reservations No Reservas
Payments GET GET /payments/orders/:id/transactions Transacciones
Users GET GET /users Listado clientes
Users GET GET /users/:id Detalle cliente
Users PATCH PATCH /users/:id Editar cliente
Users GET GET /users/:id/addresses Direcciones
Users POST POST /users/:id/addresses Crear dirección
Users PATCH PATCH /users/:id/addresses/:id Editar dirección
Users DELETE DELETE /users/:id/addresses/:id Eliminar dirección
Promotions POST POST /promotions Crear promoción
Reviews GET GET /reviews?productId= No Reseñas publicadas
Reviews PATCH PATCH /reviews/:id/moderate Moderar reseña
CMS GET GET /cms/pages/:slug No Página pública
CMS POST POST /cms/pages Crear página
CMS PATCH PATCH /cms/pages/:id Editar página
CMS POST POST /cms/pages/:id/publish Publicar
CMS POST POST /cms/pages/:id/unpublish Despublicar
Shipping POST POST /shipping/zones Crear zona envío
Shipping POST POST /shipping/methods Crear método envío

2.2 Endpoints FALTANTES en el backend

# Capacidad requerida Endpoint necesario Prioridad
BD-01 Auth/me (sesión actual) GET /auth/me CRÍTICA
BD-02 Listar promociones GET /promotions ALTA
BD-03 Editar promoción PATCH /promotions/:id ALTA
BD-04 Eliminar promoción DELETE /promotions/:id MEDIA
BD-05 Listar reseñas (todas) GET /reviews/admin ALTA
BD-06 Actualizar producto estado PATCH /products/:id/state MEDIA
BD-07 Eliminar producto DELETE /products/:id MEDIA
BD-08 Eliminar marca DELETE /brands/:id MEDIA
BD-09 Bulk stock adjustment POST /inventory/bulk-adjust BAJA
BD-10 Audit log explorer GET /admin/audit MEDIA
BD-11 Dashboard stats GET /admin/stats MEDIA

2.3 Roles existentes en backend

type Role = 'customer' | 'admin';

Solo existen dos roles. No hay granularidad (Catalog Manager, Order Manager, etc).


3. Admin API Client Design

3.1 Cliente HTTP único

// apps/admin/lib/api-client.ts
class ApiClient {
  constructor(private baseUrl: string, private getToken: () => string | null) {}

  async request<T>(method, path, body?, opts?): Promise<T>
  async get<T>(path): Promise<T>
  async post<T>(path, body): Promise<T>
  async patch<T>(path, body): Promise<T>
  async delete<T>(path): Promise<T>
}

// Feature API adapters
// apps/admin/features/orders/api.ts
export const ordersApi = {
  list: (params) => client.get('/orders', params),
  get: (id) => client.get(`/orders/${id}/admin`),
  transition: (id, state) => client.post(`/orders/${id}/transitions/admin`, { state }),
};

3.2 Permisos

// apps/admin/lib/permissions.ts
type Permission =
  | 'products.read' | 'products.write' | 'products.delete'
  | 'orders.read' | 'orders.write'
  | 'inventory.read' | 'inventory.write'
  | 'customers.read' | 'customers.write'
  | 'categories.read' | 'categories.write' | 'categories.delete'
  | 'brands.read' | 'brands.write' | 'brands.delete'
  | 'promotions.read' | 'promotions.write'
  | 'reviews.read' | 'reviews.moderate'
  | 'cms.read' | 'cms.write';

export function can(user: User, permission: Permission): boolean {
  if (user.role === 'admin') return true;
  // Granular permissions would go here when backend supports them
  return false;
}

4. Arquitectura de rutas Admin

apps/admin/app/
├── (auth)/
│   └── login/
│       └── page.tsx
├── (dashboard)/
│   ├── layout.tsx                    # AdminShell: sidebar + header
│   ├── page.tsx                     # /admin — Dashboard
│   ├── products/
│   │   ├── page.tsx                 # /admin/products — Listado
│   │   └── [id]/
│   │       └── page.tsx             # /admin/products/[id] — Editor
│   ├── orders/
│   │   ├── page.tsx                 # /admin/orders — Listado
│   │   └── [id]/
│   │       └── page.tsx             # /admin/orders/[id] — Detalle
│   ├── customers/
│   │   ├── page.tsx                 # /admin/customers
│   │   └── [id]/
│   │       └── page.tsx
│   ├── categories/
│   │   └── page.tsx                 # /admin/categories
│   ├── brands/
│   │   └── page.tsx                 # /admin/brands
│   ├── inventory/
│   │   └── page.tsx                 # /admin/inventory
│   ├── promotions/
│   │   └── page.tsx                 # /admin/promotions
│   ├── reviews/
│   │   └── page.tsx                 # /admin/reviews
│   ├── cms/
│   │   └── page.tsx                 # /admin/cms
│   └── settings/
│       └── page.tsx                 # /admin/settings
└── api/
    └── auth/
        └── [...nextauth]/route.ts   # Auth handler

5. RBAC Matrix

Feature admin customer
Products R
Products W
Orders R own only
Orders W
Inventory R
Inventory W
Customers R
Customers W own only
Categories
Brands
Promotions
Reviews own only
CMS
Audit

6. MVP Scope

Priority 1 (crítico para operar la tienda)

  1. Auth — login, logout, sesión
  2. Admin Shell — sidebar, layout, permisos
  3. Products — listado, editor (nombre, precio, stock, imágenes, estado)
  4. Orders — listado, detalle, transiciones de estado
  5. Inventory — vista de stock, ajuste rápido

Priority 2 (operación normal)

  1. Customers — listado, detalle de cliente
  2. Categories — CRUD básico
  3. Brands — CRUD básico
  4. Dashboard — stats operativos

Priority 3 (mejora)

  1. Promotions — CRUD
  2. Reviews — moderación
  3. CMS — gestión de páginas
  4. Audit log

7. Backend Dependencies (BD-01 a BD-11)

Ver sección 2.2. Cada una es un ticket de backend separado.


8. Parallelization Plan

FASE 1 — Foundation (sequencial)
│
├── ADM-001: Nuevo proyecto Next.js en apps/admin
├── ADM-002: API Client + types
├── ADM-003: Auth (BD-01 + login page)
│
FASE 2 — Admin Shell (sequencial)
│
├── ADM-004: Admin layout (sidebar, header, permisos nav)
│
FASE 3 — MVP Features (paralelo)
│
├── Stream A: Products (ADM-005 a ADM-012)
├── Stream B: Orders (ADM-013 a ADM-019)
└── Stream C: Inventory (ADM-020 a ADM-022)

FASE 4 — Secondary Features (paralelo)
│
├── Stream D: Customers (ADM-023 a ADM-025)
├── Stream E: Categories + Brands (ADM-026 a ADM-030)
└── Stream F: Dashboard (ADM-031)

FASE 5 — Extensions (paralelo)
│
├── Stream G: Promotions (BD-02, BD-03 + ADM-032 a ADM-034)
├── Stream H: Reviews (BD-05 + ADM-035 a ADM-037)
└── Stream I: CMS (ADM-038 a ADM-040)

9. Risk Assessment

Riesgo Severidad Mitigación
No existe GET /auth/me CRÍTICA BD-01 debe implementarse antes de cualquier código de admin
Promotions sin listado ALTA BD-02 debe existir para tener UI de promociones
Reviews sin listado admin ALTA BD-05 debe existir para moderación
Sin granularidad de roles MEDIA Trabajar con 'admin' vs 'customer' en frontend; backend no valida permisos finos
Concurrencia de inventario MEDIA Siempre esperar respuesta del backend antes de mostrar nuevo stock
Estado de orden inválido MEDIA Backend valida transiciones; UI solo muestra acciones permitidas
Bulk operations BAJA No implementar sin endpoint de backend dedicado (BD-09)