@hraness/peopleblade 0.1.0 → 0.1.2
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.
- package/README.md +22 -6
- package/THIRD_PARTY_NOTICES.md +3 -3
- package/dist/cli.ts +31 -0
- package/dist/cloud-sync-client.js +1827 -0
- package/dist/migrations/015_phone_identity_normalization.sql +15 -0
- package/dist/migrations/016_source_binding_metadata_incarnations.sql +205 -0
- package/dist/peopleblade.js +10210 -5708
- package/package.json +3 -2
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
-- Schema hook for one-shot application-layer phone identity renormalization.
|
|
4
|
+
-- initializeLocalDatabase / rolodex import rewrite contact_methods.normalized_value
|
|
5
|
+
-- with normalizePhoneIdentity and record completion here. Duplicate
|
|
6
|
+
-- (person_id,kind,normalized_value,label) rows are deactivated, not deleted.
|
|
7
|
+
CREATE TABLE phone_identity_renormalization (
|
|
8
|
+
singleton INTEGER PRIMARY KEY CHECK(singleton = 1),
|
|
9
|
+
algorithm_version TEXT NOT NULL CHECK(length(algorithm_version) BETWEEN 1 AND 64),
|
|
10
|
+
applied_at TEXT NOT NULL,
|
|
11
|
+
methods_scanned INTEGER NOT NULL CHECK(methods_scanned >= 0),
|
|
12
|
+
methods_updated INTEGER NOT NULL CHECK(methods_updated >= 0),
|
|
13
|
+
methods_deactivated INTEGER NOT NULL CHECK(methods_deactivated >= 0),
|
|
14
|
+
methods_inserted INTEGER NOT NULL CHECK(methods_inserted >= 0)
|
|
15
|
+
) STRICT;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
-- Schema v13 admitted same-identity guards only to reject them later. Purge
|
|
4
|
+
-- those impossible predecessors while the v14 invalidation trigger still
|
|
5
|
+
-- recognizes them, before metadata-only successors become valid.
|
|
6
|
+
DELETE FROM source_binding_transition_guards
|
|
7
|
+
WHERE NOT EXISTS (
|
|
8
|
+
SELECT 1 FROM source_binding_incarnations successor
|
|
9
|
+
WHERE successor.source_binding_id=source_binding_transition_guards.source_binding_id
|
|
10
|
+
AND successor.ordinal=source_binding_transition_guards.next_ordinal
|
|
11
|
+
)
|
|
12
|
+
AND EXISTS (
|
|
13
|
+
SELECT 1 FROM source_binding_incarnations predecessor
|
|
14
|
+
WHERE predecessor.id=source_binding_transition_guards.retiring_incarnation_id
|
|
15
|
+
AND predecessor.source_binding_id=source_binding_transition_guards.source_binding_id
|
|
16
|
+
AND predecessor.authority=source_binding_transition_guards.authority
|
|
17
|
+
AND predecessor.retired_at IS NULL
|
|
18
|
+
AND predecessor.subject_sha256=source_binding_transition_guards.next_subject_sha256
|
|
19
|
+
AND predecessor.auth_sha256=source_binding_transition_guards.next_auth_sha256
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
DROP TRIGGER source_binding_transition_guards_snapshot_insert;
|
|
23
|
+
|
|
24
|
+
CREATE TRIGGER source_binding_transition_guards_snapshot_insert
|
|
25
|
+
BEFORE INSERT ON source_binding_transition_guards FOR EACH ROW
|
|
26
|
+
WHEN NOT EXISTS (
|
|
27
|
+
SELECT 1 FROM source_binding_incarnations incarnation
|
|
28
|
+
JOIN source_bindings binding ON binding.id=incarnation.source_binding_id
|
|
29
|
+
WHERE incarnation.id=NEW.retiring_incarnation_id
|
|
30
|
+
AND incarnation.source_binding_id=NEW.source_binding_id
|
|
31
|
+
AND incarnation.retired_at IS NULL
|
|
32
|
+
AND incarnation.ordinal+1=NEW.next_ordinal
|
|
33
|
+
AND incarnation.authority=NEW.authority
|
|
34
|
+
AND julianday(NEW.observed_at)>=julianday(incarnation.last_seen_at)
|
|
35
|
+
AND incarnation.last_seen_at=NEW.expected_last_seen_at
|
|
36
|
+
AND incarnation.metadata_json=NEW.expected_metadata_json
|
|
37
|
+
AND binding.authority=NEW.authority
|
|
38
|
+
AND binding.subject_sha256=incarnation.subject_sha256
|
|
39
|
+
AND binding.auth_sha256=incarnation.auth_sha256
|
|
40
|
+
AND binding.last_seen_at=NEW.expected_last_seen_at
|
|
41
|
+
AND binding.metadata_json=NEW.expected_metadata_json
|
|
42
|
+
AND binding.complete_realm_inventory_observed_at
|
|
43
|
+
IS NEW.expected_complete_realm_inventory_observed_at
|
|
44
|
+
AND binding.complete_realm_inventory_sha256
|
|
45
|
+
IS NEW.expected_complete_realm_inventory_sha256
|
|
46
|
+
AND (
|
|
47
|
+
(
|
|
48
|
+
(incarnation.subject_sha256<>NEW.next_subject_sha256
|
|
49
|
+
OR incarnation.auth_sha256<>NEW.next_auth_sha256)
|
|
50
|
+
AND NOT EXISTS (
|
|
51
|
+
SELECT 1 FROM source_binding_incarnations owner
|
|
52
|
+
WHERE owner.authority=NEW.authority
|
|
53
|
+
AND owner.subject_sha256=NEW.next_subject_sha256
|
|
54
|
+
AND owner.source_binding_id<>NEW.source_binding_id
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
OR (
|
|
58
|
+
incarnation.subject_sha256=NEW.next_subject_sha256
|
|
59
|
+
AND incarnation.auth_sha256=NEW.next_auth_sha256
|
|
60
|
+
AND incarnation.metadata_json<>NEW.metadata_json
|
|
61
|
+
AND NEW.expected_complete_realm_inventory_observed_at IS NOT NULL
|
|
62
|
+
AND NEW.expected_complete_realm_inventory_sha256 IS NOT NULL
|
|
63
|
+
AND NEW.complete_realm_inventory_sha256
|
|
64
|
+
=NEW.expected_complete_realm_inventory_sha256
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
BEGIN SELECT RAISE(ABORT, 'source binding transition guard does not match current reviewed state'); END;
|
|
69
|
+
|
|
70
|
+
DROP TRIGGER source_binding_incarnations_chain_insert;
|
|
71
|
+
|
|
72
|
+
CREATE TRIGGER source_binding_incarnations_chain_insert
|
|
73
|
+
BEFORE INSERT ON source_binding_incarnations FOR EACH ROW
|
|
74
|
+
WHEN NEW.transition_kind='explicit-rebind' AND NOT EXISTS (
|
|
75
|
+
SELECT 1 FROM source_binding_incarnations previous
|
|
76
|
+
WHERE previous.id=NEW.previous_incarnation_id
|
|
77
|
+
AND previous.source_binding_id=NEW.source_binding_id
|
|
78
|
+
AND previous.authority=NEW.authority
|
|
79
|
+
AND previous.ordinal=NEW.ordinal-1
|
|
80
|
+
AND previous.retired_at IS NOT NULL
|
|
81
|
+
AND (
|
|
82
|
+
previous.subject_sha256<>NEW.subject_sha256
|
|
83
|
+
OR previous.auth_sha256<>NEW.auth_sha256
|
|
84
|
+
OR previous.metadata_json<>NEW.metadata_json
|
|
85
|
+
)
|
|
86
|
+
AND EXISTS (
|
|
87
|
+
SELECT 1 FROM source_bindings binding
|
|
88
|
+
WHERE binding.id=NEW.source_binding_id AND binding.authority=NEW.authority
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
BEGIN SELECT RAISE(ABORT, 'source binding incarnation predecessor is invalid'); END;
|
|
92
|
+
|
|
93
|
+
-- Schema v13 mirrored an older writer's root metadata into the current
|
|
94
|
+
-- incarnation. Preserve that compatibility only while the writer is not
|
|
95
|
+
-- attempting to overwrite an already-installed successor. The atomic
|
|
96
|
+
-- transition trigger inserts the successor before updating the root shadow, so
|
|
97
|
+
-- its target metadata already equals the one current incarnation here.
|
|
98
|
+
CREATE TRIGGER source_bindings_current_incarnation_metadata_guard
|
|
99
|
+
BEFORE UPDATE OF metadata_json ON source_bindings FOR EACH ROW
|
|
100
|
+
WHEN EXISTS (
|
|
101
|
+
SELECT 1 FROM source_binding_incarnations current
|
|
102
|
+
WHERE current.source_binding_id=NEW.id
|
|
103
|
+
AND current.authority=NEW.authority
|
|
104
|
+
AND current.retired_at IS NULL
|
|
105
|
+
AND current.metadata_json<>NEW.metadata_json
|
|
106
|
+
)
|
|
107
|
+
BEGIN SELECT RAISE(ABORT, 'source binding metadata must shadow its current incarnation'); END;
|
|
108
|
+
|
|
109
|
+
DROP TRIGGER source_binding_transition_guards_consumed_delete;
|
|
110
|
+
|
|
111
|
+
CREATE TRIGGER source_binding_transition_guards_consumed_delete
|
|
112
|
+
BEFORE DELETE ON source_binding_transition_guards FOR EACH ROW
|
|
113
|
+
WHEN NOT (
|
|
114
|
+
(
|
|
115
|
+
EXISTS (
|
|
116
|
+
SELECT 1 FROM source_binding_incarnations predecessor
|
|
117
|
+
WHERE predecessor.id=OLD.retiring_incarnation_id
|
|
118
|
+
AND predecessor.source_binding_id=OLD.source_binding_id
|
|
119
|
+
AND predecessor.authority=OLD.authority
|
|
120
|
+
AND predecessor.ordinal=OLD.next_ordinal-1
|
|
121
|
+
AND predecessor.retired_at=OLD.observed_at
|
|
122
|
+
AND predecessor.last_seen_at=OLD.expected_last_seen_at
|
|
123
|
+
AND predecessor.metadata_json=OLD.expected_metadata_json
|
|
124
|
+
)
|
|
125
|
+
AND EXISTS (
|
|
126
|
+
SELECT 1 FROM source_binding_incarnations successor
|
|
127
|
+
WHERE successor.source_binding_id=OLD.source_binding_id
|
|
128
|
+
AND successor.authority=OLD.authority
|
|
129
|
+
AND successor.ordinal=OLD.next_ordinal
|
|
130
|
+
AND successor.subject_sha256=OLD.next_subject_sha256
|
|
131
|
+
AND successor.auth_sha256=OLD.next_auth_sha256
|
|
132
|
+
AND successor.previous_incarnation_id=OLD.retiring_incarnation_id
|
|
133
|
+
AND successor.transition_kind='explicit-rebind'
|
|
134
|
+
AND successor.transition_evidence_sha256=OLD.transition_evidence_sha256
|
|
135
|
+
AND successor.transition_evidence_json=OLD.transition_evidence_json
|
|
136
|
+
AND successor.first_seen_at=OLD.observed_at
|
|
137
|
+
AND successor.last_seen_at=OLD.observed_at
|
|
138
|
+
AND successor.retired_at IS NULL
|
|
139
|
+
AND successor.metadata_json=OLD.metadata_json
|
|
140
|
+
)
|
|
141
|
+
AND EXISTS (
|
|
142
|
+
SELECT 1 FROM source_bindings binding
|
|
143
|
+
WHERE binding.id=OLD.source_binding_id
|
|
144
|
+
AND binding.authority=OLD.authority
|
|
145
|
+
AND binding.subject_sha256=OLD.next_subject_sha256
|
|
146
|
+
AND binding.auth_sha256=OLD.next_auth_sha256
|
|
147
|
+
AND binding.last_seen_at=OLD.observed_at
|
|
148
|
+
AND binding.complete_realm_inventory_observed_at=OLD.observed_at
|
|
149
|
+
AND binding.complete_realm_inventory_sha256=OLD.complete_realm_inventory_sha256
|
|
150
|
+
AND binding.metadata_json=OLD.metadata_json
|
|
151
|
+
)
|
|
152
|
+
)
|
|
153
|
+
OR (
|
|
154
|
+
NOT EXISTS (
|
|
155
|
+
SELECT 1 FROM source_binding_incarnations successor
|
|
156
|
+
WHERE successor.source_binding_id=OLD.source_binding_id
|
|
157
|
+
AND successor.ordinal=OLD.next_ordinal
|
|
158
|
+
)
|
|
159
|
+
AND EXISTS (
|
|
160
|
+
SELECT 1 FROM source_binding_incarnations predecessor
|
|
161
|
+
JOIN source_bindings binding ON binding.id=predecessor.source_binding_id
|
|
162
|
+
WHERE predecessor.id=OLD.retiring_incarnation_id
|
|
163
|
+
AND predecessor.source_binding_id=OLD.source_binding_id
|
|
164
|
+
AND predecessor.authority=OLD.authority
|
|
165
|
+
AND predecessor.ordinal=OLD.next_ordinal-1
|
|
166
|
+
AND predecessor.retired_at IS NULL
|
|
167
|
+
AND binding.authority=OLD.authority
|
|
168
|
+
AND binding.subject_sha256=predecessor.subject_sha256
|
|
169
|
+
AND binding.auth_sha256=predecessor.auth_sha256
|
|
170
|
+
AND (
|
|
171
|
+
(
|
|
172
|
+
predecessor.subject_sha256=OLD.next_subject_sha256
|
|
173
|
+
AND predecessor.auth_sha256=OLD.next_auth_sha256
|
|
174
|
+
AND predecessor.metadata_json=OLD.metadata_json
|
|
175
|
+
)
|
|
176
|
+
OR julianday(OLD.observed_at)<julianday(predecessor.last_seen_at)
|
|
177
|
+
OR predecessor.last_seen_at IS NOT OLD.expected_last_seen_at
|
|
178
|
+
OR predecessor.metadata_json IS NOT OLD.expected_metadata_json
|
|
179
|
+
OR binding.last_seen_at IS NOT OLD.expected_last_seen_at
|
|
180
|
+
OR binding.metadata_json IS NOT OLD.expected_metadata_json
|
|
181
|
+
OR binding.complete_realm_inventory_observed_at
|
|
182
|
+
IS NOT OLD.expected_complete_realm_inventory_observed_at
|
|
183
|
+
OR binding.complete_realm_inventory_sha256
|
|
184
|
+
IS NOT OLD.expected_complete_realm_inventory_sha256
|
|
185
|
+
OR (
|
|
186
|
+
predecessor.subject_sha256=OLD.next_subject_sha256
|
|
187
|
+
AND predecessor.auth_sha256=OLD.next_auth_sha256
|
|
188
|
+
AND (
|
|
189
|
+
OLD.expected_complete_realm_inventory_observed_at IS NULL
|
|
190
|
+
OR OLD.expected_complete_realm_inventory_sha256 IS NULL
|
|
191
|
+
OR OLD.complete_realm_inventory_sha256
|
|
192
|
+
IS NOT OLD.expected_complete_realm_inventory_sha256
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
OR EXISTS (
|
|
196
|
+
SELECT 1 FROM source_binding_incarnations owner
|
|
197
|
+
WHERE owner.authority=OLD.authority
|
|
198
|
+
AND owner.subject_sha256=OLD.next_subject_sha256
|
|
199
|
+
AND owner.source_binding_id<>OLD.source_binding_id
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
BEGIN SELECT RAISE(ABORT, 'source binding transition guard can only be deleted after exact consumption or proven invalidation'); END;
|