jetstream_bridge 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -4
- data/Gemfile.lock +1 -1
- data/lib/jetstream_bridge/models/inbox_event.rb +41 -33
- data/lib/jetstream_bridge/models/outbox_event.rb +34 -18
- data/lib/jetstream_bridge/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 601869d9b83276fd0e3b6a249dafc1bb7a749ffe6aade556077b60b95eb24124
|
4
|
+
data.tar.gz: b7ea75cdabb21f5f71d5ff447cd4a449c470a56ff6a3723737895c1cfa260bbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4de9e146864e60fda36d68380e7bf5485d317d599c689d2594e719c1f71f73da3667d43add5e646289a2e5dc8f4dc93495b2f615b99d90c120d4674684b415fe
|
7
|
+
data.tar.gz: 4b4f148a4dea6c38c108f84f07bb179e601faf8aec06f01cbf495a6b645e14dc11ce805d69ab7c91dbd747966f6f44866d19a9b429e347617fa06e208b159c8c
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -12,9 +12,9 @@ module JetstreamBridge
|
|
12
12
|
self.table_name = 'jetstream_inbox_events'
|
13
13
|
|
14
14
|
class << self
|
15
|
+
# Safe column presence check that never boots a connection during class load.
|
15
16
|
def has_column?(name)
|
16
17
|
return false unless ar_connected?
|
17
|
-
|
18
18
|
connection.schema_cache.columns_hash(table_name).key?(name.to_s)
|
19
19
|
rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::NoDatabaseError
|
20
20
|
false
|
@@ -22,36 +22,51 @@ module JetstreamBridge
|
|
22
22
|
|
23
23
|
def ar_connected?
|
24
24
|
ActiveRecord::Base.connected? && connection_pool.active_connection?
|
25
|
-
rescue
|
25
|
+
rescue
|
26
26
|
false
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
# Validations
|
31
|
-
if_condition = -> { self.class.has_column?(:event_id) }
|
32
|
-
unless_condition = -> { !self.class.has_column?(:event_id) }
|
30
|
+
# ---- Validations (NO with_options; guard everything with procs) ----
|
33
31
|
|
34
|
-
|
32
|
+
# Preferred dedupe key
|
33
|
+
validates :event_id,
|
34
|
+
presence: true,
|
35
|
+
uniqueness: true,
|
36
|
+
if: -> { self.class.has_column?(:event_id) }
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
validates :stream_seq, uniqueness: { scope: :stream }
|
41
|
-
elsif has_column?(:stream_seq)
|
42
|
-
validates :stream_seq, uniqueness: true
|
43
|
-
end
|
44
|
-
end
|
38
|
+
# Fallback to (stream, stream_seq) when event_id column not present
|
39
|
+
validates :stream_seq,
|
40
|
+
presence: true,
|
41
|
+
if: -> { !self.class.has_column?(:event_id) && self.class.has_column?(:stream_seq) }
|
45
42
|
|
46
|
-
validates :
|
43
|
+
validates :stream_seq,
|
44
|
+
uniqueness: { scope: :stream },
|
45
|
+
if: -> {
|
46
|
+
!self.class.has_column?(:event_id) &&
|
47
|
+
self.class.has_column?(:stream_seq) &&
|
48
|
+
self.class.has_column?(:stream)
|
49
|
+
}
|
47
50
|
|
51
|
+
validates :stream_seq,
|
52
|
+
uniqueness: true,
|
53
|
+
if: -> {
|
54
|
+
!self.class.has_column?(:event_id) &&
|
55
|
+
self.class.has_column?(:stream_seq) &&
|
56
|
+
!self.class.has_column?(:stream)
|
57
|
+
}
|
58
|
+
|
59
|
+
validates :subject,
|
60
|
+
presence: true,
|
61
|
+
if: -> { self.class.has_column?(:subject) }
|
62
|
+
|
63
|
+
# ---- Defaults that do not require schema at load time ----
|
48
64
|
before_validation do
|
49
|
-
self.status
|
50
|
-
if self.class.has_column?(:received_at) && received_at.blank?
|
51
|
-
self.received_at ||= Time.now.utc
|
52
|
-
end
|
65
|
+
self.status ||= 'received' if self.class.has_column?(:status) && status.blank?
|
66
|
+
self.received_at ||= Time.now.utc if self.class.has_column?(:received_at) && received_at.blank?
|
53
67
|
end
|
54
68
|
|
69
|
+
# ---- Helpers ----
|
55
70
|
def processed?
|
56
71
|
if self.class.has_column?(:processed_at)
|
57
72
|
processed_at.present?
|
@@ -65,34 +80,27 @@ module JetstreamBridge
|
|
65
80
|
def payload_hash
|
66
81
|
v = self[:payload]
|
67
82
|
case v
|
68
|
-
when String then
|
69
|
-
|
70
|
-
rescue StandardError
|
71
|
-
{}
|
72
|
-
end
|
73
|
-
when Hash then v
|
83
|
+
when String then JSON.parse(v) rescue {}
|
84
|
+
when Hash then v
|
74
85
|
else v.respond_to?(:as_json) ? v.as_json : {}
|
75
86
|
end
|
76
87
|
end
|
77
88
|
end
|
78
89
|
else
|
90
|
+
# Shim: loud failure if AR isn't present but someone calls the model.
|
79
91
|
class InboxEvent
|
80
92
|
class << self
|
81
93
|
def method_missing(method_name, *_args, &_block)
|
82
94
|
raise_missing_ar!('Inbox', method_name)
|
83
95
|
end
|
84
|
-
|
85
|
-
def respond_to_missing?(_m, _p = false)
|
86
|
-
false
|
87
|
-
end
|
96
|
+
def respond_to_missing?(_m, _p = false) = false
|
88
97
|
|
89
98
|
private
|
90
|
-
|
91
99
|
def raise_missing_ar!(which, method_name)
|
92
100
|
raise(
|
93
101
|
"#{which} requires ActiveRecord (tried to call ##{method_name}). " \
|
94
|
-
|
95
|
-
|
102
|
+
'Enable `use_inbox` only in apps with ActiveRecord, or add ' \
|
103
|
+
'`gem \"activerecord\"` to your Gemfile.'
|
96
104
|
)
|
97
105
|
end
|
98
106
|
end
|
@@ -21,40 +21,54 @@ module JetstreamBridge
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def ar_connected?
|
24
|
-
#
|
24
|
+
# Avoid creating a connection; rescue if pool isn't set yet.
|
25
25
|
ActiveRecord::Base.connected? && connection_pool.active_connection?
|
26
26
|
rescue
|
27
27
|
false
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
# ---- Validations guarded by safe schema checks (
|
32
|
-
validates :payload,
|
31
|
+
# ---- Validations guarded by safe schema checks (no with_options) ----
|
32
|
+
validates :payload,
|
33
|
+
presence: true,
|
34
|
+
if: -> { self.class.has_column?(:payload) }
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
36
|
+
# Preferred path when event_id exists
|
37
|
+
validates :event_id,
|
38
|
+
presence: true,
|
39
|
+
uniqueness: true,
|
40
|
+
if: -> { self.class.has_column?(:event_id) }
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
# Fallback legacy fields when event_id is absent
|
43
|
+
validates :resource_type,
|
44
|
+
presence: true,
|
45
|
+
if: -> { !self.class.has_column?(:event_id) && self.class.has_column?(:resource_type) }
|
46
|
+
|
47
|
+
validates :resource_id,
|
48
|
+
presence: true,
|
49
|
+
if: -> { !self.class.has_column?(:event_id) && self.class.has_column?(:resource_id) }
|
43
50
|
|
44
|
-
validates :
|
51
|
+
validates :event_type,
|
52
|
+
presence: true,
|
53
|
+
if: -> { !self.class.has_column?(:event_id) && self.class.has_column?(:event_type) }
|
45
54
|
|
46
|
-
validates :
|
55
|
+
validates :subject,
|
56
|
+
presence: true,
|
57
|
+
if: -> { self.class.has_column?(:subject) }
|
58
|
+
|
59
|
+
validates :attempts,
|
60
|
+
numericality: { only_integer: true, greater_than_or_equal_to: 0 },
|
47
61
|
if: -> { self.class.has_column?(:attempts) }
|
48
62
|
|
49
|
-
# Defaults that do not require schema at load time
|
63
|
+
# ---- Defaults that do not require schema at load time ----
|
50
64
|
before_validation do
|
51
65
|
now = Time.now.utc
|
52
|
-
self.status
|
53
|
-
self.enqueued_at ||= now
|
54
|
-
self.attempts
|
66
|
+
self.status ||= 'pending' if self.class.has_column?(:status) && status.blank?
|
67
|
+
self.enqueued_at ||= now if self.class.has_column?(:enqueued_at) && enqueued_at.blank?
|
68
|
+
self.attempts = 0 if self.class.has_column?(:attempts) && attempts.nil?
|
55
69
|
end
|
56
70
|
|
57
|
-
# Helpers
|
71
|
+
# ---- Helpers ----
|
58
72
|
def mark_sent!
|
59
73
|
now = Time.now.utc
|
60
74
|
self.status = 'sent' if self.class.has_column?(:status)
|
@@ -84,9 +98,11 @@ module JetstreamBridge
|
|
84
98
|
def method_missing(method_name, *_args, &_block)
|
85
99
|
raise_missing_ar!('Outbox', method_name)
|
86
100
|
end
|
101
|
+
|
87
102
|
def respond_to_missing?(_m, _p = false) = false
|
88
103
|
|
89
104
|
private
|
105
|
+
|
90
106
|
def raise_missing_ar!(which, method_name)
|
91
107
|
raise(
|
92
108
|
"#{which} requires ActiveRecord (tried to call ##{method_name}). " \
|