apidae 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '07291fb2c40fdbc091aff918c45c201602a5d58c'
4
- data.tar.gz: 76f4566eb71404f129add27100872f1263ae868b
3
+ metadata.gz: f69774e7655cd66923973e23882e6d1d0df0cb2a
4
+ data.tar.gz: 199df4ea7f45f563e569f9e1229dfdd012f6a2db
5
5
  SHA512:
6
- metadata.gz: fa72db3de71d37e56b2c8908d703419a72fc5f0efd2d9f03ce91233ae0d68bd402f4a49d775fa22856a2109f83c7bb8bb54593224cc1e14377f696afc2e6d811
7
- data.tar.gz: e1a0c2c71710947ea1b47266e2bb995ba5a44cec98190b3358168e21681ce9b2da4d3c479932514620929da4758affe03cece6e8693cf2f4458e327af108f7a8
6
+ metadata.gz: 671a682f09badf6919a55227c7366478c23bc74456fd58669101ac7a4c9462a5c08cd32a1a58711652bb484c39867c106d338afd9989f08b759af5c4dab375de
7
+ data.tar.gz: f7ba0f5be1b236da982b133e682c454ff251a1848927db75f54dd827ee0367e4b38a2fa93884dc64aebc29d60bfe04a307d25b33a10cc268ddd4ab82ce786ce5
@@ -13,3 +13,12 @@
13
13
  *= require_tree .
14
14
  *= require_self
15
15
  */
16
+
17
+ #apidae_imports_panel > a:first-child {
18
+ float: right;
19
+ }
20
+
21
+ #apidae_form label {
22
+ font-size: 18px;
23
+ margin-right: 1rem;
24
+ }
@@ -16,7 +16,6 @@ module Apidae
16
16
  @objects = SelectionObject.where(apidae_selection_id: selections.map {|s| s.id}.uniq).map {|so| so.apidae_object_id}.uniq.count
17
17
  @last_imports = FileImport.where(apidae_id: apidae_user.apidae_projects_ids).order(id: :desc).take(100)
18
18
  end
19
- @references = Reference.count
20
19
  end
21
20
  end
22
21
  end
@@ -6,6 +6,7 @@ module Apidae
6
6
  class ImportController < ApplicationController
7
7
  skip_before_action :verify_authenticity_token
8
8
  skip_before_action Rails.application.config.apidae_auth
9
+ skip_before_action :check_user_data!
9
10
 
10
11
  # Callback endpoint for Apidae exports
11
12
  #
@@ -36,34 +37,62 @@ module Apidae
36
37
  def run
37
38
  success = true
38
39
  Export.pending.each do |e|
39
- begin
40
- open(e.file_url) do |f|
41
- begin
42
- FileImport.import(f, e.project_id)
40
+ success &&= import_data(e)
41
+ end
42
+ success ? head(:ok) : head(:internal_server_error)
43
+ end
44
+
45
+ def new
46
+ @export = Export.new(status: Export::PENDING)
47
+ end
48
+
49
+ def create
50
+ @export = Export.new(export_params)
51
+ if @export.save && import_data(@export)
52
+ redirect_to apidae.root_url, notice: 'Le fichier a bien été importé.'
53
+ else
54
+ flash.now[:alert] = "Une erreur s'est produite lors de l'import du fichier."
55
+ render :new
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def export_params
62
+ params.require(:export).permit(:project_id, :file_url, :status)
63
+ end
64
+
65
+ def import_data(e)
66
+ success = true
67
+ begin
68
+ open(e.file_url) do |f|
69
+ begin
70
+ FileImport.import(f, e.project_id)
71
+ unless e.confirm_url.blank?
43
72
  uri = URI(e.confirm_url)
44
73
  req = Net::HTTP::Post.new(uri)
45
74
  Net::HTTP.start(uri.hostname, uri.port) do |http|
46
75
  http.request(req)
47
76
  end
