Files
Krow-workspace/validation_staff_mock_dataconecct.md
2025-12-26 15:14:51 -05:00

10 KiB
Raw Blame History

Análisis de Mocks de Staff App vs. Schema de Data Connect

Este documento realiza una comparación detallada entre 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 identificar discrepancias, proponer soluciones y asegurar la consistencia entre el frontend y el backend.


1. Perfil de Leaderboard (_profiles)

  • Archivo Mock: lib/screens/worker/worker_profile/level_up/leaderboard_screen.dart
  • Entidad Data Connect más cercana: Staff (dataconnect/schema/staff.gql)

Comparación Campo por Campo

Campo (Mock App) Campo (Schema GQL Staff) Recomendación
id id Match.
name employeeName ⚠️ Diferencia de nombre. Renombrar name a employeeName en la app.
photo_url (No existe) Campo faltante. El schema de Staff no tiene un campo para URL de foto. Se debe agregar.
xp (No existe) Campo faltante. Relacionado con gamificación. Proponer experiencePoints: Int.
level (No existe) Campo faltante. Relacionado con gamificación. Proponer level: String.
user_id (No existe) ⚠️ Diferencia conceptual. El schema Staff tiene vendorId y email. Aclarar si user_id corresponde al id del User o Staff.

Recomendaciones

  1. En la app (Flutter):

    • Cambiar el nombre del campo name a employeeName para que coincida con el schema.
  2. En el schema (staff.gql):

    • Agregar los campos para la gamificación y el perfil.
    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 más cercanas: Conversation (conversation.gql) y Message (message.gql).

El mock aplana la información de ambas entidades.

Comparación de Conversation

Campo (Mock App) Campo (Schema GQL Conversation) Recomendación
sender_id participants ⚠️ Diferencia de estructura. El mock asume una conversación 1-a-1, mientras participants es un String (JSON) con un array de IDs. La app debe adaptarse para manejar múltiples participantes.
sender_name (No existe directamente) Dato derivado. Este dato debe obtenerse consultando la entidad Staff o User con el ID del participante.
lastMessage (No existe directamente) Dato derivado. Este debe ser el campo content del último Message asociado a la conversationId. La app debe consultar los mensajes.
lastTime updatedDate Match conceptual. updatedDate en Conversation debería actualizarse con cada nuevo mensaje. La app puede usar este campo.
unread (No existe) Campo faltante y complejo. El conteo de no leídos es por usuario. El schema actual no lo soporta. El campo readBy en Message podría usarse para calcular esto, pero es ineficiente. Se requiere un rediseño.
messages (Corresponde a la entidad Message) Relación. La app debe hacer una query separada para obtener los Message donde conversationId coincida.

Comparación de Message (anidado en el mock)

Campo (Mock App) Campo (Schema GQL Message) Recomendación
content content Match.
sender_id createdBy / senderName Match conceptual. El schema tiene createdBy (ID del usuario) y senderName. La app debe usar estos campos.

Recomendaciones

  1. En la app (Flutter):
    • Adaptar la lógica para manejar participants como un array.
    • Implementar la obtención de sender_name y lastMessage a través de queries adicionales.
    • Eliminar la consulta de mensajes anidada y realizar una consulta separada por conversationId.
  2. En el schema (conversation.gql y message.gql):
    • El manejo de unread es un desafío. Una solución a largo plazo podría ser una nueva tabla ConversationReadStatus que vincule (userId, conversationId, lastReadTimestamp). Por ahora, se puede calcular en el cliente.
    • El schema actual es funcional pero requiere que el cliente orqueste varias llamadas.

3. Hojas de Tiempo (_timesheets)

  • Archivo Mock: lib/screens/worker/worker_profile/finances/time_card_screen.dart
  • Entidades Data Connect más cercanas: Shift (shift.gql) y Event (event.gql).

El mock es una vista aplanada que combina información de un turno (Shift) y del evento (Event) al que pertenece.

Comparación Campo por Campo

