Saltar al contenido principal
Versión: 2.0

Módulo: Documentos Legales

Scope

Tipo de organizaciónAcceso
Empresa
Agencia
Reclutador independiente
Usuario sin organización✅ (registro)

Permisos por rol

AcciónDisponiblePermiso
Ver Términos y CondicionesPúblico (no requiere autenticación)
Ver Política de PrivacidadPúblico (no requiere autenticación)

¿Qué es?

Módulo que consume los documentos legales publicados desde el backend (términos y condiciones, política de privacidad). El contenido es dinámico, bilingüe (es/en), y versionado. Se usa en el flujo de registro y es accesible desde las páginas de auth.

¿Qué puede hacer el usuario?

  • Leer los Términos y Condiciones publicados
  • Leer la Política de Privacidad publicada
  • El contenido se resuelve en el idioma del dispositivo (via Accept-Language header)
  • En el registro, debe leer ambos documentos antes de poder aceptar el checkbox

Flujo del usuario

En el registro

1. Usuario llega al formulario de registro
2. Ve el checkbox "Acepto los términos y condiciones y la política de privacidad"
3. El checkbox está deshabilitado hasta leer ambos documentos
4. Toca "términos y condiciones" → abre página que carga desde API
5. Lee el documento → regresa → indicador muestra ✓ leído
6. Toca "política de privacidad" → abre página que carga desde API
7. Lee el documento → regresa → indicador muestra ✓ leído
8. Ambos leídos → checkbox se habilita → marca → puede registrarse

Página independiente

1. Navega a la página de términos o privacidad
2. Se muestra loading mientras carga
3. Éxito → renderiza título, fecha y contenido completo
4. Error → muestra mensaje con botón de reintentar

Reglas de negocio

  • Solo se muestran documentos con status PUBLISHED
  • Si no hay documento publicado, el API retorna 404 con LEGAL_DOCUMENT_NOT_FOUND
  • El locale se resuelve del header Accept-Language (soporta es y en-US)
  • El contenido incluye body (texto plano) y bodyHtml (HTML sanitizado)
  • Actualmente se renderiza el body como texto; bodyHtml está disponible para renderizado futuro
  • Los documentos tienen un contentHash SHA-256 para verificar integridad/versión
  • En el registro, el checkbox requiere haber abierto y regresado de ambos documentos

Arquitectura

lib/features/legal_documents/
├── application/
│ ├── legal_document_cubit.dart # loadTermsAndConditions() / loadPrivacyPolicy()
│ └── legal_document_state.dart # LegalDocumentStatus enum
├── data/
│ ├── datasources/
│ │ └── legal_documents_remote_datasource.dart
│ ├── models/
│ │ └── legal_document_model.dart # fromJson
│ └── repositories/
│ └── legal_documents_repository_impl.dart
└── domain/
├── entities/
│ └── legal_document.dart # Equatable, inmutable
├── repositories/
│ └── legal_documents_repository.dart
└── usecases/
├── get_terms_and_conditions_usecase.dart
└── get_privacy_policy_usecase.dart

Las páginas de presentación viven en lib/features/auth/presentation/pages/:

  • terms_and_conditions_page.dart
  • privacy_policy_page.dart

Endpoints API (sin prefijo /api)

MétodoEndpointAutenticaciónDescripción
GET/legal-documents/terms-and-conditionsPúblicoTérminos y Condiciones publicados
GET/legal-documents/privacy-policyPúblicoPolítica de Privacidad publicada

Estructura de respuesta

{
"key": "TERMS_AND_CONDITIONS",
"version": 1,
"status": "PUBLISHED",
"locale": "es",
"title": "Términos y condiciones",
"summary": "Condiciones de uso de Contratta.",
"body": "Contenido legal completo...",
"bodyHtml": "<p>Contenido legal completo...</p>",
"contentHash": "sha256:4d4f5b9e...",
"publishedAt": "2026-07-17T19:00:00.000Z",
"effectiveAt": "2026-07-17T19:00:00.000Z"
}

Registro DI

  • Datasource: LazySingleton
  • Repository: LazySingleton
  • Use Cases: LazySingleton (GetTermsAndConditionsUseCase, GetPrivacyPolicyUseCase)
  • Cubit: Factory (nueva instancia por página)
getIt<LegalDocumentCubit>()

Localización

El contenido viene localizado del backend según el header Accept-Language. Las etiquetas de la UI usan claves l10n existentes (registerTerms, registerPrivacy, etc.).

Estados de la UI

EstadoComportamiento
LoadingCircularProgressIndicator centrado
SuccessRenderiza título, fecha efectiva y body completo
ErrorÍcono de error + mensaje + botón "Reintentar"