48
- e.update(status: Export::COMPLETE)
49
- if Rails.application.config.respond_to?(:apidae_import_callback)
50
- Rails.application.config.apidae_import_callback.call(e)
51
- end
52
- rescue Exception => ex
53
- logger.error("Failed to import export file : #{e.file_url}")
54
- logger.error("Error is : #{ex} \n#{ex.backtrace.join("\n") unless ex.backtrace.blank?}")
55
- success = false
56
- e.update(status: Export::CANCELLED)
57
77
  end
78
+ e.update(status: Export::COMPLETE)
79
+ if Rails.application.config.respond_to?(:apidae_import_callback)
80
+ Rails.application.config.apidae_import_callback.call(e)
81
+ end
82
+ rescue Exception => ex
83
+ logger.error("Failed to import export file : #{e.file_url}")
84
+ logger.error("Error is : #{ex} \n#{ex.backtrace.join("\n") unless ex.backtrace.blank?}")
85
+ success = false
86
+ e.update(status: Export::CANCELLED)
58
87
  end
59
- rescue OpenURI::HTTPError => err
60
- logger.error("Failed to download export file : #{e.file_url}")
61
- logger.error("Error is : #{err}")
62
- success = false
63
- e.update(status: Export::CANCELLED)
64
88
  end
89
+ rescue OpenURI::HTTPError => err
90
+ logger.error("Failed to download export file : #{e.file_url}")
91
+ logger.error("Error is : #{err}")
92
+ success = false
93
+ e.update(status: Export::CANCELLED)
65
94
  end
66
- success ? head(:ok) : head(:internal_server_error)
95
+ success
67
96
  end
68
97
  end
69
98
  end
@@ -24,7 +24,7 @@ module Apidae
24
24
  else
25
25
  @project = Project.new(project_params)
26
26
  if @project.save
27
- referrer = (session.delete(:referrer) || projects_url)
27
+ referrer = params[:redirect_to] || session.delete(:referrer) || projects_url
28
28
  redirect_to (referrer + "?apidae_project_id=#{@project.id}"), notice: 'Le projet a bien été créé'
29
29
  else
30
30
  flash.now[:alert] = "Une erreur s'est produite lors la création du projet"
@@ -54,7 +54,7 @@ module Apidae
54
54
 
55
55
  def update_project
56
56
  if @project.update(project_params)
57
- referrer = session.delete(:referrer)
57
+ referrer = params[:redirect_to] || session.delete(:referrer)
58
58
  redirect_to (referrer + "?apidae_project_id=#{@project.id}"), notice: 'Le projet a bien été mis à jour'
59
59
  else
60
60
  flash.now[:alert] = "Une erreur s'est produite lors la mise à jour du projet"
@@ -1,8 +1,25 @@
1
1
  module Apidae
2
2
  class ApidaeDataParser
3
3
  PHONE = 201
4
+ ALT_PHONE = 206
4
5
  EMAIL = 204
5
6
  WEBSITE = 205
7
+ GOOGLE = 3789
8
+ FACEBOOK = 207
9
+ TWITTER = 3755
10
+ YELP = 4007
11
+ TRIP_ADVISOR = 4000
12
+
13
+ CONTACTS_MAP = {
14
+ 'telephone' => PHONE,
15
+ 'email' => EMAIL,
16
+ 'website' => WEBSITE,
17
+ 'facebook' => FACEBOOK,
18
+ 'google' => GOOGLE,
19
+ 'trip_advisor' => TRIP_ADVISOR,
20
+ 'twitter' => TWITTER,
21
+ 'yelp' => YELP
22
+ }
6
23
 
7
24
  MODE_AUTO = 'auto'
8
25
  MODE_MANUAL = 'manual'
@@ -108,7 +125,7 @@ module Apidae
108
125
  url: pic[:traductionFichiers][0][:url].gsub('http:', 'https:'),
109
126
  description: localized_value(pic, :legende, locale),
110
127
  credits: localized_value(pic, :copyright, locale),
111
- expiration_date: pic[:dateLimiteDePublication]
128
+ expiration_date: pic[:dateLimiteDePublication] || ''
112
129
  }
113
130
  end
114
131
  end
