workspace/projects/gamilit/docs/01-fase-alcance-inicial/EAI-001-fundamentos/historias-usuario/US-FUND-002-perfiles-usuario-basicos.md
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

10 KiB
Raw Blame History

US-FUND-002: Perfiles de usuario básicos

Épica: EAI-001 - Fundamentos Sprint: Mes 1, Semana 1-2 Story Points: 5 SP Presupuesto: $1,800 MXN Prioridad: Alta (Alcance Inicial) Estado: Completada (Mes 1)


Descripción

Como usuario registrado, quiero ver y editar mi perfil básico para mantener mi información actualizada en la plataforma.

Contexto del Alcance Inicial: El MVP incluye perfiles de usuario muy básicos con información esencial (nombre, email, foto). No incluye personalización avanzada como preferencias de gamificación, estadísticas detalladas o configuraciones de privacidad, que se agregarán en extensiones futuras.


Criterios de Aceptación

  • CA-01: El usuario puede ver su perfil con: nombre completo, email, rol, foto de perfil
  • CA-02: El usuario puede editar: firstName, lastName, foto de perfil
  • CA-03: El email NO es editable (requeriría re-verificación)
  • CA-04: La foto de perfil puede subirse (max 5MB, formatos: jpg, png, webp)
  • CA-05: Si no hay foto, se muestra avatar por defecto (iniciales del nombre)
  • CA-06: Los cambios se guardan en la base de datos
  • CA-07: Se muestra mensaje de confirmación al guardar cambios
  • CA-08: Se valida que firstName y lastName no estén vacíos
  • CA-09: La foto se redimensiona automáticamente a 200x200px

Especificaciones Técnicas

Backend (NestJS)

Endpoints:

GET /api/users/profile
- Headers: Authorization: Bearer {token}
- Response: { user: { id, email, firstName, lastName, role, photoUrl, createdAt } }

PATCH /api/users/profile
- Headers: Authorization: Bearer {token}
- Body: { firstName?, lastName? }
- Response: { user: { ... } }

POST /api/users/profile/photo
- Headers: Authorization: Bearer {token}, Content-Type: multipart/form-data
- Body: FormData with 'photo' file
- Response: { photoUrl: string }

DELETE /api/users/profile/photo
- Headers: Authorization: Bearer {token}
- Response: { message: "Photo deleted" }

Servicios:

  • UsersService: CRUD de usuarios
  • FileUploadService: Manejo de uploads de imágenes
  • ImageProcessingService: Redimensionamiento de imágenes

Entidades:

@Entity('users')
class User {
  // ... campos de US-FUND-001
  photoUrl?: string
  photoKey?: string // Para S3 o storage local
}

Validaciones:

  • DTOs con class-validator
  • File upload: max size 5MB, tipos permitidos
  • Sanitización de nombres (trim, evitar caracteres especiales)

Frontend (React + Vite)

Componentes:

- ProfileView.tsx: Vista de perfil (solo lectura)
- ProfileEditForm.tsx: Formulario de edición
- PhotoUpload.tsx: Componente de upload de foto
- AvatarPlaceholder.tsx: Avatar con iniciales

Rutas:

  • /profile - Vista de perfil
  • /profile/edit - Editar perfil

Estado (Zustand):

interface ProfileStore {
  profile: User | null
  loading: boolean
  fetchProfile: () => Promise<void>
  updateProfile: (data: Partial<User>) => Promise<void>
  uploadPhoto: (file: File) => Promise<void>
  deletePhoto: () => Promise<void>
}

UI/UX:

  • Card con información del usuario
  • Botón "Editar perfil"
  • Upload drag-and-drop para foto
  • Preview de foto antes de guardar
  • Loading states durante operaciones

Almacenamiento de Archivos

Opción Inicial (Alcance MVP):

  • Archivos guardados localmente en /uploads/profile-photos/
  • Nombres generados con UUID para evitar colisiones
  • Public URL: /static/profile-photos/{photoKey}

