# 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-001–F-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 build` → `dist/` - 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 ```typescript 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 ```typescript // apps/admin/lib/api-client.ts class ApiClient { constructor(private baseUrl: string, private getToken: () => string | null) {} async request(method, path, body?, opts?): Promise async get(path): Promise async post(path, body): Promise async patch(path, body): Promise async delete(path): Promise } // 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 ```typescript // 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) 6. Customers — listado, detalle de cliente 7. Categories — CRUD básico 8. Brands — CRUD básico 9. Dashboard — stats operativos ### Priority 3 (mejora) 10. Promotions — CRUD 11. Reviews — moderación 12. CMS — gestión de páginas 13. 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) |