Files
AnchorOS/docs/ENROLLMENT_SYSTEM.md

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