Opción Futura:

  • Migración a AWS S3 o similar (EXT-Infrastructure)

Dependencias

Antes:

  • US-FUND-001 (Autenticación - requiere usuario autenticado)

Después:

  • US-FUND-003 (Dashboard - muestra foto de perfil)
  • Múltiples historias usan la foto de perfil del usuario

Definición de Hecho (DoD)

  • Endpoints implementados y documentados
  • Validaciones en backend
  • Upload de archivos funcional
  • Redimensionamiento de imágenes
  • Componentes de frontend implementados
  • Tests unitarios (>80% coverage)
  • Tests E2E para edición de perfil
  • Responsive design
  • Manejo de errores (file too large, invalid format)

Notas del Alcance Inicial

  • Solo campos básicos: nombre, foto
  • Sin estadísticas de usuario en perfil
  • Sin configuraciones avanzadas (tema, notificaciones)
  • Sin campo "bio" o "descripción"
  • Sin badges o insignias en perfil (se muestran en dashboard)
  • Storage local (no S3)
  • ⚠️ Extensión futura: EXT-003-Profiles (bio, social links, preferencias)
  • ⚠️ Extensión futura: EXT-004-Infrastructure (migrar a S3)

Tareas de Implementación

Backend (Estimado: 10h, Real: 10.5h)

Total Backend: 10.5h (~2.6 SP)

  • Tarea B.1: Endpoints de perfil - Estimado: 4h, Real: 4h

    • Subtarea B.1.1: GET /users/profile con JWT guard - 1h
    • Subtarea B.1.2: PATCH /users/profile con validación de DTO - 1.5h
    • Subtarea B.1.3: Prevenir edición de email con validación - 0.5h
    • Subtarea B.1.4: Documentación Swagger de endpoints - 1h
  • Tarea B.2: Sistema de upload de archivos - Estimado: 4h, Real: 4.5h

    • Subtarea B.2.1: Configurar Multer para file upload - 1h
    • Subtarea B.2.2: POST /users/profile/photo con validación (5MB, jpg/png/webp) - 1.5h
    • Subtarea B.2.3: DELETE /users/profile/photo - 0.5h
    • Subtarea B.2.4: FileUploadService con generación de nombres únicos - 1h
    • Subtarea B.2.5: Configuración de carpeta /uploads/profile-photos/ - 0.5h
  • Tarea B.3: Procesamiento de imágenes - Estimado: 2h, Real: 2h

    • Subtarea B.3.1: Instalar y configurar Sharp - 0.5h
    • Subtarea B.3.2: ImageProcessingService con redimensionamiento a 200x200 - 1h
    • Subtarea B.3.3: Mantener aspect ratio y optimización de calidad - 0.5h

Frontend (Estimado: 6h, Real: 6.5h)

Total Frontend: 6.5h (~1.6 SP)

  • Tarea F.1: Componentes de perfil - Estimado: 4h, Real: 4.5h

    • Subtarea F.1.1: Componente ProfileView (vista de solo lectura) - 1h
    • Subtarea F.1.2: Componente ProfileEditForm con validación - 1.5h
    • Subtarea F.1.3: Componente AvatarPlaceholder con iniciales - 0.5h
    • Subtarea F.1.4: Páginas /profile y /profile/edit - 1h
    • Subtarea F.1.5: Navegación entre vista y edición - 0.5h
  • Tarea F.2: Upload de foto de perfil - Estimado: 2h, Real: 2h

    • Subtarea F.2.1: Componente PhotoUpload con drag & drop (react-dropzone) - 1h
    • Subtarea F.2.2: Preview de imagen antes de guardar - 0.5h
    • Subtarea F.2.3: ProfileStore en Zustand con métodos upload/delete - 0.5h

Testing (Estimado: 3h, Real: 2.5h)

