feat(ADM-018): completed feature

This commit is contained in:
chattie
2026-08-17 22:23:10 +02:00
parent cf1c69fc8b
commit d595b4871f
871 changed files with 47411 additions and 281 deletions

342
project/specs-admin/SPEC.md Normal file
View File

@@ -0,0 +1,342 @@
# 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 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<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
```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) |