Campo (Mock App) Campo (Schema GQL Shift/Event) Recomendación
id Shift.id Match.
shift_id Shift.id Match. (Redundante en el mock).
date Shift.startDate Match conceptual. Usar startDate.
actual_start (No existe) Campo faltante. El schema de Shift necesita campos para el check-in/out real. Proponer actualStartTime: Timestamp.
actual_end (No existe) Campo faltante. Proponer actualEndTime: Timestamp.
total_hours (No existe) Dato derivado. Debe calcularse en la app o en el backend a partir de actualStartTime y actualEndTime.
hourly_rate Staff.rate / Event.rate? ⚠️ Requiere clarificación. La tarifa puede depender del staff, del evento o del rol en el turno. El schema de Shift debería tener un campo rate.
total_pay (No existe) Dato derivado. Calcular total_hours * hourly_rate.
status Shift.status? ⚠️ Ambigüedad. Shift no tiene status, pero Event sí. El estado del pago (pending, approved, paid) es un concepto diferente. Se necesita un campo paymentStatus en Shift.
shift_title Shift.shiftName Match.
client_name Event.clientName o Business.name Dato relacionado. Se debe obtener a través del eventId en el Shift para luego consultar el Event o Business asociado.
location Event.eventLocation Dato relacionado. Obtener del Event asociado.

Recomendaciones

  1. En la app (Flutter):

    • La app debe realizar una consulta que una datos de Shift y su Event relacionado para construir esta vista.
    • Calcular campos derivados como total_hours y total_pay.
  2. En el schema (shift.gql):

    • Agregar campos cruciales para el registro de tiempo y pago.
    type Shift @table(name: "shifts") {
      # ... campos existentes
      actualStartTime: Timestamp
      actualEndTime: Timestamp
      rate: Float
      paymentStatus: String # O un enum: PENDING, APPROVED, PAID, DISPUTED
    }
    

4. Certificados (_certificates)

  • Archivo Mock: lib/screens/worker/worker_profile/compliance/certificates_screen.dart
  • Entidad Data Connect más cercana: Certification (certification.gql)

Comparación Campo por Campo

Campo (Mock App) Campo (Schema GQL Certification) Recomendación
id id Match.
name certificationName ⚠️ Diferencia de nombre. Renombrar name a certificationName en la app.
icon / color (No existe) Lógica de UI. Estos campos son para la visualización y deben manejarse en el frontend. No pertenecen al schema.
description (No existe) Campo faltante. El schema podría beneficiarse de un campo descriptivo. Proponer description: String.
status status y validationStatus Match conceptual. El schema tiene dos campos de estado. La app debe combinar o decidir cuál mostrar. CertificationStatus (CURRENT, EXPIRED) parece el correcto.
expiry expiryDate Match conceptual. El tipo de dato debe ser consistente (el mock usa String?, el schema String!).

Recomendaciones

  1. En la app (Flutter):

    • Cambiar name por certificationName.
    • Mapear los valores de status del schema al estado que la UI espera.
  2. En el schema (certification.gql):

    • Considerar añadir un campo opcional para la descripción.
    type Certification @table(name: "certification") {
      # ... campos existentes
      description: String
    }
    

5. Contactos de Emergencia (_contacts)

  • Archivo Mock: lib/screens/worker/worker_profile/onboarding/emergency_contact_screen.dart
  • Entidad Data Connect más cercana: Ninguna.

No existe una entidad para almacenar contactos de emergencia.

Recomendaciones

  1. En el schema:

    • Crear una nueva entidad EmergencyContact. Debería estar vinculada a un Staff.
    # En un nuevo archivo: 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", "Friend"
      createdDate: Timestamp @default(expr: "request.time")
      updatedDate: Timestamp @default(expr: "request.time")
    }
    
    • Se debe decidir si esta información se almacena como un array de jsonb en la tabla Staff o como una tabla separada. Una tabla separada es más limpia y escalable.

Conclusiones Generales

  1. Aplanamiento de Datos: La app de Flutter tiende a usar estructuras de datos aplanadas que combinan campos de múltiples entidades de Data Connect. Esto es normal para las vistas de UI, pero requiere que la capa de datos de la app realice las consultas y uniones necesarias.
  2. Campos Faltantes Críticos: Se han identificado campos faltantes importantes, especialmente en Shift (para el control de horas y pagos) y Staff (para gamificación y perfil).
  3. Nomenclatura: Hay inconsistencias menores en los nombres de los campos. La recomendación general es alinear la app con los nombres del schema de Data Connect, que es la fuente de verdad.
  4. Nuevas Entidades: Se necesitan nuevas entidades como EmergencyContact. Otras estructuras mock (_benefitsData, _attireOptions, _courses, etc.) también requerirán probablemente sus propias tablas y schemas en Data Connect.