696 lines
22 KiB
YAML
696 lines
22 KiB
YAML
# TRACEABILITY.yml - MGN-001: Autenticacion
|
|
# Matriz de trazabilidad: Documentacion -> Codigo
|
|
# Ubicacion: docs/01-fase-foundation/MGN-001-auth/implementacion/
|
|
|
|
epic_code: MGN-001
|
|
epic_name: Autenticacion
|
|
phase: 1
|
|
phase_name: Foundation
|
|
story_points: 40
|
|
status: documented
|
|
|
|
# =============================================================================
|
|
# DOCUMENTACION
|
|
# =============================================================================
|
|
|
|
documentation:
|
|
|
|
requirements:
|
|
- id: RF-AUTH-001
|
|
file: ../requerimientos/RF-AUTH-001.md
|
|
title: Login con Email/Password
|
|
priority: P0
|
|
status: migrated
|
|
description: |
|
|
El sistema debe permitir autenticacion mediante email y password.
|
|
Incluye validacion de credenciales, generacion de tokens y registro de sesion.
|
|
|
|
- id: RF-AUTH-002
|
|
file: ../requerimientos/RF-AUTH-002.md
|
|
title: Manejo de Tokens JWT
|
|
priority: P0
|
|
status: migrated
|
|
description: |
|
|
Gestion de access tokens y refresh tokens JWT.
|
|
Incluye generacion, validacion, refresh y revocacion.
|
|
|
|
- id: RF-AUTH-003
|
|
file: ../requerimientos/RF-AUTH-003.md
|
|
title: Recuperacion de Password
|
|
priority: P1
|
|
status: migrated
|
|
description: |
|
|
Flujo de recuperacion de password via email.
|
|
Incluye generacion de token, envio de email y reset.
|
|
|
|
- id: RF-AUTH-004
|
|
file: ../requerimientos/RF-AUTH-004.md
|
|
title: Proteccion Brute Force
|
|
priority: P1
|
|
status: migrated
|
|
description: |
|
|
Proteccion contra ataques de fuerza bruta.
|
|
Rate limiting por IP y por email, bloqueo temporal.
|
|
|
|
- id: RF-AUTH-005
|
|
file: ../requerimientos/RF-AUTH-005.md
|
|
title: OAuth Social Login
|
|
priority: P2
|
|
status: migrated
|
|
description: |
|
|
Login con proveedores OAuth (Google, Microsoft).
|
|
Vinculacion de cuentas sociales a cuenta local.
|
|
|
|
- id: RF-AUTH-006
|
|
file: ../requerimientos/RF-AUTH-005.md
|
|
title: Logout y Revocacion (incluido en RF-AUTH-005)
|
|
priority: P0
|
|
status: migrated
|
|
description: |
|
|
Cierre de sesion y revocacion de tokens.
|
|
Logout de dispositivo actual o de todos los dispositivos.
|
|
|
|
specifications:
|
|
- id: ET-AUTH-001
|
|
file: ../especificaciones/ET-auth-backend.md
|
|
title: Backend Authentication
|
|
rf: [RF-AUTH-001, RF-AUTH-002, RF-AUTH-005]
|
|
status: migrated
|
|
components:
|
|
- AuthService
|
|
- TokenService
|
|
- AuthController
|
|
- JwtAuthGuard
|
|
|
|
- id: ET-AUTH-002
|
|
file: ../especificaciones/auth-domain.md
|
|
title: Domain Model Authentication
|
|
rf: [RF-AUTH-001, RF-AUTH-003]
|
|
status: migrated
|
|
components:
|
|
- Modelo de dominio Auth
|
|
|
|
- id: ET-AUTH-003
|
|
file: ../especificaciones/ET-AUTH-database.md
|
|
title: Database Authentication
|
|
rf: [RF-AUTH-001, RF-AUTH-002, RF-AUTH-004]
|
|
status: migrated
|
|
components:
|
|
- Schema core_auth
|
|
- Tablas y funciones
|
|
|
|
user_stories:
|
|
- id: US-MGN001-001
|
|
file: ../historias-usuario/US-MGN001-001.md
|
|
title: Login con Email/Password
|
|
rf: [RF-AUTH-001]
|
|
story_points: 8
|
|
status: migrated
|
|
acceptance_criteria: 5
|
|
|
|
- id: US-MGN001-002
|
|
file: ../historias-usuario/US-MGN001-002.md
|
|
title: Logout de Sesion
|
|
rf: [RF-AUTH-005]
|
|
story_points: 3
|
|
status: migrated
|
|
acceptance_criteria: 3
|
|
|
|
- id: US-MGN001-003
|
|
file: ../historias-usuario/US-MGN001-003.md
|
|
title: Recuperar Password
|
|
rf: [RF-AUTH-003]
|
|
story_points: 5
|
|
status: migrated
|
|
acceptance_criteria: 4
|
|
|
|
- id: US-MGN001-004
|
|
file: ../historias-usuario/US-MGN001-004.md
|
|
title: Refresh de Token
|
|
rf: [RF-AUTH-002]
|
|
story_points: 5
|
|
status: migrated
|
|
acceptance_criteria: 3
|
|
|
|
backlog:
|
|
file: ../historias-usuario/BACKLOG-MGN001.md
|
|
status: migrated
|
|
|
|
# =============================================================================
|
|
# IMPLEMENTACION
|
|
# =============================================================================
|
|
|
|
implementation:
|
|
|
|
database:
|
|
schema: core_auth
|
|
path: apps/database/ddl/schemas/core_auth/
|
|
|
|
tables:
|
|
- name: users_auth
|
|
file: apps/database/ddl/schemas/core_auth/tables/users_auth.sql
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
columns:
|
|
- {name: id, type: UUID, pk: true}
|
|
- {name: tenant_id, type: UUID, fk: tenants}
|
|
- {name: user_id, type: UUID, fk: users}
|
|
- {name: email, type: VARCHAR(255), unique: true}
|
|
- {name: password_hash, type: VARCHAR(255)}
|
|
- {name: is_active, type: BOOLEAN}
|
|
- {name: email_verified_at, type: TIMESTAMPTZ}
|
|
- {name: last_login_at, type: TIMESTAMPTZ}
|
|
- {name: created_at, type: TIMESTAMPTZ}
|
|
- {name: updated_at, type: TIMESTAMPTZ}
|
|
indexes:
|
|
- idx_users_auth_email
|
|
- idx_users_auth_tenant
|
|
rls_policies:
|
|
- tenant_isolation
|
|
|
|
- name: sessions
|
|
file: apps/database/ddl/schemas/core_auth/tables/sessions.sql
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
columns:
|
|
- {name: id, type: UUID, pk: true}
|
|
- {name: user_id, type: UUID, fk: users_auth}
|
|
- {name: token_hash, type: VARCHAR(255)}
|
|
- {name: ip_address, type: INET}
|
|
- {name: user_agent, type: TEXT}
|
|
- {name: expires_at, type: TIMESTAMPTZ}
|
|
- {name: created_at, type: TIMESTAMPTZ}
|
|
|
|
- name: refresh_tokens
|
|
file: apps/database/ddl/schemas/core_auth/tables/refresh_tokens.sql
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
columns:
|
|
- {name: id, type: UUID, pk: true}
|
|
- {name: user_id, type: UUID, fk: users_auth}
|
|
- {name: token_hash, type: VARCHAR(255)}
|
|
- {name: expires_at, type: TIMESTAMPTZ}
|
|
- {name: revoked_at, type: TIMESTAMPTZ}
|
|
- {name: created_at, type: TIMESTAMPTZ}
|
|
|
|
- name: password_resets
|
|
file: apps/database/ddl/schemas/core_auth/tables/password_resets.sql
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
columns:
|
|
- {name: id, type: UUID, pk: true}
|
|
- {name: user_id, type: UUID, fk: users_auth}
|
|
- {name: token_hash, type: VARCHAR(255)}
|
|
- {name: expires_at, type: TIMESTAMPTZ}
|
|
- {name: used_at, type: TIMESTAMPTZ}
|
|
- {name: created_at, type: TIMESTAMPTZ}
|
|
|
|
- name: login_attempts
|
|
file: apps/database/ddl/schemas/core_auth/tables/login_attempts.sql
|
|
rf: RF-AUTH-004
|
|
status: pending
|
|
columns:
|
|
- {name: id, type: UUID, pk: true}
|
|
- {name: email, type: VARCHAR(255)}
|
|
- {name: ip_address, type: INET}
|
|
- {name: attempted_at, type: TIMESTAMPTZ}
|
|
- {name: success, type: BOOLEAN}
|
|
|
|
- name: oauth_accounts
|
|
file: apps/database/ddl/schemas/core_auth/tables/oauth_accounts.sql
|
|
rf: RF-AUTH-005
|
|
status: pending
|
|
columns:
|
|
- {name: id, type: UUID, pk: true}
|
|
- {name: user_id, type: UUID, fk: users_auth}
|
|
- {name: provider, type: VARCHAR(50)}
|
|
- {name: provider_user_id, type: VARCHAR(255)}
|
|
- {name: access_token, type: TEXT}
|
|
- {name: refresh_token, type: TEXT}
|
|
- {name: expires_at, type: TIMESTAMPTZ}
|
|
- {name: created_at, type: TIMESTAMPTZ}
|
|
|
|
functions:
|
|
- name: validate_password
|
|
file: apps/database/ddl/schemas/core_auth/functions/validate_password.sql
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
params: [user_id UUID, password TEXT]
|
|
returns: BOOLEAN
|
|
description: Valida password contra hash almacenado
|
|
|
|
- name: cleanup_expired_sessions
|
|
file: apps/database/ddl/schemas/core_auth/functions/cleanup_sessions.sql
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
params: []
|
|
returns: INTEGER
|
|
description: Elimina sesiones expiradas, retorna cantidad eliminada
|
|
|
|
triggers:
|
|
- name: trg_update_users_auth_timestamp
|
|
table: users_auth
|
|
event: BEFORE UPDATE
|
|
function: update_updated_at()
|
|
status: pending
|
|
|
|
backend:
|
|
module: auth
|
|
path: apps/backend/src/modules/auth/
|
|
framework: NestJS
|
|
|
|
entities:
|
|
- name: UserAuth
|
|
file: apps/backend/src/modules/auth/entities/user-auth.entity.ts
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
table: users_auth
|
|
|
|
- name: Session
|
|
file: apps/backend/src/modules/auth/entities/session.entity.ts
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
table: sessions
|
|
|
|
- name: RefreshToken
|
|
file: apps/backend/src/modules/auth/entities/refresh-token.entity.ts
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
table: refresh_tokens
|
|
|
|
- name: PasswordReset
|
|
file: apps/backend/src/modules/auth/entities/password-reset.entity.ts
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
table: password_resets
|
|
|
|
- name: OAuthAccount
|
|
file: apps/backend/src/modules/auth/entities/oauth-account.entity.ts
|
|
rf: RF-AUTH-005
|
|
status: pending
|
|
table: oauth_accounts
|
|
|
|
services:
|
|
- name: AuthService
|
|
file: apps/backend/src/modules/auth/auth.service.ts
|
|
rf: [RF-AUTH-001, RF-AUTH-006]
|
|
status: pending
|
|
methods:
|
|
- {name: login, rf: RF-AUTH-001, description: "Valida credenciales y retorna tokens"}
|
|
- {name: logout, rf: RF-AUTH-006, description: "Revoca sesion actual"}
|
|
- {name: logoutAll, rf: RF-AUTH-006, description: "Revoca todas las sesiones"}
|
|
- {name: validateUser, rf: RF-AUTH-001, description: "Valida email y password"}
|
|
- {name: getProfile, rf: RF-AUTH-001, description: "Obtiene usuario autenticado"}
|
|
|
|
- name: TokenService
|
|
file: apps/backend/src/modules/auth/token.service.ts
|
|
rf: [RF-AUTH-002]
|
|
status: pending
|
|
methods:
|
|
- {name: generateAccessToken, rf: RF-AUTH-002, description: "Genera JWT access token"}
|
|
- {name: generateRefreshToken, rf: RF-AUTH-002, description: "Genera refresh token"}
|
|
- {name: refreshTokens, rf: RF-AUTH-002, description: "Renueva par de tokens"}
|
|
- {name: revokeRefreshToken, rf: RF-AUTH-002, description: "Revoca refresh token"}
|
|
- {name: validateAccessToken, rf: RF-AUTH-002, description: "Valida JWT"}
|
|
|
|
- name: PasswordService
|
|
file: apps/backend/src/modules/auth/password.service.ts
|
|
rf: [RF-AUTH-003]
|
|
status: pending
|
|
methods:
|
|
- {name: requestPasswordReset, rf: RF-AUTH-003, description: "Genera token y envia email"}
|
|
- {name: resetPassword, rf: RF-AUTH-003, description: "Cambia password con token"}
|
|
- {name: validateResetToken, rf: RF-AUTH-003, description: "Valida token de reset"}
|
|
|
|
- name: OAuthService
|
|
file: apps/backend/src/modules/auth/oauth.service.ts
|
|
rf: [RF-AUTH-005]
|
|
status: pending
|
|
methods:
|
|
- {name: initiateOAuth, rf: RF-AUTH-005, description: "Inicia flujo OAuth"}
|
|
- {name: handleCallback, rf: RF-AUTH-005, description: "Procesa callback OAuth"}
|
|
- {name: linkAccount, rf: RF-AUTH-005, description: "Vincula cuenta OAuth"}
|
|
|
|
controllers:
|
|
- name: AuthController
|
|
file: apps/backend/src/modules/auth/auth.controller.ts
|
|
status: pending
|
|
endpoints:
|
|
- method: POST
|
|
path: /api/v1/auth/login
|
|
rf: RF-AUTH-001
|
|
dto_in: LoginDto
|
|
dto_out: TokenResponseDto
|
|
auth: false
|
|
description: Login con email y password
|
|
|
|
- method: POST
|
|
path: /api/v1/auth/logout
|
|
rf: RF-AUTH-006
|
|
dto_in: null
|
|
dto_out: MessageResponseDto
|
|
auth: true
|
|
description: Cerrar sesion actual
|
|
|
|
- method: POST
|
|
path: /api/v1/auth/refresh
|
|
rf: RF-AUTH-002
|
|
dto_in: RefreshTokenDto
|
|
dto_out: TokenResponseDto
|
|
auth: false
|
|
description: Refrescar tokens
|
|
|
|
- method: POST
|
|
path: /api/v1/auth/forgot-password
|
|
rf: RF-AUTH-003
|
|
dto_in: ForgotPasswordDto
|
|
dto_out: MessageResponseDto
|
|
auth: false
|
|
description: Solicitar recuperacion de password
|
|
|
|
- method: POST
|
|
path: /api/v1/auth/reset-password
|
|
rf: RF-AUTH-003
|
|
dto_in: ResetPasswordDto
|
|
dto_out: MessageResponseDto
|
|
auth: false
|
|
description: Restablecer password con token
|
|
|
|
- method: GET
|
|
path: /api/v1/auth/me
|
|
rf: RF-AUTH-001
|
|
dto_in: null
|
|
dto_out: UserProfileDto
|
|
auth: true
|
|
description: Obtener usuario autenticado
|
|
|
|
- method: GET
|
|
path: /api/v1/auth/oauth/:provider
|
|
rf: RF-AUTH-005
|
|
dto_in: null
|
|
dto_out: OAuthRedirectDto
|
|
auth: false
|
|
description: Iniciar OAuth flow
|
|
|
|
dtos:
|
|
- name: LoginDto
|
|
file: apps/backend/src/modules/auth/dto/login.dto.ts
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
fields:
|
|
- {name: email, type: string, validation: "IsEmail"}
|
|
- {name: password, type: string, validation: "MinLength(8)"}
|
|
- {name: remember_me, type: boolean, optional: true}
|
|
|
|
- name: TokenResponseDto
|
|
file: apps/backend/src/modules/auth/dto/token-response.dto.ts
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
fields:
|
|
- {name: access_token, type: string}
|
|
- {name: refresh_token, type: string}
|
|
- {name: expires_in, type: number}
|
|
- {name: token_type, type: string}
|
|
|
|
- name: RefreshTokenDto
|
|
file: apps/backend/src/modules/auth/dto/refresh-token.dto.ts
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
fields:
|
|
- {name: refresh_token, type: string, validation: "IsNotEmpty"}
|
|
|
|
- name: ForgotPasswordDto
|
|
file: apps/backend/src/modules/auth/dto/forgot-password.dto.ts
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
fields:
|
|
- {name: email, type: string, validation: "IsEmail"}
|
|
|
|
- name: ResetPasswordDto
|
|
file: apps/backend/src/modules/auth/dto/reset-password.dto.ts
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
fields:
|
|
- {name: token, type: string, validation: "IsNotEmpty"}
|
|
- {name: password, type: string, validation: "MinLength(8)"}
|
|
- {name: password_confirmation, type: string}
|
|
|
|
guards:
|
|
- name: JwtAuthGuard
|
|
file: apps/backend/src/modules/auth/guards/jwt-auth.guard.ts
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
description: Valida JWT en header Authorization
|
|
|
|
- name: RefreshTokenGuard
|
|
file: apps/backend/src/modules/auth/guards/refresh-token.guard.ts
|
|
rf: RF-AUTH-002
|
|
status: pending
|
|
description: Valida refresh token
|
|
|
|
decorators:
|
|
- name: CurrentUser
|
|
file: apps/backend/src/modules/auth/decorators/current-user.decorator.ts
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
description: Inyecta usuario actual del request
|
|
|
|
- name: Public
|
|
file: apps/backend/src/modules/auth/decorators/public.decorator.ts
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
description: Marca endpoint como publico (sin auth)
|
|
|
|
frontend:
|
|
feature: auth
|
|
path: apps/frontend/src/features/auth/
|
|
framework: React
|
|
|
|
pages:
|
|
- name: LoginPage
|
|
file: apps/frontend/src/features/auth/pages/LoginPage.tsx
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
route: /login
|
|
components: [LoginForm, SocialLoginButtons]
|
|
|
|
- name: ForgotPasswordPage
|
|
file: apps/frontend/src/features/auth/pages/ForgotPasswordPage.tsx
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
route: /forgot-password
|
|
components: [ForgotPasswordForm]
|
|
|
|
- name: ResetPasswordPage
|
|
file: apps/frontend/src/features/auth/pages/ResetPasswordPage.tsx
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
route: /reset-password/:token
|
|
components: [ResetPasswordForm]
|
|
|
|
components:
|
|
- name: LoginForm
|
|
file: apps/frontend/src/features/auth/components/LoginForm.tsx
|
|
rf: RF-AUTH-001
|
|
status: pending
|
|
description: Formulario de login con validacion
|
|
|
|
- name: SocialLoginButtons
|
|
file: apps/frontend/src/features/auth/components/SocialLoginButtons.tsx
|
|
rf: RF-AUTH-005
|
|
status: pending
|
|
description: Botones de login social (Google, Microsoft)
|
|
|
|
- name: ForgotPasswordForm
|
|
file: apps/frontend/src/features/auth/components/ForgotPasswordForm.tsx
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
description: Formulario solicitud de reset
|
|
|
|
- name: ResetPasswordForm
|
|
file: apps/frontend/src/features/auth/components/ResetPasswordForm.tsx
|
|
rf: RF-AUTH-003
|
|
status: pending
|
|
description: Formulario cambio de password
|
|
|
|
stores:
|
|
- name: authStore
|
|
file: apps/frontend/src/features/auth/stores/authStore.ts
|
|
rf: [RF-AUTH-001, RF-AUTH-002]
|
|
status: pending
|
|
state:
|
|
- {name: user, type: "User | null"}
|
|
- {name: isAuthenticated, type: boolean}
|
|
- {name: isLoading, type: boolean}
|
|
- {name: error, type: "string | null"}
|
|
actions:
|
|
- {name: login, rf: RF-AUTH-001}
|
|
- {name: logout, rf: RF-AUTH-006}
|
|
- {name: refreshToken, rf: RF-AUTH-002}
|
|
- {name: getProfile, rf: RF-AUTH-001}
|
|
|
|
api:
|
|
- name: authApi
|
|
file: apps/frontend/src/features/auth/api/authApi.ts
|
|
status: pending
|
|
methods:
|
|
- {name: login, endpoint: "POST /auth/login"}
|
|
- {name: logout, endpoint: "POST /auth/logout"}
|
|
- {name: refresh, endpoint: "POST /auth/refresh"}
|
|
- {name: forgotPassword, endpoint: "POST /auth/forgot-password"}
|
|
- {name: resetPassword, endpoint: "POST /auth/reset-password"}
|
|
- {name: getMe, endpoint: "GET /auth/me"}
|
|
|
|
hooks:
|
|
- name: useAuth
|
|
file: apps/frontend/src/features/auth/hooks/useAuth.ts
|
|
status: pending
|
|
description: Hook para acceder a estado de auth
|
|
|
|
- name: useRequireAuth
|
|
file: apps/frontend/src/features/auth/hooks/useRequireAuth.ts
|
|
status: pending
|
|
description: Hook para proteger rutas
|
|
|
|
# =============================================================================
|
|
# DEPENDENCIAS
|
|
# =============================================================================
|
|
|
|
dependencies:
|
|
depends_on: [] # Primer modulo, sin dependencias
|
|
|
|
required_by:
|
|
- module: MGN-002
|
|
type: hard
|
|
reason: Usuarios necesitan autenticacion
|
|
- module: MGN-003
|
|
type: hard
|
|
reason: RBAC usa tokens JWT
|
|
- module: MGN-004
|
|
type: hard
|
|
reason: Tenant ID en token
|
|
- module: ALL
|
|
type: hard
|
|
reason: Todos los modulos requieren auth
|
|
|
|
external:
|
|
- name: bcrypt
|
|
version: "^5.1.0"
|
|
purpose: Hash de passwords
|
|
- name: jsonwebtoken
|
|
version: "^9.0.0"
|
|
purpose: Generacion/validacion JWT
|
|
- name: passport
|
|
version: "^0.7.0"
|
|
purpose: Estrategias de autenticacion
|
|
- name: @nestjs/jwt
|
|
version: "^10.0.0"
|
|
purpose: Integracion JWT con NestJS
|
|
|
|
# =============================================================================
|
|
# TESTS
|
|
# =============================================================================
|
|
|
|
tests:
|
|
unit:
|
|
- name: AuthService.spec.ts
|
|
file: apps/backend/src/modules/auth/__tests__/auth.service.spec.ts
|
|
status: pending
|
|
cases: 12
|
|
rf: [RF-AUTH-001, RF-AUTH-006]
|
|
|
|
- name: TokenService.spec.ts
|
|
file: apps/backend/src/modules/auth/__tests__/token.service.spec.ts
|
|
status: pending
|
|
cases: 8
|
|
rf: [RF-AUTH-002]
|
|
|
|
- name: PasswordService.spec.ts
|
|
file: apps/backend/src/modules/auth/__tests__/password.service.spec.ts
|
|
status: pending
|
|
cases: 6
|
|
rf: [RF-AUTH-003]
|
|
|
|
integration:
|
|
- name: auth.controller.e2e.spec.ts
|
|
file: apps/backend/test/auth/auth.controller.e2e.spec.ts
|
|
status: pending
|
|
cases: 10
|
|
endpoints:
|
|
- POST /auth/login
|
|
- POST /auth/logout
|
|
- POST /auth/refresh
|
|
- GET /auth/me
|
|
|
|
frontend:
|
|
- name: LoginForm.test.tsx
|
|
file: apps/frontend/src/features/auth/__tests__/LoginForm.test.tsx
|
|
status: pending
|
|
cases: 5
|
|
rf: [RF-AUTH-001]
|
|
|
|
coverage:
|
|
target: 80%
|
|
current: 0%
|
|
unit: 0%
|
|
integration: 0%
|
|
e2e: 0%
|
|
|
|
# =============================================================================
|
|
# METRICAS
|
|
# =============================================================================
|
|
|
|
metrics:
|
|
story_points:
|
|
estimated: 40
|
|
actual: null
|
|
variance: null
|
|
|
|
files:
|
|
database: 9
|
|
backend: 22
|
|
frontend: 14
|
|
tests: 8
|
|
total: 53
|
|
|
|
lines_of_code:
|
|
estimated: 2500
|
|
actual: 0
|
|
|
|
complexity:
|
|
services: medium
|
|
database: low
|
|
frontend: low
|
|
|
|
# =============================================================================
|
|
# BUG FIXES
|
|
# =============================================================================
|
|
|
|
bug_fixes: []
|
|
|
|
# =============================================================================
|
|
# CHANGELOG
|
|
# =============================================================================
|
|
|
|
changelog:
|
|
- version: "1.0.0"
|
|
date: null
|
|
changes:
|
|
- "Implementacion inicial de autenticacion"
|
|
- "Login con email/password"
|
|
- "Manejo de tokens JWT"
|
|
- "Proteccion brute force"
|
|
|
|
# =============================================================================
|
|
# HISTORIAL
|
|
# =============================================================================
|
|
|
|
history:
|
|
- date: "2025-12-05"
|
|
action: "Creacion de TRACEABILITY.yml"
|
|
author: Requirements-Analyst
|
|
changes:
|
|
- "Documentacion completa de trazabilidad"
|
|
- "Mapeo RF -> ET -> US -> Codigo"
|
|
- "Definicion de todos los componentes"
|