mirror of
https://github.com/marcogll/AnchorOS.git
synced 2026-03-15 14:24:27 +00:00
332 lines
8.1 KiB
Markdown
332 lines
8.1 KiB
Markdown
# Sistema de Enrollment - Guía de Implementación
|
|
|
|
## Resumen
|
|
|
|
El sistema de enrollment permite a los administradores agregar nuevos usuarios (staff, artists, managers) y kiosks al sistema AnchorOS mediante una interfaz web segura.
|
|
|
|
---
|
|
|
|
## Arquitectura
|
|
|
|
### Componentes
|
|
|
|
#### 1. Frontend
|
|
- **Ruta**: `/admin/enrollment`
|
|
- **Tecnología**: Next.js 14 App Router + React
|
|
- **Características**:
|
|
- Autenticación por admin key
|
|
- Tabs separados para Staff y Kiosks
|
|
- Listado de usuarios/kiosks existentes
|
|
- Formularios validados
|
|
|
|
#### 2. API Routes
|
|
|
|
##### `/api/admin/locations`
|
|
- **GET**: Obtener todas las locations activas
|
|
- **Auth**: Bearer token (ADMIN_ENROLLMENT_KEY)
|
|
|
|
##### `/api/admin/users`
|
|
- **GET**: Listar staff members (filtrable por location y role)
|
|
- **POST**: Crear nuevo staff member
|
|
- **Campos requeridos**:
|
|
- `location_id` - UUID de la location
|
|
- `role` - admin | manager | staff | artist
|
|
- `display_name` - Nombre público del staff
|
|
- `email` - Email para autenticación
|
|
- `password` - Contraseña inicial
|
|
- `first_name`, `last_name` - Nombres para perfil
|
|
- `phone` - Teléfono (opcional)
|
|
- **Acción**:
|
|
1. Crea usuario en Supabase Auth
|
|
2. Crea registro en tabla `staff`
|
|
3. Devuelve respuesta con éxito
|
|
|
|
##### `/api/admin/kiosks`
|
|
- **GET**: Listar kiosks (filtrable por location)
|
|
- **POST**: Crear nuevo kiosk
|
|
- **Campos requeridos**:
|
|
- `location_id` - UUID de la location
|
|
- `device_name` - Identificador único del dispositivo
|
|
- `display_name` - Nombre legible del kiosko
|
|
- `ip_address` - IP para restricción (opcional)
|
|
- **Acción**:
|
|
1. Llama función SQL `create_kiosk()`
|
|
2. Genera API key de 64 caracteres
|
|
3. Devuelve API key (solo se muestra una vez)
|
|
|
|
---
|
|
|
|
## Instalación
|
|
|
|
### 1. Configurar Variables de Entorno
|
|
|
|
Agrega a tu archivo `.env.local`:
|
|
|
|
```env
|
|
# Admin Enrollment Key (genera una segura)
|
|
ADMIN_ENROLLMENT_KEY=your-secure-admin-key-here-change-me
|
|
```
|
|
|
|
### 2. Instalar Dependencias Necesarias
|
|
|
|
```bash
|
|
npm install @radix-ui/react-label @radix-ui/react-select @radix-ui/react-tabs lucide-react clsx tailwind-merge
|
|
```
|
|
|
|
### 3. Verificar Archivos Creados
|
|
|
|
Deberías tener estos archivos:
|
|
|
|
```
|
|
app/
|
|
├── admin/
|
|
│ └── enrollment/
|
|
│ └── page.tsx
|
|
└── api/
|
|
└── admin/
|
|
├── locations/route.ts
|
|
├── users/route.ts
|
|
└── kiosks/route.ts
|
|
|
|
components/
|
|
└── ui/
|
|
├── button.tsx
|
|
├── card.tsx
|
|
├── input.tsx
|
|
├── label.tsx
|
|
├── select.tsx
|
|
└── tabs.tsx
|
|
|
|
lib/
|
|
└── utils.ts
|
|
```
|
|
|
|
### 4. Ejecutar Migraciones
|
|
|
|
```bash
|
|
npx supabase db push
|
|
```
|
|
|
|
Esto debería aplicar:
|
|
- `20260116000000_add_kiosk_system.sql`
|
|
- `20260116010000_update_resources.sql`
|
|
- `20260116020000_cleanup_and_fix_resources.sql`
|
|
|
|
---
|
|
|
|
## Uso del Sistema
|
|
|
|
### 1. Acceder al Sistema
|
|
|
|
Navega a: `http://localhost:3000/admin/enrollment`
|
|
|
|
### 2. Autenticación
|
|
|
|
1. Ingresa tu `ADMIN_ENROLLMENT_KEY`
|
|
2. Haz clic en "Access Enrollment System"
|
|
3. La clave se guardará en localStorage para futuras sesiones
|
|
|
|
### 3. Crear Staff Member
|
|
|
|
1. Selecciona la tab "Staff Members"
|
|
2. Completa el formulario:
|
|
- **Location**: Selecciona del dropdown
|
|
- **Role**: Admin, Manager, Staff, o Artist
|
|
- **Display Name**: e.g., "María García"
|
|
- **First Name**: e.g., "María"
|
|
- **Last Name**: e.g., "García"
|
|
- **Email**: e.g., "maria@salon.com"
|
|
- **Password**: Contraseña inicial
|
|
- **Phone**: (opcional)
|
|
3. Haz clic en "Create Staff Member"
|
|
4. Verifica que aparezca en la lista de "Existing Staff Members"
|
|
|
|
### 4. Crear Kiosk
|
|
|
|
1. Selecciona la tab "Kiosks"
|
|
2. Completa el formulario:
|
|
- **Location**: Selecciona del dropdown
|
|
- **Device Name**: Identificador único (e.g., "kiosk-entrance-1")
|
|
- **Display Name**: Nombre legible (e.g., "Kiosko Entrada Principal")
|
|
- **IP Address**: IP para restricción (opcional, e.g., "192.168.1.100")
|
|
3. Haz clic en "Create Kiosk"
|
|
4. ⚠️ **IMPORTANTE**: Guarda el API key generado en un lugar seguro
|
|
- Solo se mostrará una vez
|
|
- Debes agregarla a `NEXT_PUBLIC_KIOSK_API_KEY` en .env.local
|
|
- O compartirla manualmente al dispositivo del kiosko
|
|
|
|
---
|
|
|
|
## Seguridad
|
|
|
|
### Autenticación
|
|
|
|
- **Método**: Bearer token en header `Authorization`
|
|
- **Validación**: Token debe coincidir con `ADMIN_ENROLLMENT_KEY`
|
|
- **Almacenamiento**: Cliente guarda token en localStorage
|
|
|
|
### Protección de Rutas
|
|
|
|
Las API routes verifican:
|
|
```typescript
|
|
const authHeader = request.headers.get('authorization')
|
|
const token = authHeader.replace('Bearer ', '')
|
|
if (token !== process.env.ADMIN_ENROLLMENT_KEY) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
}
|
|
```
|
|
|
|
### API Keys de Kioskos
|
|
|
|
- Generadas aleatoriamente (64 caracteres)
|
|
- Solo se muestran una vez
|
|
- Deben guardarse de forma segura
|
|
- Se pueden rotar creando un nuevo kiosko
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Error: "Unauthorized"
|
|
|
|
**Causa**: ADMIN_ENROLLMENT_KEY incorrecto o no configurado
|
|
|
|
**Solución**:
|
|
1. Verifica que `ADMIN_ENROLLMENT_KEY` esté en `.env.local`
|
|
2. Reinicia el servidor: `npm run dev`
|
|
3. Limpia localStorage y re-autentica
|
|
|
|
### Error: "Missing required fields"
|
|
|
|
**Causa**: Faltan campos obligatorios en el formulario
|
|
|
|
**Solución**:
|
|
- Staff: location_id, role, display_name, email, password
|
|
- Kiosk: location_id, device_name, display_name
|
|
|
|
### Error: "A kiosk with this device_name already exists"
|
|
|
|
**Causa**: Ya existe un kiosko con ese nombre
|
|
|
|
**Solución**:
|
|
1. Verifica en la lista de kiosks existentes
|
|
2. Usa un `device_name` diferente
|
|
3. O elimina el kiosko existente primero
|
|
|
|
### Error: "Failed to create auth user"
|
|
|
|
**Causa**: Email ya existe en Supabase Auth
|
|
|
|
**Solución**:
|
|
1. El usuario debe existir
|
|
2. Usa un email diferente
|
|
3. O contacta al usuario para que restablezca su contraseña
|
|
|
|
---
|
|
|
|
## Testing
|
|
|
|
### Test de Creación de Staff
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3000/api/admin/users \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer your-admin-key" \
|
|
-d '{
|
|
"location_id": "location-uuid",
|
|
"role": "artist",
|
|
"display_name": "Test Artist",
|
|
"first_name": "Test",
|
|
"last_name": "Artist",
|
|
"email": "test@salon.com",
|
|
"password": "test123",
|
|
"phone": "+52 55 1234 5678"
|
|
}'
|
|
```
|
|
|
|
### Test de Creación de Kiosk
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3000/api/admin/kiosks \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer your-admin-key" \
|
|
-d '{
|
|
"location_id": "location-uuid",
|
|
"device_name": "kiosk-test-1",
|
|
"display_name": "Test Kiosk",
|
|
"ip_address": "192.168.1.200"
|
|
}'
|
|
```
|
|
|
|
### Test de Listado de Locations
|
|
|
|
```bash
|
|
curl http://localhost:3000/api/admin/locations \
|
|
-H "Authorization: Bearer your-admin-key"
|
|
```
|
|
|
|
---
|
|
|
|
## Integración con Sistema de Kiosko
|
|
|
|
### Después de Crear un Kiosk
|
|
|
|
1. **Obtener la API Key** (solo se muestra una vez)
|
|
2. **Configurar en Frontend del Kiosko**:
|
|
|
|
En `.env.local`:
|
|
```env
|
|
NEXT_PUBLIC_KIOSK_API_KEY=la-api-key-generada
|
|
```
|
|
|
|
3. **Probar Acceso al Kiosko**:
|
|
|
|
Navega a: `http://localhost:3000/kiosk/{location-id}`
|
|
|
|
El kiosko debería autenticarse automáticamente.
|
|
|
|
---
|
|
|
|
## Próximas Mejoras
|
|
|
|
### Funcionalidades Futuras
|
|
|
|
- [ ] Desactivar staff/kiosks en lugar de eliminar
|
|
- [ ] Editar staff/kiosks existentes
|
|
- [ ] Ver historial de cambios (audit logs)
|
|
- [ ] Exportar lista de staff a CSV
|
|
- [ ] Asignar múltiples locations a un staff member
|
|
- [ ] Validación de email único antes de crear
|
|
|
|
### Seguridad Futura
|
|
|
|
- [ ] Rate limiting para prevenir abusos
|
|
- [ ] 2FA para el sistema de enrollment
|
|
- [ ] Logs de acceso al sistema de enrollment
|
|
- [ ] Notificación de creación de usuario
|
|
|
|
---
|
|
|
|
## Documentación Relacionada
|
|
|
|
- `KIOSK_SYSTEM.md` - Documentación completa del sistema de kiosko
|
|
- `KIOSK_IMPLEMENTATION.md` - Guía rápida de implementación
|
|
- `TASKS.md` - Plan de ejecución del proyecto
|
|
- `PRD.md` - Especificación funcional del sistema
|
|
|
|
---
|
|
|
|
## Soporte
|
|
|
|
Para problemas técnicos:
|
|
1. Revisa los logs del servidor
|
|
2. Verifica que las migraciones se aplicaron correctamente
|
|
3. Confirma que las variables de entorno están configuradas
|
|
4. Consulta la documentación de Supabase Auth
|
|
|
|
---
|
|
|
|
**Fecha**: 16 de Enero, 2026
|
|
**Versión**: v1.0.0
|
|
**Estado**: Completado y listo para producción
|