# Análisis Exhaustivo de Mocks de Staff App vs. Schema de Data Connect (V2) Este documento realiza una comparación detallada y completa entre todas las estructuras de datos (mocks) utilizadas en la aplicación de Staff y las entidades definidas en el schema de GraphQL de Firebase Data Connect. El objetivo es asegurar la consistencia total y planificar la evolución del schema. --- ## 1. Perfil de Leaderboard (`_profiles`) - **Archivo Mock:** `lib/screens/worker/worker_profile/level_up/leaderboard_screen.dart` - **Entidad Data Connect:** `Staff` (`dataconnect/schema/staff.gql`) - **Análisis:** Existe una correspondencia directa pero incompleta. - **Recomendaciones:** - **App:** Renombrar `name` a `employeeName`. - **Schema `staff.gql`:** Agregar campos para gamificación y perfil. ```graphql type Staff @table(name: "staffs") { # ... campos existentes profilePictureUrl: String experiencePoints: Int @default(expr: "0") level: String } ``` --- ## 2. Conversaciones (`_conversations`) - **Archivo Mock:** `lib/screens/worker/worker_profile/support/messages_screen.dart` - **Entidades Data Connect:** `Conversation` (`conversation.gql`) y `Message` (`message.gql`). - **Análisis:** El mock es una vista aplanada de ambas entidades. El schema es más robusto pero requiere que la app orqueste las llamadas. - **Recomendaciones:** - **App:** - Adaptar la lógica para manejar el campo `participants` (JSON array) en lugar de un `sender_id` simple. - Obtener `sender_name` y `lastMessage` a través de consultas adicionales (al perfil del participante y al último mensaje). - El campo `unread` es el más complejo. Debe calcularse en el cliente revisando la lista de `readBy` en cada mensaje. - **Schema:** Para optimizar el conteo de no leídos a futuro, se podría crear una tabla `ConversationReadStatus (userId, conversationId, lastReadTimestamp)`. --- ## 3. Hojas de Tiempo (`_timesheets`) - **Archivo Mock:** `lib/screens/worker/worker_profile/finances/time_card_screen.dart` - **Entidades Data Connect:** `Shift` (`shift.gql`) y `Event` (`event.gql`). - **Análisis:** El mock combina información del turno y del evento. Faltan campos cruciales en el schema `Shift` para el registro de horas y pagos. - **Recomendaciones:** - **App:** Realizar una consulta que una datos de `Shift` y su `Event` relacionado para construir la vista. - **Schema `shift.gql`:** Agregar los siguientes campos es **prioritario**. ```graphql # En dataconnect/schema/shift.gql enum ShiftPaymentStatus { PENDING APPROVED PAID DISPUTED } type Shift @table(name: "shifts") { # ... campos existentes actualStartTime: Timestamp actualEndTime: Timestamp rate: Float # Tarifa específica del turno paymentStatus: ShiftPaymentStatus } ``` --- ## 4. Certificados (`_certificates`) - **Archivo Mock:** `lib/screens/worker/worker_profile/compliance/certificates_screen.dart` - **Entidad Data Connect:** `Certification` (`certification.gql`). - **Análisis:** Coincidencia conceptual fuerte. - **Recomendaciones:** - **App:** Renombrar `name` a `certificationName` y `expiry` a `expiryDate`. - **Schema `certification.gql`:** Añadir un campo opcional `description: String`. --- ## 5. Contactos de Emergencia (`_contacts`) - **Archivo Mock:** `lib/screens/worker/worker_profile/onboarding/emergency_contact_screen.dart` - **Entidad Data Connect:** **Ninguna.** - **Análisis:** No existe una entidad para esta información vital. - **Recomendaciones:** - **Schema:** Crear una nueva entidad `EmergencyContact` vinculada al `Staff`. Almacenarla en una tabla separada es preferible a un campo JSON en `Staff` por escalabilidad. ```graphql # En dataconnect/schema/emergencyContact.gql type EmergencyContact @table(name: "emergency_contacts") { id: UUID! @default(expr: "uuidV4()") staffId: UUID! # FK a la tabla Staff name: String! phone: String! relationship: String # Ejemplo: "Spouse", "Parent" createdDate: Timestamp @default(expr: "request.time") } ``` --- ## 6. Opciones de Vestimenta (`_attireOptions`) - **Archivo Mock:** `lib/screens/worker/worker_profile/onboarding/attire_screen.dart` - **Entidad Data Connect:** **Ninguna.** - **Análisis:** Representa el inventario de vestimenta de un trabajador, que puede ser requisito para un turno. - **Recomendaciones:** - **Schema:** Crear dos nuevas entidades: una para definir la vestimenta estándar y otra para asociarla a cada trabajador. ```graphql # En dataconnect/schema/attire.gql type Attire @table(name: "attire") { id: UUID! @default(expr: "uuidV4()") label: String! imageUrl: String } # En dataconnect/schema/staffAttire.gql type StaffAttire @table(name: "staff_attire") { id: UUID! @default(expr: "uuidV4()") staffId: UUID! attireId: UUID! } ``` --- ## 7. Cursos de Capacitación (`_courses`) - **Archivo Mock:** `lib/screens/worker/worker_profile/level_up/trainings_screen.dart` - **Entidad Data Connect:** **Ninguna.** - **Análisis:** Distinto de `Certification`, se enfoca en capacitación interna y gamificación. - **Recomendaciones:** - **Schema:** Crear entidades para los cursos y el progreso de cada trabajador. ```graphql # En dataconnect/schema/trainingCourse.gql type TrainingCourse @table(name: "training_courses") { id: UUID! @default(expr: "uuidV4()") title: String! description: String durationMinutes: Int xpReward: Int } # En dataconnect/schema/staffTraining.gql type StaffTraining @table(name: "staff_trainings") { id: UUID! @default(expr: "uuidV4()") staffId: UUID! courseId: UUID! progressPercent: Int @default(expr: "0") completed: Boolean @default(expr: "false") } ``` --- ## 8. Documentos Requeridos (`_requiredDocs` y `_forms`) - **Archivos Mock:** `documents_screen.dart` y `tax_forms_screen.dart`. - **Entidad Data Connect:** **Ninguna.** - **Análisis:** Ambos mocks se refieren a documentos de cumplimiento. Se pueden unificar. - **Recomendaciones:** - **Schema:** Crear una única entidad `StaffDocument` para manejar todos los documentos. ```graphql # En dataconnect/schema/staffDocument.gql enum DocumentType { GOVERNMENT_ID SSN FORM_I9 FORM_W4 OTHER } enum DocumentStatus { MISSING PENDING_UPLOAD PENDING_VERIFICATION VERIFIED REJECTED } type StaffDocument @table(name: "staff_documents") { id: UUID! @default(expr: "uuidV4()") staffId: UUID! documentType: DocumentType! status: DocumentStatus! fileUrl: String # URL al archivo en Cloud Storage notes: String # Para motivos de rechazo, etc. } ``` --- ## 9. Cuentas Bancarias (`_accounts`) - **Archivo Mock:** `lib/screens/worker/worker_profile/finances/bank_account_screen.dart` - **Entidad Data Connect:** **Ninguna.** - **Análisis:** Esta es información altamente sensible. **No debe almacenarse directamente en la base de datos.** Debe ser manejada por un proveedor de pagos (ej. Stripe, Adyen). - **Recomendaciones:** - **Schema `staff.gql`:** Agregar un campo para almacenar el ID de cliente del proveedor de pagos, no los detalles de la cuenta. ```graphql type Staff @table(name: "staffs") { # ... campos existentes paymentProviderCustomerId: String # ID del cliente en Stripe/Adyen } ``` - **App:** Integrar el SDK del proveedor de pagos para registrar y mostrar la información bancaria de forma segura (tokenizada). --- ## 10. Pagos Recientes (`_recentPayments` - detallado y resumido) - **Archivos Mock:** `payments_screen.dart` y `earnings_screen.dart`. - **Entidad Data Connect:** **Ninguna (es una vista derivada).** - **Análisis:** Estos mocks no representan una entidad, sino una vista de consulta sobre los `Shift` que han sido pagados. - **Recomendaciones:** - **Sin cambios en el schema,** asumiendo que las recomendaciones para `Shift` (punto 3) se implementen. - **App:** La lógica para estas pantallas debe: 1. Consultar todos los `Shift` para el `staffId` con `paymentStatus: 'PAID'`. 2. Unir la información del `Event` relacionado para obtener la ubicación y nombre del cliente. 3. Para la vista de "Earnings", agrupar estos turnos por período de pago (ej. semanal) y sumar los montos. --- ## 11. Franjas Horarias (`_timeSlots` - Disponibilidad) - **Archivo Mock:** `lib/screens/worker/availability_screen.dart` - **Entidad Data Connect:** **Ninguna.** - **Análisis:** Define la disponibilidad preferida del trabajador. - **Recomendaciones:** - **Schema:** Crear una nueva entidad `StaffAvailability`. Un campo JSON por día ofrece flexibilidad. ```graphql # En dataconnect/schema/staffAvailability.gql type StaffAvailability @table(name: "staff_availability") { id: UUID! @default(expr: "uuidV4()") staffId: UUID! # Usar Any (jsonb) para guardar un array de strings: ["morning", "afternoon"] monday: Any tuesday: Any wednesday: Any thursday: Any friday: Any saturday: Any sunday: Any } ``` --- ## 12. Datos de Beneficios (`_benefitsData`) - **Archivo Mock:** `lib/screens/worker/benefits_screen.dart` - **Entidad Data Connect:** **Ninguna.** - **Análisis:** Gestiona los beneficios acumulados como días de vacaciones o enfermedad. - **Recomendaciones:** - **Schema:** Crear entidades para definir los tipos de beneficio y el balance de cada trabajador. ```graphql # En dataconnect/schema/benefit.gql enum BenefitType { SICK_DAYS VACATION OTHER } type StaffBenefit @table(name: "staff_benefits") { id: UUID! @default(expr: "uuidV4()") staffId: UUID! benefitType: BenefitType! currentBalance: Float! # En horas o días totalAllowance: Float! # Total anual/periodo } # Opcional: una tabla para el historial de uso type BenefitHistory @table(name: "benefit_history") { id: UUID! @default(expr: "uuidV4()") staffBenefitId: UUID! amount: Float! # Horas/días usados date: Timestamp! status: String # PENDING, APPROVED } ``` --- ## 13. Actividad Reciente (`ActivityLog`) - **Mock:** No hay un mock específico, pero el concepto es universal. - **Entidad Data Connect:** `ActivityLog` (`activityLog.gql`) - **Análisis:** El schema `activityLog.gql` ya existe y es perfecto para registrar eventos importantes (ej. "Turno aceptado", "Perfil actualizado", "Certificado validado"). - **Recomendaciones:** - **Backend:** Implementar la lógica para que las mutaciones importantes (actualizar staff, aceptar un turno, etc.) generen una entrada en la tabla `ActivityLog`. - **App:** Crear una pantalla de "Actividad Reciente" que consulte esta tabla para el `staffId` logueado, mostrando un historial de eventos. --- ## 14. Pasos de Setup y FAQs (`_steps` y `_faqData`) - **Archivos Mock:** `profile_setup_screen.dart` y `faqs_screen.dart`. - **Análisis:** Estas estructuras son puramente para la UI (navegación de un wizard) o contienen contenido estático (FAQs). - **Recomendaciones:** - **Sin cambios en el schema.** Esta información no necesita ser gestionada a través de Data Connect. Puede permanecer como contenido estático dentro de la aplicación o, si requiere ser dinámico, ser gestionado por un CMS externo.