You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
6.3 KiB

Nexo desktop-first redesign + demo restructure Move servers/dating → demos/dating/server and the dating route's co-located _components/_lib/_design assets → demos/dating/web. Single `npm run dating:dev` boots both server and web via concurrently. Replace the warm-paper / raspberry-pink Claude Design adaptation with a sober desktop-first system: - Tokens: slate neutrals + violet accent, Inter family, dark mode via prefers-color-scheme + explicit data-theme. - Inline SVG icon set (Icon.svelte, Feather-style) — no Unicode glyph placeholders. - Layout shell: 240px rail nav on desktop, bottom tab bar on mobile; auth + onboarding own their own shell. - Discover: square photo carousel (dots + chevrons), name/age/location overlay, action buttons floating off the photo edge, sticky context panel on desktop. - Matches: clean conversation list with unread dot + chevron-on-hover. - Chat: 3-column on desktop (threads + thread + match context), 2-col on tablet, single thread on mobile. Day separators, retry/dismiss on failed messages, autogrow composer with Enter-to-send. - Profile: sticky hero card + 3-section form, dirty/saved indicator. - Photos: dropzone + grid with hover-only cell toolbar (set primary, reorder, delete). - Onboarding: sidebar stepper (320px) + content panel. - Auth: split layout (form left, brand quote right) on ≥900px. Server boot: env loader's repo-root resolution corrected after the move (../../.. instead of ../..) so .env.local at the repo root is picked up again. Hoist BRAND.md and SECURITY.md into docs/, drop superseded audit notes that were already closed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
# Requisitos de Nexo
## Roles
### Visitante
Usuario no autenticado.
Puede:
- ver la pantalla de entrada;
- registrarse;
- iniciar sesion;
- recuperar acceso;
- cambiar idioma/tema local antes de autenticar.
No puede:
- ver perfiles;
- enviar likes;
- abrir chats;
- acceder a safety center autenticado;
- acceder a moderacion.
### Usuario
Usuario autenticado con perfil activo.
Puede:
- completar onboarding;
- editar perfil;
- configurar preferencias de descubrimiento;
- ver perfiles compatibles;
- hacer like/pass;
- chatear con matches;
- bloquear y reportar perfiles;
- gestionar sesion y privacidad.
### Usuario limitado
Usuario autenticado con restriccion temporal por moderacion.
Puede:
- ver su perfil;
- gestionar seguridad;
- leer decisiones de moderacion;
- apelar si se implementa el flujo.
No puede:
- enviar likes;
- iniciar conversaciones nuevas;
- aparecer en discover;
- editar campos sensibles si la sancion lo impide.
### Moderador
Usuario con permisos de moderacion.
Puede:
- ver reportes;
- revisar contexto limitado;
- ocultar perfiles;
- imponer restricciones;
- resolver reportes;
- dejar notas auditadas.
### Admin
Usuario con permisos de administracion.
Puede:
- gestionar roles;
- revisar auditoria;
- cambiar flags de la demo;
- resetear seeds locales;
- abrir devtools completos.
## Requisitos funcionales
### Autenticacion
- Pagina `/dating/login` con email, password, recordarme, errores y redireccion.
- Pagina `/dating/register` con email, password, confirmacion, nombre visible inicial y confirmacion de edad adulta.
- Pagina `/dating/reset` para recuperacion simulada sin revelar si el email existe.
- Pagina `/dating/mfa` para challenge MFA simulado.
- Logout desde menu de sesion.
- Sesion persistente.
- Expiracion de sesion y refresh.
- Lista de dispositivos/sesiones activas.
### Onboarding
- Flujo por pasos.
- Validacion por schema `sium`.
- Draft persistente en `storage`.
- Progreso recuperable tras reload.
- Campos minimos:
- nombre visible;
- edad adulta validada;
- bio;
- intereses;
- intencion;
- ubicacion aproximada;
- preferencias de descubrimiento;
- visibilidad del perfil.
### Perfil
- Editar datos publicos.
- Subir fotos de perfil a PocketBase desde `/dating/profile/photos`.
- Gestionar hasta 6 fotos por perfil.
- Reordenar fotos y marcar foto principal.
- Eliminar o reemplazar fotos.
- Validar tipo, tamano y permisos antes de subir.
- Configurar privacidad.
- Configurar idioma, tema, densidad y notificaciones.
- Ver preview publico del perfil.
- Validar cambios antes de guardar.
### Discover
- Mostrar perfiles compatibles.
- Filtros por rango de edad, distancia aproximada, intereses e intencion.
- Acciones like/pass.
- Estados empty/loading/error/offline.
- Cache de feed.
- Invalidacion tras like/pass.
- Paginacion o carga incremental.
### Matching
- Crear match cuando hay like mutuo.
- Mostrar matches activos, pending, archivados y expirados.
- Expirar matches pendientes mediante `timer`.
- Emitir eventos de match por `bus`.
- Orquestar notificacion y cache invalidation con `orca`.
### Chat
- Chat por match.
- Envio online.
- Envio offline con cola local.
- Retry al reconectar.
- Estado de mensaje: pending, sent, delivered, failed.
- Typing indicator simulado.
- Presence simulada.
- Bloqueo corta envio/recepcion.
### Safety
- Bloquear usuario.
- Reportar perfil o mensaje.
- Seleccionar motivo.
- Adjuntar contexto fake.
- Confirmacion clara.
- Ocultar perfil reportado/bloqueado.
- Exportacion simulada de datos.
- Borrado de cuenta simulado.
### Moderacion
- Bandeja de reportes.
- Filtros por estado, motivo y prioridad.
- Vista de detalle con contexto minimo.
- Acciones: dismiss, warn, restrict, hide profile, ban demo user.
- Notas auditadas.
- Decision visible en audit log.
- Permisos estrictos con `perm`.
### Devtools internos
- Estado de `active-app`.
- Servicios activos/lazy/disposed.
- Eventos de `bus`.
- Logs de `logger`.
- Cache entries.
- Storage namespaces.
- Session state.
- Perm checks recientes.
- Connection state.
- Orca traces.
- Timers activos.
## Requisitos no funcionales
- La demo debe funcionar en local sin servicios externos reales.
- Debe tener seed determinista.
- Debe ser testeable con datos estables.
- Debe responder bien en desktop y movil.
- Debe tener estados accesibles para teclado y lector de pantalla.
- Debe evitar datos sensibles reales.
- Debe poder resetearse entre tests.
- Debe evitar coupling entre rutas y componentes publicos.
- Debe trazar errores sin exponer secretos.
## Modelo de datos minimo
### User
- `id`
- `email`
- `role`
- `status`
- `createdAt`
- `lastLoginAt`
### Profile
- `id`
- `userId`
- `displayName`
- `age`
- `bio`
- `interests`
- `intent`
- `approxLocation`
- `visibility`
- `photos`
- `primaryPhoto`
### Preference
- `userId`
- `ageRange`
- `distanceKm`
- `intent`
- `interests`
- `theme`
- `density`
- `locale`
- `notifications`
### Like
- `fromUserId`
- `toUserId`
- `state`
- `createdAt`
### Match
- `id`
- `userIds`
- `state`
- `createdAt`
- `expiresAt`
### Message
- `id`
- `matchId`
- `senderId`
- `body`
- `state`
- `createdAt`
- `clientNonce`
### Report
- `id`
- `reporterId`
- `targetUserId`
- `targetMessageId`
- `reason`
- `details`
- `state`
- `priority`
- `createdAt`
- `resolvedAt`
- `resolverId`
## Matriz de permisos inicial
| Accion | Visitante | Usuario | Limitado | Moderador | Admin |
| --- | --- | --- | --- | --- | --- |
| `profile:create` | no | si | si | si | si |
| `profile:update:self` | no | si | parcial | si | si |
| `profile:photo:add` | no | si | no | si | si |
| `profile:photo:delete:self` | no | si | parcial | si | si |
| `profile:photo:reorder` | no | si | no | si | si |
| `profile:photo:moderate` | no | no | no | si | si |
| `discover:view` | no | si | no | si | si |
| `match:like` | no | si | no | no | si |
| `chat:send` | no | si | no | no | si |
| `safety:block` | no | si | si | si | si |
| `safety:report` | no | si | si | si | si |
| `moderation:view` | no | no | no | si | si |
| `moderation:resolve` | no | no | no | si | si |
| `admin:roles` | no | no | no | no | si |
| `devtools:view` | no | limitado | limitado | si | si |
## Estados de error obligatorios
- Sesion expirada.
- Usuario sin permiso.
- Perfil incompleto.
- Feed sin resultados.
- Cache stale.
- Red offline.
- Reconnect en curso.
- Mensaje pendiente.
- Envio fallido.
- Reporte ya resuelto.
- Usuario bloqueado.
- Servicio lazy fallido.

Powered by TurnKey Linux.