paper_trail-background 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 801abe0ea0d7e83c628f71db2a9983b00af26f9b68a66a2e5cc79fce306abb2c
4
- data.tar.gz: 68e276d1635253b002c84eb45b644cc85d9e4b35f1595da87de4552a6755b31d
3
+ metadata.gz: 7fc0974202e685594acc5eed60867bac3a7153fc660b92b5495a06926cf181cb
4
+ data.tar.gz: a486bc4b7221801ec0712595b13c60c30734352ec79b3c6fe821416c0ad3d1cf
5
5
  SHA512:
6
- metadata.gz: 45f4ddea7993170dad7a1c611bf21b3097a090764a0c19f962f07431047d2e05726645e29afd7d12e90796dc151f032329b556e27369f9eb19ec864b7022de4e
7
- data.tar.gz: 26b673571563ed840b85dc63faa4da4144bd017948f0c33b7b8001cf20cb249e8e4c6a8fe409884767bf6bfeb4858041e01d97e7f846a4f064cf427ed84645b2
6
+ metadata.gz: ff6250a3ae16dc8cc55d08f03579dd20cdfcfaaa9a63e0752e5312b94b570fb87b25f618bd9b6e70e4e8be923dbf25ea8a8f4adc1ed5de9f628d6c47d7438b63
7
+ data.tar.gz: c14b0a815e41a81e3a30c4b7a262b9bde349bcb3af5b405196098eb3e29572c15840994d97829217af67269aa52453bf4814c7b6b8cf6a197b371093f2a18602
data/LICENSE ADDED
@@ -0,0 +1,420 @@
1
+ HIPPOCRATIC LICENSE
2
+
3
+ Version 3.0, October 2021
4
+
5
+ https://firstdonoharm.dev/version/3/0/bod-cl-eco-extr-ffd-law-media-mil-my-soc-sup-sv-tal-xuar.txt
6
+
7
+ TERMS AND CONDITIONS
8
+
9
+ TERMS AND CONDITIONS FOR USE, COPY, MODIFICATION, PREPARATION OF DERIVATIVE
10
+ WORK, REPRODUCTION, AND DISTRIBUTION:
11
+
12
+ 1. DEFINITIONS:
13
+
14
+ This section defines certain terms used throughout this license agreement.
15
+
16
+ 1.1. “License” means the terms and conditions, as stated herein, for use, copy,
17
+ modification, preparation of derivative work, reproduction, and distribution of
18
+ Software (as defined below).
19
+
20
+ 1.2. “Licensor” means the copyright and/or patent owner or entity authorized by
21
+ the copyright and/or patent owner that is granting the License.
22
+
23
+ 1.3. “Licensee” means the individual or entity exercising permissions granted by
24
+ this License, including the use, copy, modification, preparation of derivative
25
+ work, reproduction, and distribution of Software (as defined below).
26
+
27
+ 1.4. “Software” means any copyrighted work, including but not limited to
28
+ software code, authored by Licensor and made available under this License.
29
+
30
+ 1.5. “Supply Chain” means the sequence of processes involved in the production
31
+ and/or distribution of a commodity, good, or service offered by the Licensee.
32
+
33
+ 1.6. “Supply Chain Impacted Party” or “Supply Chain Impacted Parties” means any
34
+ person(s) directly impacted by any of Licensee’s Supply Chain, including the
35
+ practices of all persons or entities within the Supply Chain prior to a good or
36
+ service reaching the Licensee.
37
+
38
+ 1.7. “Duty of Care” is defined by its use in tort law, delict law, and/or
39
+ similar bodies of law closely related to tort and/or delict law, including
40
+ without limitation, a requirement to act with the watchfulness, attention,
41
+ caution, and prudence that a reasonable person in the same or similar
42
+ circumstances would use towards any Supply Chain Impacted Party.
43
+
44
+ 1.8. “Worker” is defined to include any and all permanent, temporary, and agency
45
+ workers, as well as piece-rate, salaried, hourly paid, legal young (minors),
46
+ part-time, night, and migrant workers.
47
+
48
+ 2. INTELLECTUAL PROPERTY GRANTS:
49
+
50
+ This section identifies intellectual property rights granted to a Licensee.
51
+
52
+ 2.1. Grant of Copyright License: Subject to the terms and conditions of this
53
+ License, Licensor hereby grants to Licensee a worldwide, non-exclusive,
54
+ no-charge, royalty-free copyright license to use, copy, modify, prepare
55
+ derivative work, reproduce, or distribute the Software, Licensor authored
56
+ modified software, or other work derived from the Software.
57
+
58
+ 2.2. Grant of Patent License: Subject to the terms and conditions of this
59
+ License, Licensor hereby grants Licensee a worldwide, non-exclusive, no-charge,
60
+ royalty-free patent license to make, have made, use, offer to sell, sell,
61
+ import, and otherwise transfer Software.
62
+
63
+ 3. ETHICAL STANDARDS:
64
+
65
+ This section lists conditions the Licensee must comply with in order to have
66
+ rights under this License.
67
+
68
+ The rights granted to the Licensee by this License are expressly made subject to
69
+ the Licensee’s ongoing compliance with the following conditions:
70
+
71
+ * 3.1. The Licensee SHALL NOT, whether directly or indirectly, through agents
72
+ or assigns:
73
+
74
+ * 3.1.1. Infringe upon any person’s right to life or security of person,
75
+ engage in extrajudicial killings, or commit murder, without lawful cause
76
+ (See Article 3, United Nations Universal Declaration of Human Rights;
77
+ Article 6, International Covenant on Civil and Political Rights)
78
+
79
+ * 3.1.2. Hold any person in slavery, servitude, or forced labor (See Article
80
+ 4, United Nations Universal Declaration of Human Rights; Article 8,
81
+ International Covenant on Civil and Political Rights);
82
+
83
+ * 3.1.3. Contribute to the institution of slavery, slave trading, forced
84
+ labor, or unlawful child labor (See Article 4, United Nations Universal
85
+ Declaration of Human Rights; Article 8, International Covenant on Civil and
86
+ Political Rights);
87
+
88
+ * 3.1.4. Torture or subject any person to cruel, inhumane, or degrading
89
+ treatment or punishment (See Article 5, United Nations Universal
90
+ Declaration of Human Rights; Article 7, International Covenant on Civil and
91
+ Political Rights);
92
+
93
+ * 3.1.5. Discriminate on the basis of sex, gender, sexual orientation, race,
94
+ ethnicity, nationality, religion, caste, age, medical disability or
95
+ impairment, and/or any other like circumstances (See Article 7, United
96
+ Nations Universal Declaration of Human Rights; Article 2, International
97
+ Covenant on Economic, Social and Cultural Rights; Article 26, International
98
+ Covenant on Civil and Political Rights);
99
+
100
+ * 3.1.6. Prevent any person from exercising his/her/their right to seek an
101
+ effective remedy by a competent court or national tribunal (including
102
+ domestic judicial systems, international courts, arbitration bodies, and
103
+ other adjudicating bodies) for actions violating the fundamental rights
104
+ granted to him/her/them by applicable constitutions, applicable laws, or by
105
+ this License (See Article 8, United Nations Universal Declaration of Human
106
+ Rights; Articles 9 and 14, International Covenant on Civil and Political
107
+ Rights);
108
+
109
+ * 3.1.7. Subject any person to arbitrary arrest, detention, or exile (See
110
+ Article 9, United Nations Universal Declaration of Human Rights; Article 9,
111
+ International Covenant on Civil and Political Rights);
112
+
113
+ * 3.1.8. Subject any person to arbitrary interference with a person’s
114
+ privacy, family, home, or correspondence without the express written
115
+ consent of the person (See Article 12, United Nations Universal Declaration
116
+ of Human Rights; Article 17, International Covenant on Civil and Political
117
+ Rights);
118
+
119
+ * 3.1.9. Arbitrarily deprive any person of his/her/their property (See
120
+ Article 17, United Nations Universal Declaration of Human Rights);
121
+
122
+ * 3.1.10. Forcibly remove indigenous peoples from their lands or territories
123
+ or take any action with the aim or effect of dispossessing indigenous
124
+ peoples from their lands, territories, or resources, including without
125
+ limitation the intellectual property or traditional knowledge of indigenous
126
+ peoples, without the free, prior, and informed consent of indigenous
127
+ peoples concerned (See Articles 8 and 10, United Nations Declaration on the
128
+ Rights of Indigenous Peoples);
129
+
130
+ * 3.1.11. Fossil Fuel Divestment: Be an individual or entity, or a
131
+ representative, agent, affiliate, successor, attorney, or assign of an
132
+ individual or entity, on the FFI Solutions Carbon Underground 200 list
133
+ [https://www.ffisolutions.com/research-analytics-index-solutions/research-screening/the-carbon-underground-200/?cn-reloaded=1];
134
+
135
+ * 3.1.12. Ecocide: Commit ecocide:
136
+
137
+ * 3.1.12.1. For the purpose of this section, “ecocide” means unlawful or
138
+ wanton acts committed with knowledge that there is a substantial
139
+ likelihood of severe and either widespread or long-term damage to the
140
+ environment being caused by those acts;
141
+
142
+ * 3.1.12.2. For the purpose of further defining ecocide and the terms
143
+ contained in the previous paragraph:
144
+
145
+ * 3.1.12.2.1. “Wanton” means with reckless disregard for damage which
146
+ would be clearly excessive in relation to the social and economic
147
+ benefits anticipated;
148
+
149
+ * 3.1.12.2.2. “Severe” means damage which involves very serious adverse
150
+ changes, disruption, or harm to any element of the environment,
151
+ including grave impacts on human life or natural, cultural, or
152
+ economic resources;
153
+
154
+ * 3.1.12.2.3. “Widespread” means damage which extends beyond a limited
155
+ geographic area, crosses state boundaries, or is suffered by an entire
156
+ ecosystem or species or a large number of human beings;
157
+
158
+ * 3.1.12.2.4. “Long-term” means damage which is irreversible or which
159
+ cannot be redressed through natural recovery within a reasonable
160
+ period of time; and
161
+
162
+ * 3.1.12.2.5. “Environment” means the earth, its biosphere, cryosphere,
163
+ lithosphere, hydrosphere, and atmosphere, as well as outer space
164
+
165
+ (See Section II, Independent Expert Panel for the Legal Definition of
166
+ Ecocide, Stop Ecocide Foundation and the Promise Institute for Human
167
+ Rights at UCLA School of Law, June 2021);
168
+
169
+ * 3.1.13. Extractive Industries: Be an individual or entity, or a
170
+ representative, agent, affiliate, successor, attorney, or assign of an
171
+ individual or entity, that engages in fossil fuel or mineral exploration,
172
+ extraction, development, or sale;
173
+
174
+ * 3.1.14. Taliban: Be an individual or entity that:
175
+
176
+ * 3.1.14.1. engages in any commercial transactions with the Taliban; or
177
+
178
+ * 3.1.14.2. is a representative, agent, affiliate, successor, attorney, or
179
+ assign of the Taliban;
180
+
181
+ * 3.1.15. Myanmar: Be an individual or entity that:
182
+
183
+ * 3.1.15.1. engages in any commercial transactions with the
184
+ Myanmar/Burmese military junta; or
185
+
186
+ * 3.1.15.2. is a representative, agent, affiliate, successor, attorney, or
187
+ assign of the Myanmar/Burmese government;
188
+
189
+ * 3.1.16. Xinjiang Uygur Autonomous Region: Be an individual or entity, or a
190
+ representative, agent, affiliate, successor, attorney, or assign of any
191
+ individual or entity, that does business in, purchases goods from, or
192
+ otherwise benefits from goods produced in the Xinjiang Uygur Autonomous
193
+ Region of China;
194
+
195
+ * 3.1.17. Mass Surveillance: Be a government agency or multinational
196
+ corporation, or a representative, agent, affiliate, successor, attorney,
197
+ or assign of a government or multinational corporation, which participates
198
+ in mass surveillance programs;
199
+
200
+ * 3.1.18. Military Activities: Be an entity or a representative, agent,
201
+ affiliate, successor, attorney, or assign of an entity which conducts
202
+ military activities;
203
+
204
+ * 3.1.19. Law Enforcement: Be an individual or entity, or a or a
205
+ representative, agent, affiliate, successor, attorney, or assign of an
206
+ individual or entity, that provides good or services to, or otherwise
207
+ enters into any commercial contracts with, any local, state, or federal
208
+ law enforcement agency;
209
+
210
+ * 3.1.20. Media: Be an individual or entity, or a or a representative,
211
+ agent, affiliate, successor, attorney, or assign of an individual or
212
+ entity, that broadcasts messages promoting killing, torture, or other
213
+ forms of extreme violence;
214
+
215
+ * 3.1.21. Interfere with Workers' free exercise of the right to organize and
216
+ associate (See Article 20, United Nations Universal Declaration of Human
217
+ Rights; C087 - Freedom of Association and Protection of the Right to
218
+ Organise Convention, 1948 (No. 87), International Labour Organization;
219
+ Article 8, International Covenant on Economic, Social and Cultural Rights);
220
+ and
221
+
222
+ * 3.1.22. Harm the environment in a manner inconsistent with local, state,
223
+ national, or international law.
224
+
225
+ * 3.2. The Licensee SHALL:
226
+
227
+ * 3.2.1. Social Auditing: Only use social auditing mechanisms that adhere to
228
+ Worker-Driven Social Responsibility Network’s Statement of Principles
229
+ (https://wsr-network.org/what-is-wsr/statement-of-principles/
230
+ [https://wsr-network.org/what-is-wsr/statement-of-principles/]) over
231
+ traditional social auditing mechanisms, to the extent the Licensee uses
232
+ any social auditing mechanisms at all;
233
+
234
+ * 3.2.2. Workers on Board of Directors: Ensure that if the Licensee has a
235
+ Board of Directors, 30% of Licensee’s board seats are held by Workers paid
236
+ no more than 200% of the compensation of the lowest paid Worker of the
237
+ Licensee;
238
+
239
+ * 3.2.3. Supply Chain: Provide clear, accessible supply chain data to the
240
+ public in accordance with the following conditions:
241
+
242
+ * 3.2.3.1. All data will be on Licensee’s website and/or, to the extent
243
+ Licensee is a representative, agent, affiliate, successor, attorney,
244
+ subsidiary, or assign, on Licensee’s principal’s or parent’s website or
245
+ some other online platform accessible to the public via an internet
246
+ search on a common internet search engine; and
247
+
248
+ * 3.2.3.2. Data published will include, where applicable, manufacturers,
249
+ top tier suppliers, subcontractors, cooperatives, component parts
250
+ producers, and farms;
251
+
252
+ * 3.2.4. Provide equal pay for equal work where the performance of such work
253
+ requires equal skill, effort, and responsibility, and which are performed
254
+ under similar working conditions, except where such payment is made
255
+ pursuant to:
256
+
257
+ * 3.2.4.1. A seniority system;
258
+
259
+ * 3.2.4.2. A merit system;
260
+
261
+ * 3.2.4.3. A system which measures earnings by quantity or quality of
262
+ production; or
263
+
264
+ * 3.2.4.4. A differential based on any other factor other than sex, gender,
265
+ sexual orientation, race, ethnicity, nationality, religion, caste, age,
266
+ medical disability or impairment, and/or any other like circumstances
267
+ (See 29 U.S.C.A. § 206(d)(1); Article 23, United Nations Universal
268
+ Declaration of Human Rights; Article 7, International Covenant on
269
+ Economic, Social and Cultural Rights; Article 26, International Covenant
270
+ on Civil and Political Rights); and
271
+
272
+ * 3.2.5. Allow for reasonable limitation of working hours and periodic
273
+ holidays with pay (See Article 24, United Nations Universal Declaration of
274
+ Human Rights; Article 7, International Covenant on Economic, Social and
275
+ Cultural Rights).
276
+
277
+ 4. SUPPLY CHAIN IMPACTED PARTIES:
278
+
279
+ This section identifies additional individuals or entities that a Licensee could
280
+ harm as a result of violating the Ethical Standards section, the condition that
281
+ the Licensee must voluntarily accept a Duty of Care for those individuals or
282
+ entities, and the right to a private right of action that those individuals or
283
+ entities possess as a result of violations of the Ethical Standards section.
284
+
285
+ 4.1. In addition to the above Ethical Standards, Licensee voluntarily accepts a
286
+ Duty of Care for Supply Chain Impacted Parties of this License, including
287
+ individuals and communities impacted by violations of the Ethical Standards. The
288
+ Duty of Care is breached when a provision within the Ethical Standards section
289
+ is violated by a Licensee, one of its successors or assigns, or by an individual
290
+ or entity that exists within the Supply Chain prior to a good or service
291
+ reaching the Licensee.
292
+
293
+ 4.2. Breaches of the Duty of Care, as stated within this section, shall create a
294
+ private right of action, allowing any Supply Chain Impacted Party harmed by the
295
+ Licensee to take legal action against the Licensee in accordance with applicable
296
+ negligence laws, whether they be in tort law, delict law, and/or similar bodies
297
+ of law closely related to tort and/or delict law, regardless if Licensee is
298
+ directly responsible for the harms suffered by a Supply Chain Impacted Party.
299
+ Nothing in this section shall be interpreted to include acts committed by
300
+ individuals outside of the scope of his/her/their employment.
301
+
302
+ 5. NOTICE: This section explains when a Licensee must notify others of the
303
+ License.
304
+
305
+ 5.1. Distribution of Notice: Licensee must ensure that everyone who receives a
306
+ copy of or uses any part of Software from Licensee, with or without changes,
307
+ also receives the License and the copyright notice included with Software (and
308
+ if included by the Licensor, patent, trademark, and attribution notice).
309
+ Licensee must ensure that License is prominently displayed so that any
310
+ individual or entity seeking to download, copy, use, or otherwise receive any
311
+ part of Software from Licensee is notified of this License and its terms and
312
+ conditions. Licensee must cause any modified versions of the Software to carry
313
+ prominent notices stating that Licensee changed the Software.
314
+
315
+ 5.2. Modified Software: Licensee is free to create modifications of the Software
316
+ and distribute only the modified portion created by Licensee, however, any
317
+ derivative work stemming from the Software or its code must be distributed
318
+ pursuant to this License, including this Notice provision.
319
+
320
+ 5.3. Recipients as Licensees: Any individual or entity that uses, copies,
321
+ modifies, reproduces, distributes, or prepares derivative work based upon the
322
+ Software, all or part of the Software’s code, or a derivative work developed by
323
+ using the Software, including a portion of its code, is a Licensee as defined
324
+ above and is subject to the terms and conditions of this License.
325
+
326
+ 6. REPRESENTATIONS AND WARRANTIES:
327
+
328
+ 6.1. Disclaimer of Warranty: TO THE FULL EXTENT ALLOWED BY LAW, THIS SOFTWARE
329
+ COMES “AS IS,” WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED, AND LICENSOR SHALL NOT
330
+ BE LIABLE TO ANY PERSON OR ENTITY FOR ANY DAMAGES OR OTHER LIABILITY ARISING
331
+ FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THIS LICENSE, UNDER ANY
332
+ LEGAL CLAIM.
333
+
334
+ 6.2. Limitation of Liability: LICENSEE SHALL HOLD LICENSOR HARMLESS AGAINST ANY
335
+ AND ALL CLAIMS, DEBTS, DUES, LIABILITIES, LIENS, CAUSES OF ACTION, DEMANDS,
336
+ OBLIGATIONS, DISPUTES, DAMAGES, LOSSES, EXPENSES, ATTORNEYS' FEES, COSTS,
337
+ LIABILITIES, AND ALL OTHER CLAIMS OF EVERY KIND AND NATURE WHATSOEVER, WHETHER
338
+ KNOWN OR UNKNOWN, ANTICIPATED OR UNANTICIPATED, FORESEEN OR UNFORESEEN, ACCRUED
339
+ OR UNACCRUED, DISCLOSED OR UNDISCLOSED, ARISING OUT OF OR RELATING TO LICENSEE’S
340
+ USE OF THE SOFTWARE. NOTHING IN THIS SECTION SHOULD BE INTERPRETED TO REQUIRE
341
+ LICENSEE TO INDEMNIFY LICENSOR, NOR REQUIRE LICENSOR TO INDEMNIFY LICENSEE.
342
+
343
+ 7. TERMINATION
344
+
345
+ 7.1. Violations of Ethical Standards or Breaching Duty of Care: If Licensee
346
+ violates the Ethical Standards section or Licensee, or any other person or
347
+ entity within the Supply Chain prior to a good or service reaching the Licensee,
348
+ breaches its Duty of Care to Supply Chain Impacted Parties, Licensee must remedy
349
+ the violation or harm caused by Licensee within 30 days of being notified of the
350
+ violation or harm. If Licensee fails to remedy the violation or harm within 30
351
+ days, all rights in the Software granted to Licensee by License will be null and
352
+ void as between Licensor and Licensee.
353
+
354
+ 7.2. Failure of Notice: If any person or entity notifies Licensee in writing
355
+ that Licensee has not complied with the Notice section of this License, Licensee
356
+ can keep this License by taking all practical steps to comply within 30 days
357
+ after the notice of noncompliance. If Licensee does not do so, Licensee’s
358
+ License (and all rights licensed hereunder) will end immediately.
359
+
360
+ 7.3. Judicial Findings: In the event Licensee is found by a civil, criminal,
361
+ administrative, or other court of competent jurisdiction, or some other
362
+ adjudicating body with legal authority, to have committed actions which are in
363
+ violation of the Ethical Standards or Supply Chain Impacted Party sections of
364
+ this License, all rights granted to Licensee by this License will terminate
365
+ immediately.
366
+
367
+ 7.4. Patent Litigation: If Licensee institutes patent litigation against any
368
+ entity (including a cross-claim or counterclaim in a suit) alleging that the
369
+ Software, all or part of the Software’s code, or a derivative work developed
370
+ using the Software, including a portion of its code, constitutes direct or
371
+ contributory patent infringement, then any patent license, along with all other
372
+ rights, granted to Licensee under this License will terminate as of the date
373
+ such litigation is filed.
374
+
375
+ 7.5. Additional Remedies: Termination of the License by failing to remedy harms
376
+ in no way prevents Licensor or Supply Chain Impacted Party from seeking
377
+ appropriate remedies at law or in equity.
378
+
379
+ 8. MISCELLANEOUS:
380
+
381
+ 8.1. Conditions: Sections 3, 4.1, 5.1, 5.2, 7.1, 7.2, 7.3, and 7.4 are
382
+ conditions of the rights granted to Licensee in the License.
383
+
384
+ 8.2. Equitable Relief: Licensor and any Supply Chain Impacted Party shall be
385
+ entitled to equitable relief, including injunctive relief or specific
386
+ performance of the terms hereof, in addition to any other remedy to which they
387
+ are entitled at law or in equity.
388
+
389
+ 8.3. Copyleft: Modified software, source code, or other derivative work must be
390
+ licensed, in its entirety, under the exact same conditions as this License.
391
+
392
+ 8.4. Severability: If any term or provision of this License is determined to be
393
+ invalid, illegal, or unenforceable by a court of competent jurisdiction, any
394
+ such determination of invalidity, illegality, or unenforceability shall not
395
+ affect any other term or provision of this License or invalidate or render
396
+ unenforceable such term or provision in any other jurisdiction. If the
397
+ determination of invalidity, illegality, or unenforceability by a court of
398
+ competent jurisdiction pertains to the terms or provisions contained in the
399
+ Ethical Standards section of this License, all rights in the Software granted to
400
+ Licensee shall be deemed null and void as between Licensor and Licensee.
401
+
402
+ 8.5. Section Titles: Section titles are solely written for organizational
403
+ purposes and should not be used to interpret the language within each section.
404
+
405
+ 8.6. Citations: Citations are solely written to provide context for the source
406
+ of the provisions in the Ethical Standards.
407
+
408
+ 8.7. Section Summaries: Some sections have a brief italicized description which
409
+ is provided for the sole purpose of briefly describing the section and should
410
+ not be used to interpret the terms of the License.
411
+
412
+ 8.8. Entire License: This is the entire License between the Licensor and
413
+ Licensee with respect to the claims released herein and that the consideration
414
+ stated herein is the only consideration or compensation to be paid or exchanged
415
+ between them for this License. This License cannot be modified or amended except
416
+ in a writing signed by Licensor and Licensee.
417
+
418
+ 8.9. Successors and Assigns: This License shall be binding upon and inure to the
419
+ benefit of the Licensor’s and Licensee’s respective heirs, successors, and
420
+ assigns.
data/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # paper_trail-background
2
2
 
3
- - [![Build](http://img.shields.io/travis-ci/krainboltgreene/paper_trail-background.svg?style=flat-square)](https://travis-ci.org/krainboltgreene/paper_trail-background)
4
3
  - [![Downloads](http://img.shields.io/gem/dtv/paper_trail-background.svg?style=flat-square)](https://rubygems.org/gems/paper_trail-background)
5
4
  - [![Version](http://img.shields.io/gem/v/paper_trail-background.svg?style=flat-square)](https://rubygems.org/gems/paper_trail-background)
6
5
 
@@ -15,20 +14,29 @@ First you'll need to setup a job for processing versions:
15
14
  ``` ruby
16
15
  # The class MUST be named this
17
16
  class VersionJob < ApplicationJob
18
-
19
- # These are settings you'll probably want, I suggest sidekiq-unique-jobs
20
- sidekiq_options(
21
- :queue => "versions",
22
- :unique_across_queues => true,
23
- :lock => :until_executed,
24
- :log_duplicate_payload => true
25
- )
17
+ queue_as :default
26
18
 
27
19
  # This wires up the background job
28
- include PaperTrail::Background::Sidekiq
20
+ include PaperTrail::Background::Job
21
+ end
22
+ ```
23
+
24
+ ## Configuration
25
+ In an initializer, you can specify whether you want to opt into this behavior on a per-model basis:
26
+
27
+ ``` ruby
28
+ PaperTrail::Background::Config.configure do |config|
29
+ config.opt_in = true
29
30
  end
30
31
  ```
31
32
 
33
+ If opt-in behavior is set to `true`, you can enable async paper trails by specifying `async: true` in a given model's paper trail options:
34
+
35
+ ``` ruby
36
+ class SomeModel < ActiveRecord::Base
37
+ has_paper_trail async: true
38
+ end
39
+ ```
32
40
 
33
41
  ## Installing
34
42
 
@@ -0,0 +1,23 @@
1
+ module PaperTrail
2
+ module Background
3
+ class Configuration
4
+ attr_reader :opt_in
5
+
6
+ def opt_in=(value)
7
+ @opt_in = value
8
+ end
9
+ end
10
+
11
+ class Config
12
+ class << self
13
+ def configuration
14
+ @configuration ||= Configuration.new
15
+ end
16
+
17
+ def configure(&block)
18
+ yield(configuration)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,6 @@
1
1
  module PaperTrail
2
2
  module Background
3
- module Sidekiq
3
+ module Job
4
4
  def perform(version_class, attributes, event)
5
5
  version = version_class.constantize.create!(attributes)
6
6
  end
@@ -0,0 +1,43 @@
1
+ module PaperTrail
2
+ module Background
3
+ module RSpecHelpers
4
+ module InstanceMethods
5
+ # enable versioning for specific blocks (at instance-level)
6
+ def with_versioning(expected_open_transactions: 1, &block)
7
+ was_enabled = ::PaperTrail.enabled?
8
+ ::PaperTrail.enabled = true
9
+
10
+ normally_open_transactions = ActiveRecord::Base.normally_open_transactions
11
+ ActiveRecord::Base.normally_open_transactions = expected_open_transactions
12
+
13
+ # ensure that VersionJobs are executed
14
+ perform_enqueued_jobs only: VersionJob, &block
15
+ ensure
16
+ ::PaperTrail.enabled = was_enabled
17
+ ActiveRecord::Base.normally_open_transactions = normally_open_transactions
18
+ end
19
+ end
20
+
21
+ module ClassMethods
22
+ # enable versioning for specific blocks (at class-level)
23
+ def with_versioning(expected_open_transactions: 1, &block)
24
+ context "with versioning", versioning: true do
25
+ around do |example|
26
+ normally_open_transactions = ActiveRecord::Base.normally_open_transactions
27
+ ActiveRecord::Base.normally_open_transactions = expected_open_transactions
28
+
29
+ perform_enqueued_jobs only: VersionJob do
30
+ example.run
31
+ end
32
+
33
+ ActiveRecord::Base.normally_open_transactions = normally_open_transactions
34
+ end
35
+
36
+ class_exec(&block)
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,5 @@
1
1
  module PaperTrail
2
2
  module Background
3
- VERSION = "1.0.1"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -1,6 +1,10 @@
1
+ require "paper_trail/record_trail"
2
+ require "ar_after_transaction"
3
+
1
4
  module PaperTrail
5
+ require_relative "background/config"
2
6
  require_relative "background/version"
3
- require_relative "background/sidekiq"
7
+ require_relative "background/job"
4
8
 
5
9
  module Background
6
10
  # @api private
@@ -8,6 +12,7 @@ module PaperTrail
8
12
  # paper_trail-association_tracking
9
13
  def record_create
10
14
  return unless enabled?
15
+ return if Config.configuration.opt_in && @record.paper_trail_options[:async].blank?
11
16
 
12
17
  event = PaperTrail::Events::Create.new(@record, true)
13
18
 
@@ -25,6 +30,7 @@ module PaperTrail
25
30
  # paper_trail-association_tracking
26
31
  def record_destroy(recording_order)
27
32
  return unless enabled?
33
+ return if Config.configuration.opt_in && @record.paper_trail_options[:async].blank?
28
34
  return if @record.new_record?
29
35
 
30
36
  in_after_callback = recording_order == "after"
@@ -43,6 +49,7 @@ module PaperTrail
43
49
  # paper_trail-association_tracking
44
50
  def record_update(force:, in_after_callback:, is_touch:)
45
51
  return unless enabled?
52
+ return if Config.configuration.opt_in && @record.paper_trail_options[:async].blank?
46
53
 
47
54
  event = PaperTrail::Events::Update.new(@record, in_after_callback, is_touch, nil)
48
55
 
@@ -60,6 +67,7 @@ module PaperTrail
60
67
  # paper_trail-association_tracking
61
68
  def record_update_columns(changes)
62
69
  return unless enabled?
70
+ return if Config.configuration.opt_in && @record.paper_trail_options[:async].blank?
63
71
 
64
72
  event = Events::Update.new(@record, false, false, changes)
65
73
 
@@ -73,15 +81,12 @@ module PaperTrail
73
81
  end
74
82
 
75
83
  private def trigger_write(record, data, event)
76
- version_class = record.class.paper_trail.version_class
84
+ version_class = record.class.paper_trail.version_class.name
77
85
 
78
- version_class.after_transaction do
79
- VersionJob.perform_async(
86
+ ActiveRecord::Base.after_transaction do
87
+ VersionJob.perform_later(
80
88
  version_class,
81
- data.merge(
82
- :item_id => record.id,
83
- :item_type => record.class.name
84
- ),
89
+ data,
85
90
  event
86
91
  )
87
92
  end
@@ -0,0 +1,200 @@
1
+ require "spec_helper"
2
+
3
+ class DummyClass
4
+ include PaperTrail::Background
5
+
6
+ def initialize(options: {}, record: nil)
7
+ @options = options
8
+ @record = record
9
+ end
10
+
11
+ def enabled?
12
+ @options[:enabled]
13
+ end
14
+
15
+ def data_for_create
16
+ {}
17
+ end
18
+
19
+ def data_for_destroy
20
+ {}
21
+ end
22
+
23
+ def data_for_update_columns
24
+ {}
25
+ end
26
+
27
+ def force
28
+ true
29
+ end
30
+ end
31
+
32
+ class VersionJob
33
+ def self.perform_later(*args); end
34
+ end
35
+
36
+ RSpec.describe PaperTrail::Background do
37
+ before do
38
+ allow(VersionJob).to receive(:perform_later)
39
+ end
40
+
41
+ describe "#record_create" do
42
+ it "does not trigger a write if not enabled" do
43
+ DummyClass.new(options: { enabled: false }).record_create
44
+
45
+ expect(VersionJob).not_to have_received(:perform_later)
46
+ end
47
+
48
+ context "when enabled and opt_in config is enabled" do
49
+ let(:record) { double("SomeRecord") }
50
+
51
+ before do
52
+ PaperTrail::Background::Config.configure do |config|
53
+ config.opt_in = true
54
+ end
55
+ end
56
+
57
+ it "does not trigger a write if record is opted in but async is blank" do
58
+ allow(record).to receive(:paper_trail_options).and_return(async: nil)
59
+
60
+ DummyClass.new(options: { enabled: true }, record: record).record_create
61
+
62
+ expect(VersionJob).not_to have_received(:perform_later)
63
+ end
64
+
65
+ it "triggers a write if record is opted in and async is true" do
66
+ allow(record).to receive(:paper_trail_options).and_return(async: true)
67
+ allow(PaperTrail::Events::Create).to receive(:new).and_return(OpenStruct.new(data: {}))
68
+ allow(RSpec::Mocks::Double).to receive(:paper_trail).and_return(OpenStruct.new(version_class: Class))
69
+ allow(ActiveRecord::Base).to receive(:after_transaction).and_yield
70
+
71
+ DummyClass.new(options: { enabled: true }, record: record).record_create
72
+
73
+ expect(VersionJob).to have_received(:perform_later)
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "#record_destroy" do
79
+ it "does not trigger a write if not enabled" do
80
+ DummyClass.new(options: { enabled: false }).record_destroy("after")
81
+
82
+ expect(VersionJob).not_to have_received(:perform_later)
83
+ end
84
+
85
+ context "when enabled and opt_in config is enabled" do
86
+ let(:record) { double("SomeRecord") }
87
+
88
+ before do
89
+ PaperTrail::Background::Config.configure do |config|
90
+ config.opt_in = true
91
+ end
92
+ end
93
+
94
+ it "does not trigger a write if record is opted in but async is blank" do
95
+ allow(record).to receive(:paper_trail_options).and_return(async: nil)
96
+
97
+ DummyClass.new(options: { enabled: true }, record: record).record_destroy("after")
98
+
99
+ expect(VersionJob).not_to have_received(:perform_later)
100
+ end
101
+
102
+ it "does not trigger a write if record is new" do
103
+ allow(record).to receive(:paper_trail_options).and_return(async: true)
104
+ allow(record).to receive(:new_record?).and_return(true)
105
+
106
+ DummyClass.new(options: { enabled: true }, record: record).record_destroy("after")
107
+
108
+ expect(VersionJob).not_to have_received(:perform_later)
109
+ end
110
+
111
+ it "triggers a write if record is opted in and async is true" do
112
+ allow(record).to receive(:paper_trail_options).and_return(async: true)
113
+ allow(record).to receive(:new_record?).and_return(false)
114
+ allow(PaperTrail::Events::Destroy).to receive(:new).and_return(OpenStruct.new(data: {}))
115
+ allow(RSpec::Mocks::Double).to receive(:paper_trail).and_return(OpenStruct.new(version_class: Class))
116
+ allow(ActiveRecord::Base).to receive(:after_transaction).and_yield
117
+
118
+ DummyClass.new(options: { enabled: true }, record: record).record_destroy("after")
119
+
120
+ expect(VersionJob).to have_received(:perform_later)
121
+ end
122
+ end
123
+ end
124
+
125
+ describe "#record_update" do
126
+ it "does not trigger a write if not enabled" do
127
+ DummyClass.new(options: { enabled: false }).record_update(force: true, in_after_callback: true, is_touch: false)
128
+
129
+ expect(VersionJob).not_to have_received(:perform_later)
130
+ end
131
+
132
+ context "when enabled and opt_in config is enabled" do
133
+ let(:record) { double("SomeRecord") }
134
+
135
+ before do
136
+ PaperTrail::Background::Config.configure do |config|
137
+ config.opt_in = true
138
+ end
139
+ end
140
+
141
+ it "does not trigger a write if record is opted in but async is blank" do
142
+ allow(record).to receive(:paper_trail_options).and_return(async: nil)
143
+
144
+ DummyClass.new(options: { enabled: true }, record: record).record_update(force: true, in_after_callback: true, is_touch: false)
145
+
146
+ expect(VersionJob).not_to have_received(:perform_later)
147
+ end
148
+
149
+ it "triggers a write if record is opted in and async is true" do
150
+ allow(record).to receive(:paper_trail_options).and_return(async: true)
151
+ allow(record).to receive(:new_record?).and_return(false)
152
+ allow(PaperTrail::Events::Update).to receive(:new).and_return(OpenStruct.new(data: {}))
153
+ allow(RSpec::Mocks::Double).to receive(:paper_trail).and_return(OpenStruct.new(version_class: Class))
154
+ allow(ActiveRecord::Base).to receive(:after_transaction).and_yield
155
+
156
+ DummyClass.new(options: { enabled: true }, record: record).record_update(force: true, in_after_callback: true, is_touch: false)
157
+
158
+ expect(VersionJob).to have_received(:perform_later)
159
+ end
160
+ end
161
+ end
162
+
163
+ describe "#record_update_columns" do
164
+ it "does not trigger a write if not enabled" do
165
+ DummyClass.new(options: { enabled: false }).record_update_columns({})
166
+
167
+ expect(VersionJob).not_to have_received(:perform_later)
168
+ end
169
+
170
+ context "when enabled and opt_in config is enabled" do
171
+ let(:record) { double("SomeRecord") }
172
+
173
+ before do
174
+ PaperTrail::Background::Config.configure do |config|
175
+ config.opt_in = true
176
+ end
177
+ end
178
+
179
+ it "does not trigger a write if record is opted in but async is blank" do
180
+ allow(record).to receive(:paper_trail_options).and_return(async: nil)
181
+
182
+ DummyClass.new(options: { enabled: true }, record: record).record_update_columns({})
183
+
184
+ expect(VersionJob).not_to have_received(:perform_later)
185
+ end
186
+
187
+ it "triggers a write if record is opted in and async is true" do
188
+ allow(record).to receive(:paper_trail_options).and_return(async: true)
189
+ allow(record).to receive(:new_record?).and_return(false)
190
+ allow(PaperTrail::Events::Update).to receive(:new).and_return(OpenStruct.new(data: {}))
191
+ allow(RSpec::Mocks::Double).to receive(:paper_trail).and_return(OpenStruct.new(version_class: Class))
192
+ allow(ActiveRecord::Base).to receive(:after_transaction).and_yield
193
+
194
+ DummyClass.new(options: { enabled: true }, record: record).record_update_columns({})
195
+
196
+ expect(VersionJob).to have_received(:perform_later)
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,8 @@
1
+ require 'ar_after_transaction'
2
+
3
+ require_relative '../paper_trail/background/rspec_helpers'
4
+
5
+ RSpec.configure do |config|
6
+ config.include PaperTrail::Background::RSpecHelpers::InstanceMethods
7
+ config.extend PaperTrail::Background::RSpecHelpers::ClassMethods
8
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail-background
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kurtis Rainbolt-Greene
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-25 00:00:00.000000000 Z
11
+ date: 2023-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '='
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.11.2
61
+ version: '0.14'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '='
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.11.2
68
+ version: '0.14'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry-doc
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,43 +80,58 @@ dependencies:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.11.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: ar_after_transaction
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: paper_trail
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '='
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: 10.0.1
103
+ version: '10'
90
104
  type: :runtime
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '='
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: 10.0.1
110
+ version: '10'
97
111
  description: A library for making paper_trail a background process
98
112
  email:
99
113
  - kurtis@rainbolt-greene.online
100
- executables:
101
- - setup
102
- - console
114
+ executables: []
103
115
  extensions: []
104
116
  extra_rdoc_files: []
105
117
  files:
118
+ - LICENSE
106
119
  - README.md
107
120
  - Rakefile
108
- - bin/console
109
- - bin/setup
110
121
  - lib/paper_trail-background.rb
122
+ - lib/paper_trail-background/rspec.rb
111
123
  - lib/paper_trail/background.rb
112
- - lib/paper_trail/background/sidekiq.rb
124
+ - lib/paper_trail/background/config.rb
125
+ - lib/paper_trail/background/job.rb
126
+ - lib/paper_trail/background/rspec_helpers.rb
113
127
  - lib/paper_trail/background/version.rb
114
128
  - lib/paper_trail/background/version_spec.rb
115
- homepage: http://krainboltgreene.github.io/paper_trail-background.rb
129
+ - lib/paper_trail/background_spec.rb
130
+ homepage: https://github.com/krainboltgreene/paper_trail-background.rb
116
131
  licenses:
117
- - ISC
132
+ - HL3
118
133
  metadata: {}
119
- post_install_message:
134
+ post_install_message:
120
135
  rdoc_options: []
121
136
  require_paths:
122
137
  - lib
@@ -131,9 +146,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
146
  - !ruby/object:Gem::Version
132
147
  version: '0'
133
148
  requirements: []
134
- rubyforge_project:
135
- rubygems_version: 2.7.7
136
- signing_key:
149
+ rubygems_version: 3.3.7
150
+ signing_key:
137
151
  specification_version: 4
138
152
  summary: A library for making paper_trail a background process
139
153
  test_files: []
data/bin/console DELETED
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "paper_trail-background"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- require "pry"
11
- Pry.start
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here