@@ -142,15 +159,30 @@ module Apidae
142
159
  contact_entries = information_hash[:moyensCommunication] || []
143
160
  contact_entries.each do |c|
144
161
  case c[:type][:id]
145
- when PHONE
146
- contact_details[:telephone] ||= []
147
- contact_details[:telephone] << c[:coordonnees][:fr]
162
+ when PHONE, ALT_PHONE
163
+ contact_details[:telephone] ||= {}
164
+ contact_details[:telephone][c[:identifiant]] = c[:coordonnees][:fr]
148
165
  when EMAIL
149
- contact_details[:email] ||= []
150
- contact_details[:email] << c[:coordonnees][:fr]
166
+ contact_details[:email] ||= {}
167
+ contact_details[:email][c[:identifiant]] = c[:coordonnees][:fr]
151
168
  when WEBSITE
152
- contact_details[:website] ||= []
153
- contact_details[:website] << c[:coordonnees][:fr]
169
+ contact_details[:website] ||= {}
170
+ contact_details[:website][c[:identifiant]] = c[:coordonnees][:fr]
171
+ when GOOGLE
172
+ contact_details[:google] ||= {}
173
+ contact_details[:google][c[:identifiant]] = c[:coordonnees][:fr]
174
+ when FACEBOOK
175
+ contact_details[:facebook] ||= {}
176
+ contact_details[:facebook][c[:identifiant]] = c[:coordonnees][:fr]
177
+ when TWITTER
178
+ contact_details[:twitter] ||= {}
179
+ contact_details[:twitter][c[:identifiant]] = c[:coordonnees][:fr]
180
+ when YELP
181
+ contact_details[:yelp] ||= {}
182
+ contact_details[:yelp][c[:identifiant]] = c[:coordonnees][:fr]
183
+ when TRIP_ADVISOR
184
+ contact_details[:trip_advisor] ||= {}
185
+ contact_details[:trip_advisor][c[:identifiant]] = c[:coordonnees][:fr]
154
186
  else
155
187
  end
156
188
  end
@@ -189,7 +221,8 @@ module Apidae
189
221
  openings_desc: node_value(openings_hash, :periodeEnClair, *locales),
190
222
  openings_desc_mode: openings_hash[:periodeEnClairGenerationMode] == 'AUTOMATIQUE' ? MODE_AUTO : MODE_MANUAL,
191
223
  openings: build_openings(openings_hash, *locales),
192
- time_periods: lists_ids(openings_hash[:indicationsPeriode])
224
+ time_periods: lists_ids(openings_hash[:indicationsPeriode]),
225
+ openings_extra: lists_ids(openings_hash[:ouverturesComplementaires])
193
226
  }
194
227
  end
195
228
  end
@@ -229,7 +262,8 @@ module Apidae
229
262
  track: apidae_obj.apidae_type == Obj::EQU ? data_hash[:itineraire] : nil,
230
263
  products: lists_ids(data_hash[:typesProduit], data_hash[:aopAocIgps], data_hash[:specialites]),
231
264
  audience: lists_ids(prestations_hash[:typesClientele]),
232
- animals: prestations_hash[:animauxAcceptes] == 'ACCEPTES',
265
+ animals: {allowed: prestations_hash[:animauxAcceptes] == 'ACCEPTES', desc: node_value(prestations_hash, :descriptifAnimauxAcceptes, *locales),
266
+ fee: prestations_hash[:animauxAcceptesSupplement] == 'AVEC_SUPPLEMENT'},
233
267
  extra: apidae_obj.apidae_type == Obj::SPA ? node_value(data_hash, :formuleHebergement, *locales) : node_value(prestations_hash, :complementAccueil, *locales),
234
268
  duration: apidae_obj.apidae_type == Obj::SPA ? {days: data_hash[:nombreJours], nights: data_hash[:nombreNuits]} : data_hash[:dureeSeance],
235
269
  certifications: data_hash[:agrements].blank? ? [] : data_hash[:agrements].map {|a| {id: a[:type][:id], identifier: a[:numero]}},
