require 'digest/sha1'
require 'active_support'
require 'active_support/core_ext/hash'

module StreamService
  TIME_STAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'

  class Item

    attr_reader :id, :stream_id, :ts, :type

    def initialize(id:, stream_id:, ts:, type:)
      @id        = id.to_i
      @stream_id = stream_id
      @ts        = (DateTime.parse(ts, StreamService::TIME_STAMP_FORMAT) if ts.is_a? String) || ts
      @type      = type
    end

    def self.from_post(post_id:, user_id:, timestamp: DateTime.now, is_repost: false)
      self.new(
        id:        post_id,
        stream_id: StreamService.format_stream_id(user_id),
        ts:        timestamp,
        type:      is_repost ? 1:0
      )
    end

    def as_json
      {
        id:        @id.to_s,
        stream_id: @stream_id,
        ts:        @ts.strftime(StreamService::TIME_STAMP_FORMAT),
        type:      @type
      }
    end
  end
end

require 'digest/sha1'
require 'active_support'
require 'active_support/core_ext/hash'

module StreamService
  TIME_STAMP_FORMAT = '%Y-%m-%dT%H:%M:%S.%6N%:z'

  class Item

    attr_reader :id, :stream_id, :ts, :type

    def initialize(id:, stream_id:, ts:, type:)
      @id        = id.to_i
      @stream_id = stream_id
      @ts        = (DateTime.parse(ts, StreamService::TIME_STAMP_FORMAT) if ts.is_a? String) || ts
      @type      = type
    end

    def self.from_post(post_id:, user_id:, timestamp: DateTime.now, is_repost: false)
      self.new(
        id:        post_id,
        stream_id: StreamService.format_stream_id(user_id),
        ts:        timestamp,
        type:      is_repost ? 1:0
      )
    end

    def as_json
      {
        id:        @id.to_s,
        stream_id: @stream_id,
        ts:        @ts.strftime(StreamService::TIME_STAMP_FORMAT),
        type:      @type
      }
    end
  end
end

Reduce precision sent to roshi to match db.
Reduce precision sent to roshi to match db.

This ensures that roshi only cares about microseconds and nanoseconds
are discarded. This is important because postgres only stores
microsecond precision. In cases where we write to the stream from an
object recently created in ruby memory we have nanosecond precision.

Due to the nature of roshi adding/removal of items from streams has a
"highest score wins" approach. In our case ts is our score.

This fix ensures that all writes to streams can be removed, as both
addition and removal will be the same timestamp.