Total Testing: 2.5h (~0.6 SP)

  • Tarea T.1: Tests unitarios backend - Estimado: 1.5h, Real: 1h

    • Subtarea T.1.1: Tests de UsersService (fetch, update) - 0.5h
    • Subtarea T.1.2: Tests de FileUploadService (validación tamaño/tipo) - 0.25h
    • Subtarea T.1.3: Tests de ImageProcessingService (resize) - 0.25h
  • Tarea T.2: Tests E2E - Estimado: 1h, Real: 1h

    • Subtarea T.2.1: Tests de endpoints GET/PATCH profile - 0.5h
    • Subtarea T.2.2: Tests de upload de foto (success y errores) - 0.5h
  • Tarea T.3: Tests frontend - Estimado: 0.5h, Real: 0.5h

    • Subtarea T.3.1: Tests de ProfileEditForm - 0.25h
    • Subtarea T.3.2: Tests de PhotoUpload - 0.25h

Deployment (Estimado: 1h, Real: 0.5h)

Total Deployment: 0.5h (~0.1 SP)

  • Tarea D.1: Configuración de storage - Estimado: 0.5h, Real: 0.25h

    • Subtarea D.1.1: Crear directorio /uploads en servidor - 0.1h
    • Subtarea D.1.2: Configurar permisos de escritura - 0.15h
  • Tarea D.2: Deploy y validación - Estimado: 0.5h, Real: 0.25h

    • Subtarea D.2.1: Deploy a staging - 0.15h
    • Subtarea D.2.2: Smoke tests de upload de foto - 0.1h

Resumen de Horas

Categoría Estimado Real Variación
Backend 10h 10.5h +5%
Frontend 6h 6.5h +8.3%
Testing 3h 2.5h -16.7%
Deployment 1h 0.5h -50%
TOTAL 20h 20h 0%

Validación: 5 SP × 4h/SP = 20 horas estimadas


Cronograma Real

Sprint: Sprint 1-2 (05-16 Agosto 2024) Fecha Inicio Real: 07 Agosto 2024 Fecha Fin Real: 09 Agosto 2024 Estado: Completada Notas: La implementación se completó en tiempo gracias a la reutilización de componentes de UI base. El sistema de upload con Sharp funcionó perfectamente. Los tiempos de testing fueron menores debido a la simplicidad del CRUD.


Testing

Tests Unitarios

describe('UsersService', () => {
  it('should fetch user profile')
  it('should update firstName and lastName')
  it('should not update email')
  it('should handle photo upload')
  it('should delete photo and revert to default')
})

describe('FileUploadService', () => {
  it('should validate file size')
  it('should validate file type')
  it('should generate unique filename')
})

describe('ImageProcessingService', () => {
  it('should resize image to 200x200')
  it('should maintain aspect ratio')
})

Tests E2E

describe('Profile API', () => {
  it('GET /users/profile - returns user data')
  it('PATCH /users/profile - updates fields')
  it('PATCH /users/profile - rejects email change')
  it('POST /users/profile/photo - uploads photo')
  it('POST /users/profile/photo - rejects large files')
  it('DELETE /users/profile/photo - removes photo')
})

Tests Frontend

describe('ProfileEditForm', () => {
  it('renders current user data')
  it('submits updated data on save')
  it('shows validation errors')
  it('handles photo upload')
  it('previews photo before upload')
})

Estimación

Desglose de Esfuerzo (5 SP = ~2 días):

  • Backend endpoints + validations: 0.5 días
  • File upload + processing: 0.75 días
  • Frontend components: 0.5 días
  • Photo upload UI: 0.5 días
  • Testing: 0.5 días
  • Ajustes: 0.25 días

Riesgos:

  • File upload puede tener edge cases (conexión lenta, archivos corruptos)
  • Redimensionamiento de imágenes puede requerir librería adicional

Recursos Externos

Librerías:

  • Backend: multer (file upload), sharp (image processing)
  • Frontend: react-dropzone (drag & drop upload)

Creado: 2025-11-02 Actualizado: 2025-11-02 Responsable: Equipo Fullstack