@@ -316,6 +350,7 @@ module Apidae
316
350
  external_id: o[:identifiantTechnique],
317
351
  start_date: o[:dateDebut],
318
352
  end_date: o[:dateFin],
353
+ each_year: o[:tousLesAns],
319
354
  closing_days: closing_days.blank? ? [] : closing_days.map {|d| d[:dateSpeciale]},
320
355
  details: node_value(o, :complementHoraire, *locales),
321
356
  time_periods: [
@@ -5,6 +5,8 @@ module Apidae
5
5
  COMPLETE = 'complete'
6
6
  CANCELLED = 'cancelled'
7
7
 
8
+ validates_presence_of :file_url, :project_id
9
+
8
10
  # Note : handle reset case
9
11
  def self.pending
10
12
  where(remote_status: 'SUCCESS', status: PENDING).order(:id)
@@ -14,11 +14,11 @@ module Apidae
14
14
  store_accessor :pictures_data, :pictures
15
15
  store_accessor :attachments_data, :attachments
16
16
  store_accessor :type_data, :categories, :themes, :capacity, :classification, :labels, :chains, :area, :track,
17
- :products, :audience, :animals, :extra, :duration, :certifications, :business
17
+ :products, :audience, :animals, :animals_desc, :extra, :duration, :certifications, :business
18
18
  store_accessor :entity_data, :entity_id, :entity_name, :service_provider_id
19
- store_accessor :contact_data, :telephone, :email, :website, :contacts
19
+ store_accessor :contact_data, :telephone, :email, :website, :google, :facebook, :twitter, :yelp, :trip_advisor, :contacts
20
20
  store_accessor :location_data, :address, :place, :latitude, :longitude, :access, :territories, :environments
21
- store_accessor :openings_data, :openings_desc, :openings_desc_mode, :openings, :time_periods
21
+ store_accessor :openings_data, :openings_desc, :openings_desc_mode, :openings, :time_periods, :openings_extra
22
22
  store_accessor :rates_data, :rates_desc, :rates_desc_mode, :rates, :payment_methods, :includes, :excludes
23
23
  store_accessor :service_data, :services, :equipments, :comfort, :activities, :challenged, :languages
24
24
  store_accessor :booking_data, :booking_desc, :booking_entities
@@ -122,6 +122,18 @@ module Apidae
122
122
  self
123
123
  end
124
124
 
125
+ def dig(*keys)
126
+ root_key, *nested_keys = keys
127
+ root_val = self.send(root_key)
128
+ if root_val.blank?
129
+ nested_keys.blank? ? root_val : nil
130
+ elsif root_val.respond_to?(:dig)
131
+ root_val.dig(*nested_keys)
132
+ else
133
+ raise ArgumentError.new('Cannot call dig with these args')
134
+ end
135
+ end
136
+
125
137
  def self.default_scope
126
138
  where(root_obj_id: nil)
127
139
  end
@@ -5,6 +5,10 @@ module Apidae
5
5
 
6
6
  store_accessor :meta_data, :category, :parent
7
7
 
8
+ def self.default_scope
9
+ where(is_active: true)
10
+ end
11
+
8
12
  def self.import(refs_json)
9
13
  locales = Rails.application.config.respond_to?(:apidae_locales) ? Rails.application.config.apidae_locales : [DEFAULT_LOCALE]
10
14
  locales_map = Hash[locales.map {|loc| ["libelle#{loc.camelize.gsub('-', '')}".to_sym, loc]}]
@@ -15,6 +19,7 @@ module Apidae
15
19
  ref.label_data = ref_data.slice(*locales_map.keys).transform_keys {|k| locales_map[k]}
16
20
  ref.parent = ref_data[:parent][:id] if ref_data[:parent]
17
21
  ref.category = ref_data[:familleCritere] ? ref_data[:familleCritere][:id] : (ref_data[:typeLabel] ? ref_data[:typeLabel][:id] : nil)
22
+ ref.is_active = ref_data[:actif]
18
23
  ref.save!
19
24
  end
20
25
  end
@@ -3,13 +3,20 @@
3
3
  <%= link_to pluralize(@projects, 'projet', 'projets'), apidae.projects_path, class: styles[:projects] %>
4
4
  <%= link_to pluralize(@selections, 'sélection', 'sélections'), apidae.selections_path, class: styles[:selections] %>
5
5
  <%= link_to pluralize(@objects, 'objet touristique', 'objets touristiques'), apidae.objects_path, class: styles[:objects] %>
6
- <%= link_to (pluralize(@references, 'élément', 'éléments') + ' de référence'), apidae.references_path, class: styles[:references] %>
7
6
  <%= link_to 'Retour', :back, class: styles[:back] %>
8
7
  <h1 class="<%= styles[:h1] %>">Apidae</h1>
9
8
  </div>
10
9
  <div id="apidae_dashboard" class="<%= styles[:wrapper] %>">
11
10
  <div id="apidae_imports_panel" class="<%= styles[:body] %>">
11
+ <%= link_to 'Importer un fichier', apidae.import_new_path, class: styles[:projects] %>
12
12
  <h2 class="<%= styles[:h2] %>">Derniers imports</h2>
13
+ <p>
14
+ Les imports provenant de vos projets Apidae apparaîtront ci-dessous. Pour que les données soient importées correctement,
15
+ vos projets doivent être configurés pour exporter les données au format <strong>JSON V2</strong>, en
16
+ <strong>groupant les objets exportés</strong>.<br/>
17
+ Si vous souhaitez que chaque export soit récupéré automatiquement, veillez à renseigner le paramètre
18
+ <strong>Url de notification</strong> avec la valeur <strong><%= apidae.import_callback_url %></strong>.
19
+ </p>
13
20
  <table id="apidae_imports" class="<%= styles[:table] %>">
14
21
  <thead class="<%= styles[:table_head] %>">
15
22
  <tr>
@@ -0,0 +1,29 @@
1
+ <%= form_for(@export, url: apidae.import_create_path, method: :post, html: {class: styles[:form]}) do |f| %>
2
+ <% if @export.errors.any? %>
3
+ <div id="apidae_form_errors">
4
+ <ul>
5
+ <% @export.errors.full_messages.each do |message| %>
6
+ <li><%= message %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
11
+ <p>
12
+ Pour que les données soient importées correctement,
13
+ vos projets doivent être configurés pour exporter les données au format <strong>JSON V2</strong>, en
14
+ <strong>groupant les objets exportés</strong>.
15
+ </p>
16
+
17
+ <div class="<%= styles[:form_field] %>">
18
+ <div><%= f.label :project_id %></div>
19
+ <div><%= f.text_field :project_id, placeholder: "Ex: 1234" %></div>
20
+ </div>
21
+ <div class="<%= styles[:form_field] %>">
22
+ <div><%= f.label :file_url %></div>
23
+ <div><%= f.text_field :file_url, placeholder: "Ex: http://export.apidae-tourisme.com/exports/1234_20200101-5678_ABCdef.zip" %></div>
24
+ </div>
25
+ <%= f.hidden_field :status %>
26
+ <div class="<%= styles[:form_actions] %>">
27
+ <%= f.submit 'Valider' %> | <%= link_to 'Retour', :back, class: styles[:back] %>
28
+ </div>
29
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= render layout: "/layouts/#{Rails.application.config.apidae_layout}" do |styles| %>
2
+ <div id="apidae_header" class="<%= styles[:header] %>">
3
+ <%= link_to 'Retour', :back, class: styles[:back] %>
4
+ <h1 class="<%= styles[:h1] %>">Apidae - Importer un fichier de données</h1>
5
+ </div>
6
+ <div id="apidae_import" class="<%= styles[:wrapper] %>">
7
+ <div id="apidae_form" class="<%= styles[:body] %>">
8
+ <%= render 'form', styles: styles %>
9
+ </div>
10
+ </div>
11
+ <% end %>
@@ -10,12 +10,21 @@ fr:
10
10
  apidae/obj:
11
11
  apidae_id: Identifiant Apidae
12
12
  selection_apidae_id: Sélection Apidae
13
+ apidae/export:
14
+ project_id: Identifiant du projet
15
+ file_url: URL du fichier d'export
13
16
  errors:
14
17
  models:
15
18
  apidae/project:
16
19
  attributes:
17
20
  apidae_id:
18
21
  taken: Un projet avec cet identifiant Apidae existe déjà.
22
+ apidae/export:
23
+ attributes:
24
+ file_url:
25
+ blank: est requise
26
+ project_id:
27
+ blank: est requis
19
28
  apidae:
20
29
  file_import:
21
30
  status:
@@ -39,4 +48,21 @@ fr:
39
48
  HANDICAP: Handicap
40
49
  TOURISME_AFFAIRES: Affaires
41
50
  GROUPES: Groupes
42
- PRESTATAIRE_ACTIVITES: Prestataire d'activités
51
+ PRESTATAIRE_ACTIVITES: Prestataire d'activités
52
+ types:
53
+ ACTIVITE: Activités
54
+ COMMERCE_ET_SERVICE: Commerces et services
55
+ DEGUSTATION: Producteurs
56
+ DOMAINE_SKIABLE: Domaines skiables
57
+ EQUIPEMENT: Équipements
58
+ FETE_ET_MANIFESTATION: Fêtes et manifestations
59
+ HEBERGEMENT_COLLECTIF: Hébergements collectifs
60
+ HEBERGEMENT_LOCATIF: Hébergements locatifs
61
+ HOTELLERIE: Hôtellerie
62
+ HOTELLERIE_PLEIN_AIR: Hôtellerie de plein air
63
+ PATRIMOINE_CULTUREL: Patrimoine culturel
64
+ PATRIMOINE_NATUREL: Patrimoine naturel
65
+ RESTAURATION: Restauration
66
+ SEJOUR_PACKAGE: Séjour et produits packagés
67
+ STRUCTURE: Entité juridique
68
+ TERRITOIRE: Territoire
@@ -15,6 +15,8 @@ Apidae::Engine.routes.draw do
15
15
 
16
16
  match 'import/callback', via: :post, to: 'import#callback'
17
17
  match 'import/run', via: :post, to: 'import#run'
18
+ match 'import/new', via: :get, to: 'import#new'
19
+ match 'import/create', via: :post, to: 'import#create'
18
20
 
19
21
  root to: 'dashboard#index'
20
22
  end
@@ -0,0 +1,6 @@
1
+ class AddIsActiveToApidaeReferences < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :apidae_references, :is_active, :boolean
4
+ add_index :apidae_references, :is_active, unique: false
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Apidae
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apidae
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Baptiste Vilain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '2.5'
62
62
  type: :runtime
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'
68
+ version: '2.5'
69
69
  description: To be completed
70
70
  email:
71
71
  - jbvilain@gmail.com
@@ -106,7 +106,9 @@ files:
106
106
  - app/models/apidae/selection_object.rb
107
107
  - app/models/apidae/town.rb
108
108
  - app/views/apidae/dashboard/index.html.erb
109
+ - app/views/apidae/import/_form.html.erb
109
110
  - app/views/apidae/import/callback.html.erb
111
+ - app/views/apidae/import/new.html.erb
110
112
  - app/views/apidae/objects/_form.html.erb
111
113
  - app/views/apidae/objects/edit.html.erb
112
114
  - app/views/apidae/objects/index.html.erb
@@ -178,6 +180,7 @@ files:
178
180
  - db/migrate/20200312150008_add_version_data_to_apidae_objs.rb
179
181
  - db/migrate/20200312150904_add_version_index_on_apidae_objs.rb
180
182
  - db/migrate/20200522124205_rename_objs_contact_to_contact_data.rb
183
+ - db/migrate/20200528101957_add_is_active_to_apidae_references.rb
181
184
  - lib/apidae.rb
182
185
  - lib/apidae/engine.rb
183
186
  - lib/apidae/version.rb