Advertisement
NameL3ss

importer

Nov 9th, 2020
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.26 KB | None | 0 0
  1. Sistema de Alertas-Notificaciones de Eventos
  2.  
  3. Se requiere de poder configurar mediante un tiempo la frecuencia de las alertas, para lo cual un usuario configurará los tipos de eventos con su respectivo tiempo.
  4.  
  5. Importer Dir
  6. Account has_many :importer_logs
  7.  
  8. ImporterLog
  9. account_id, user_id, total_rows, status (error, en_cola, procesado, etc), importer_log_candidate_id:references
  10. belongs_to :importer_log_candidate
  11. has_one_attached :file
  12.  
  13. ImporterLogCandidate (se sube a aws para previsualizacion)
  14. file_path, status, preview_quantity
  15. has_one :importer_log
  16.  
  17.  
  18.  
  19.  
  20. Alcance primera etapa:
  21.  
  22. Importadores
  23. ---fecha-vencimiento
  24. ----tipo-documento
  25.  
  26. ---Agregar documentos una vez creado el vehiculo
  27. Revision Tecnica
  28.  
  29.  
  30.  
  31.  
  32. eventos
  33. stop: Velocidad de detención
  34. overheating: Máxima temperatura
  35. speeding: Máxima velocidad
  36.  
  37.  
  38. Soluciones
  39. 1-Se creará un modelo de Configuración para los eventos
  40.  
  41. EventsConfiguration(id: integer, account_id: integer, event_type: string, event_attribute_value: float, frequency_time: integer, created_at: datetime, updated_at: datetime)
  42.  
  43. El cual tendrá relación con la cuenta. Una cuenta puede tener muchas configuraciones de eventos.
  44. Dependiendo del evento algunos pueden tener una variable especial event_attribute_value, como es el caso de "speeding", "overheating" y "stop", en donde por ejemplo el evento "stop" esta asociado a la velocidad de detención de un vehículo.
  45.  
  46. Ejemplo de la configuración para evento "stop" para la cuenta (donde se aprecia el valor de event_attribute_value en 1.0, lo cual indica que a esa velocidad el vehículo se detendrá, a su vez posee una frecuencia de 5, lo cual esta expresado en minutos)
  47. id: 21,
  48. account_id: 1,
  49. event_type: "stop",
  50. event_attribute_value: 1.0,
  51. frequency_time: 5
  52.  
  53. Ejemplo de configuración para evento "inside_origin_warehouse", el cual no necesita el atributo event_attribute_value, solo importa su frecuencia.
  54. id: 22,
  55. account_id: 1,
  56. event_type: "inside_origin_warehouse",
  57. event_attribute_value: nil,
  58. frequency_time: 5
  59.  
  60. De este modo se pueden configurar los tipos eventos y sus frecuencias para una cuenta y posterior alerta.
  61.  
  62. 1.1 Alertas-Eventos
  63.  
  64. -Una vez se ha configurado la frecuencia y valores de las alertas, se debería poder enviar alertas con el valor frequency_time, para lo cual con el modelo actual, es un tanto engorroso esto debido a:
  65.  
  66. Al momento de mostrar cada uno de los eventos por frecuencia (posible endpoint), se debería consultar por el antepenúltimo
  67. registro en la base de datos (por tipo) y revisar sí hay una diferencia entre el valor de started_at de ambos (último y antepenúltimo) y si coincide con la frecuencia configurada para ese tipo de evento.
  68.  
  69. PSeudoCode
  70. Controller
  71. @trip = @trip = current_account.trips.where(id: params[:id], active: true).first
  72. # se obtiene el antepenúltimo evento por tipo para un viaje
  73. last_events = %w[overheating speeding stop].map do |el|
  74. Event.where(trip_id: @trip.id, event_type: el).select(:id, :event_type, :started_at, :created_at).second_to_last
  75. end.compact
  76. # se obtienen las configuraciones de eventos para la cuenta actual
  77. configurations = current_account.events_configurations.select(:id, :event_type, :frequency_time)
  78.  
  79. EventSerializer
  80. attribute :event_configurations do |object, params|
  81. configurations = params[:configurations].as_json
  82. last_events = params[:last_events].as_json
  83. frequency_event = configurations.detect{|el| el['event_type'] == object.event_type }['frequency_time']
  84. ant_event = last_events.detect{|el| el['event_type'] == object.event_type }
  85. ((object.started_at - Time.parse(ant_event['started_at'])) / 1.minute) == frequency_event
  86. end
  87.  
  88. PseudoCode Solo Controller
  89. def trip_events
  90. from = parse_datetime(params[:from])
  91. result = from.present? ? @trip.events.filter_by_created_at(from) : @trip.events
  92. result = result.not_internal
  93. antep_events = %w[overheating speeding stop].map do |x|
  94. Event.where(trip_id: @trip.id, event_type: x, ended_at: nil).select(:id, :event_type, :started_at, :created_at).second_to_last
  95. end.compact.as_json
  96. configurations = current_account.events_configurations.select(:id, :event_type, :frequency_time).as_json
  97.  
  98. final = result.map do |object|
  99. frequency_event = configurations.detect{|el| el['event_type'] == object.event_type }['frequency_time']
  100. ant_event = antep_events.detect{|el| el['event_type'] == object.event_type }
  101. object.id if ((object.started_at - Time.parse(ant_event['started_at'])) / 1.minute) >= frequency_event
  102. end
  103. result = result.not_internal.where(id: final.compact)
  104. render json: json_api_serializer(path: 'events_api_v1_activities_trip_path',
  105. object: result,
  106. resource: Event)
  107. end
  108.  
  109. Se debe Agregar columna read:boolean a modelo Event, además de varios scopes como el de unread
  110.  
  111. PRO:
  112. Quizás puede ser una forma rápida de la solución
  113.  
  114. CONTRA:
  115. El performance es bastante perjudicial al realizar tanta comparación.
  116.  
  117. 2- En un comienzo se utilizaría el punto 1 para los eventos y configuraciones
  118. 2.1 - Alertas-Eventos
  119.  
  120. Se crearía un modelo Notification
  121. notifiable, events, trucks, etc
  122. Notification(:account_id, :notifiable_type, :notifiable_id, :read:bool)
  123.  
  124. Una vez que se dispara un evento con el algoritmo de procesamiento de puntos, mediante algún servicio más un worker se procesarían las alertas
  125.  
  126. PseudoCode
  127. frequency_time = account.events_configurations.where(event_type: 'event_type').frequency_time
  128. Se verifica si existe una notificación, sino se crea, luego cuando llegue la segunda notificación, se verifica el tiempo
  129. actual (started_at) del evento y de la última notificación, si estos dan como resultado que valor de la frecuencia para ese tipo de evento es mayor o igual se envía otra notificación
  130.  
  131. last_notification = Notification.where(notifiable: event)
  132. event_stop = Event.started_at
  133. ((event_stop.started_at - last_notification.created_at) / 1.minute) >= frequency_time
  134.  
  135. PRO:
  136. Se delega la responsabilidad en un modelo con relación al evento
  137. Mejor performance
  138. Reutilización de modelo para posteriores alertas
  139.  
  140. CONTRA:
  141. Dependiente de algoritmo, realizar algunos cambios
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement