diff --git a/app/controllers/api/v2/mappings_controller.rb b/app/controllers/api/v2/mappings_controller.rb index 4490e4af..186d6891 100644 --- a/app/controllers/api/v2/mappings_controller.rb +++ b/app/controllers/api/v2/mappings_controller.rb @@ -5,6 +5,27 @@ module Api def searchable_columns [] end + + def create + instantiate_resource + resource.user = current_user if current_user.present? + resource.updated_by = current_user if current_user.present? + authorize resource + create_action + respond_with_resource + end + + def update + resource.updated_by = current_user if current_user.present? + update_action + respond_with_resource + end + + def destroy + resource.updated_by = current_user if current_user.present? + destroy_action + head :no_content + end end end end diff --git a/app/controllers/mappings_controller.rb b/app/controllers/mappings_controller.rb index de2c8ea1..86db023e 100644 --- a/app/controllers/mappings_controller.rb +++ b/app/controllers/mappings_controller.rb @@ -19,10 +19,10 @@ class MappingsController < ApplicationController @mapping = Mapping.new(mapping_params) authorize @mapping @mapping.user = current_user + @mapping.updated_by = current_user if @mapping.save render json: @mapping, status: :created - Events::NewMapping.publish!(@mapping, current_user) else render json: @mapping.errors, status: :unprocessable_entity end @@ -32,8 +32,10 @@ class MappingsController < ApplicationController def update @mapping = Mapping.find(params[:id]) authorize @mapping + @mapping.updated_by = current_user + @mapping.assign_attributes(mapping_params) - if @mapping.update_attributes(mapping_params) + if @mapping.save head :no_content else render json: @mapping.errors, status: :unprocessable_entity @@ -44,14 +46,7 @@ class MappingsController < ApplicationController def destroy @mapping = Mapping.find(params[:id]) authorize @mapping - - mappable = @mapping.mappable - if mappable.defer_to_map - mappable.permission = mappable.defer_to_map.permission - mappable.defer_to_map_id = nil - mappable.save - end - + @mapping.updated_by = current_user @mapping.destroy head :no_content diff --git a/app/models/event.rb b/app/models/event.rb index 02c6d698..cf974664 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,8 +1,10 @@ # frozen_string_literal: true class Event < ApplicationRecord - KINDS = %w(user_present_on_map conversation_started_on_map topic_added_to_map synapse_added_to_map).freeze + KINDS = %w(user_present_on_map conversation_started_on_map + topic_added_to_map topic_moved_on_map topic_removed_from_map + synapse_added_to_map synapse_removed_from_map + topic_updated synapse_updated).freeze - # has_many :notifications, dependent: :destroy belongs_to :eventable, polymorphic: true belongs_to :map belongs_to :user @@ -14,18 +16,12 @@ class Event < ApplicationRecord validates :kind, inclusion: { in: KINDS } validates :eventable, presence: true - # def notify!(user) - # notifications.create!(user: user) - # end - def belongs_to?(this_user) user_id == this_user.id end def notify_webhooks! - # group = self.discussion.group map.webhooks.each { |webhook| WebhookService.publish! webhook: webhook, event: self } - # group.webhooks.each { |webhook| WebhookService.publish! webhook: webhook, event: self } end handle_asynchronously :notify_webhooks! end diff --git a/app/models/events/new_mapping.rb b/app/models/events/new_mapping.rb deleted file mode 100644 index 889c69bc..00000000 --- a/app/models/events/new_mapping.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -class Events::NewMapping < Event - # after_create :notify_users! - - def self.publish!(mapping, user) - create!(kind: mapping.mappable_type == 'Topic' ? 'topic_added_to_map' : 'synapse_added_to_map', - eventable: mapping, - map: mapping.map, - user: user) - end -end diff --git a/app/models/events/synapse_added_to_map.rb b/app/models/events/synapse_added_to_map.rb new file mode 100644 index 00000000..5afa885d --- /dev/null +++ b/app/models/events/synapse_added_to_map.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +class Events::SynapseAddedToMap < Event + # after_create :notify_users! + + def self.publish!(synapse, map, user, meta) + create!(kind: 'synapse_added_to_map', + eventable: synapse, + map: map, + user: user, + meta: meta) + end +end diff --git a/app/models/events/synapse_removed_from_map.rb b/app/models/events/synapse_removed_from_map.rb new file mode 100644 index 00000000..b64035dd --- /dev/null +++ b/app/models/events/synapse_removed_from_map.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +class Events::SynapseRemovedFromMap < Event + # after_create :notify_users! + + def self.publish!(synapse, map, user, meta) + create!(kind: 'synapse_removed_from_map', + eventable: synapse, + map: map, + user: user, + meta: meta) + end +end diff --git a/app/models/events/synapse_updated.rb b/app/models/events/synapse_updated.rb new file mode 100644 index 00000000..0d85cbe8 --- /dev/null +++ b/app/models/events/synapse_updated.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +class Events::SynapseUpdated < Event + # after_create :notify_users! + + def self.publish!(synapse, user, meta) + create!(kind: 'synapse_updated', + eventable: synapse, + user: user, + meta: meta) + end +end diff --git a/app/models/events/topic_added_to_map.rb b/app/models/events/topic_added_to_map.rb new file mode 100644 index 00000000..a3fa62cf --- /dev/null +++ b/app/models/events/topic_added_to_map.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +class Events::TopicAddedToMap < Event + # after_create :notify_users! + + def self.publish!(topic, map, user, meta) + create!(kind: 'topic_added_to_map', + eventable: topic, + map: map, + user: user, + meta: meta) + end +end diff --git a/app/models/events/topic_moved_on_map.rb b/app/models/events/topic_moved_on_map.rb new file mode 100644 index 00000000..08d01277 --- /dev/null +++ b/app/models/events/topic_moved_on_map.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +class Events::TopicMovedOnMap < Event + # after_create :notify_users! + + def self.publish!(topic, map, user, meta) + create!(kind: 'topic_moved_on_map', + eventable: topic, + map: map, + user: user, + meta: meta) + end +end diff --git a/app/models/events/topic_removed_from_map.rb b/app/models/events/topic_removed_from_map.rb new file mode 100644 index 00000000..2f03ec26 --- /dev/null +++ b/app/models/events/topic_removed_from_map.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +class Events::TopicRemovedFromMap < Event + # after_create :notify_users! + + def self.publish!(topic, map, user, meta) + create!(kind: 'topic_removed_from_map', + eventable: topic, + map: map, + user: user, + meta: meta) + end +end diff --git a/app/models/events/topic_updated.rb b/app/models/events/topic_updated.rb new file mode 100644 index 00000000..fd41a4d6 --- /dev/null +++ b/app/models/events/topic_updated.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +class Events::TopicUpdated < Event + # after_create :notify_users! + + def self.publish!(topic, user, meta) + create!(kind: 'topic_updated', + eventable: topic, + user: user, + meta: meta) + end +end diff --git a/app/models/mapping.rb b/app/models/mapping.rb index f7219008..99d23db0 100644 --- a/app/models/mapping.rb +++ b/app/models/mapping.rb @@ -6,6 +6,7 @@ class Mapping < ApplicationRecord belongs_to :mappable, polymorphic: true belongs_to :map, class_name: 'Map', foreign_key: 'map_id', touch: true belongs_to :user + belongs_to :updated_by, class_name: 'User' validates :xloc, presence: true, unless: proc { |m| m.mappable_type == 'Synapse' } @@ -16,6 +17,10 @@ class Mapping < ApplicationRecord delegate :name, to: :user, prefix: true + after_create :after_created + after_update :after_updated + before_destroy :before_destroyed + def user_image user.image.url end @@ -23,4 +28,35 @@ class Mapping < ApplicationRecord def as_json(_options = {}) super(methods: [:user_name, :user_image]) end + + def after_created + if mappable_type == 'Topic' + meta = {'x': xloc, 'y': yloc, 'mapping_id': id} + Events::TopicAddedToMap.publish!(mappable, map, user, meta) + elsif mappable_type == 'Synapse' + Events::SynapseAddedToMap.publish!(mappable, map, user, meta) + end + end + + def after_updated + if mappable_type == 'Topic' and (xloc_changed? or yloc_changed?) + meta = {'x': xloc, 'y': yloc, 'mapping_id': id} + Events::TopicMovedOnMap.publish!(mappable, map, updated_by, meta) + end + end + + def before_destroyed + if mappable.defer_to_map + mappable.permission = mappable.defer_to_map.permission + mappable.defer_to_map_id = nil + mappable.save + end + + meta = {'mapping_id': id} + if mappable_type == 'Topic' + Events::TopicRemovedFromMap.publish!(mappable, map, updated_by, meta) + elsif mappable_type == 'Synapse' + Events::SynapseRemovedFromMap.publish!(mappable, map, updated_by, meta) + end + end end diff --git a/app/models/synapse.rb b/app/models/synapse.rb index 08512e4f..d14a18f4 100644 --- a/app/models/synapse.rb +++ b/app/models/synapse.rb @@ -22,6 +22,8 @@ class Synapse < ApplicationRecord where(topic1_id: topic_id).or(where(topic2_id: topic_id)) } + after_update :after_updated + delegate :name, to: :user, prefix: true def user_image @@ -39,4 +41,15 @@ class Synapse < ApplicationRecord def as_json(_options = {}) super(methods: [:user_name, :user_image, :collaborator_ids]) end + + def after_updated + attrs = ['desc', 'category', 'permission', 'defer_to_map_id'] + if attrs.any? {|k| changed_attributes.key?(k)} + new = self.attributes.select {|k| attrs.include?(k) } + old = changed_attributes.select {|k| attrs.include?(k) } + meta = new.merge(old) # we are prioritizing the old values, keeping them + meta['changed'] = changed_attributes.keys.select {|k| attrs.include?(k) } + Events::SynapseUpdated.publish!(self, user, meta) + end + end end diff --git a/app/models/topic.rb b/app/models/topic.rb index 256fc604..e5ea90ee 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -16,6 +16,7 @@ class Topic < ApplicationRecord belongs_to :metacode before_create :create_metamap? + after_update :after_updated validates :permission, presence: true validates :permission, inclusion: { in: Perm::ISSIONS.map(&:to_s) } @@ -135,4 +136,15 @@ class Topic < ApplicationRecord self.link = Rails.application.routes.url_helpers .map_url(host: ENV['MAILER_DEFAULT_URL'], id: @map.id) end + + def after_updated + attrs = ['name', 'desc', 'link', 'metacode_id', 'permission', 'defer_to_map_id'] + if attrs.any? {|k| changed_attributes.key?(k)} + new = self.attributes.select {|k| attrs.include?(k) } + old = changed_attributes.select {|k| attrs.include?(k) } + meta = new.merge(old) # we are prioritizing the old values, keeping them + meta['changed'] = changed_attributes.keys.select {|k| attrs.include?(k) } + Events::TopicUpdated.publish!(self, user, meta) + end + end end diff --git a/app/models/webhooks/slack/base.rb b/app/models/webhooks/slack/base.rb index ba4e9ea5..27f95861 100644 --- a/app/models/webhooks/slack/base.rb +++ b/app/models/webhooks/slack/base.rb @@ -16,45 +16,14 @@ Webhooks::Slack::Base = Struct.new(:webhook, :event) do delegate :channel, to: :webhook - def attachments - [{ - title: attachment_title, - text: attachment_text, - fields: attachment_fields, - fallback: attachment_fallback - }] - end - alias_method :read_attribute_for_serialization, :send private - # def motion_vote_field - # { - # title: "Vote on this proposal", - # value: "#{proposal_link(eventable, "yes")} · " + - # "#{proposal_link(eventable, "abstain")} · " + - # "#{proposal_link(eventable, "no")} · " + - # "#{proposal_link(eventable, "block")}" - # } - # end - def view_map_on_metamaps(text = nil) "<#{map_url(event.map)}|#{text || event.map.name}>" end - # def view_discussion_on_loomio(params = {}) - # { value: discussion_link(I18n.t(:"webhooks.slack.view_it_on_loomio"), params) } - # end - - # def proposal_link(proposal, position = nil) - # discussion_link position || proposal.name, { proposal: proposal.key, position: position } - # end - - # def discussion_link(text = nil, params = {}) - # "<#{discussion_url(eventable.map, params)}|#{text || eventable.discussion.title}>" - # end - def eventable @eventable ||= event.eventable end @@ -63,12 +32,3 @@ Webhooks::Slack::Base = Struct.new(:webhook, :event) do @author ||= eventable.author end end - -# webhooks: -# slack: -# motion_closed: "*%{name}* has closed" -# motion_closing_soon: "*%{name}* has a proposal closing in 24 hours" -# motion_outcome_created: "*%{author}* published an outcome in *%{name}*" -# motion_outcome_updated: "*%{author}* updated the outcome for *%{name}*" -# new_motion: "*%{author}* started a new proposal in *%{name}*" -# view_it_on_loomio: "View it on Loomio" diff --git a/app/models/webhooks/slack/conversation_started_on_map.rb b/app/models/webhooks/slack/conversation_started_on_map.rb index daf2270e..6b6595ce 100644 --- a/app/models/webhooks/slack/conversation_started_on_map.rb +++ b/app/models/webhooks/slack/conversation_started_on_map.rb @@ -3,24 +3,4 @@ class Webhooks::Slack::ConversationStartedOnMap < Webhooks::Slack::Base def text "There is a live conversation starting on map *#{event.map.name}*. #{view_map_on_metamaps('Join in!')}" end - # TODO: it would be sweet if it sends it with the metacode as the icon_url - - def attachment_fallback - '' # {}"*#{eventable.name}*\n#{eventable.description}\n" - end - - def attachment_title - '' # proposal_link(eventable) - end - - def attachment_text - '' # "#{eventable.description}\n" - end - - def attachment_fields - [{ - title: 'nothing', - value: 'nothing' - }] # [motion_vote_field] - end end diff --git a/app/models/webhooks/slack/synapse_added_to_map.rb b/app/models/webhooks/slack/synapse_added_to_map.rb index 5157afa7..3d944878 100644 --- a/app/models/webhooks/slack/synapse_added_to_map.rb +++ b/app/models/webhooks/slack/synapse_added_to_map.rb @@ -1,25 +1,7 @@ # frozen_string_literal: true class Webhooks::Slack::SynapseAddedToMap < Webhooks::Slack::Base def text - "\"*#{eventable.mappable.topic1.name}* #{eventable.mappable.desc || '->'} *#{eventable.mappable.topic2.name}*\" was added as a connection to the map *#{view_map_on_metamaps}*" - end - - def attachment_fallback - '' # {}"*#{eventable.name}*\n#{eventable.description}\n" - end - - def attachment_title - '' # proposal_link(eventable) - end - - def attachment_text - '' # "#{eventable.description}\n" - end - - def attachment_fields - [{ - title: 'nothing', - value: 'nothing' - }] # [motion_vote_field] + connector = eventable.desc.empty? ? '->' : eventable.desc + "\"*#{eventable.topic1.name}* #{connector} *#{eventable.topic2.name}*\" was added as a connection by *#{event.user.name}* to the map *#{view_map_on_metamaps}*" end end diff --git a/app/models/webhooks/slack/synapse_removed_from_map.rb b/app/models/webhooks/slack/synapse_removed_from_map.rb new file mode 100644 index 00000000..06d31206 --- /dev/null +++ b/app/models/webhooks/slack/synapse_removed_from_map.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +class Webhooks::Slack::SynapseRemovedFromMap < Webhooks::Slack::Base + def text + connector = eventable.desc.empty? ? '->' : eventable.desc + # todo express correct directionality of arrows when desc is empty + "\"*#{eventable.topic1.name}* #{connector} *#{eventable.topic2.name}*\" was removed by *#{event.user.name}* as a connection from the map *#{view_map_on_metamaps}*" + end +end diff --git a/app/models/webhooks/slack/topic_added_to_map.rb b/app/models/webhooks/slack/topic_added_to_map.rb index d3a19760..4f726069 100644 --- a/app/models/webhooks/slack/topic_added_to_map.rb +++ b/app/models/webhooks/slack/topic_added_to_map.rb @@ -1,26 +1,7 @@ # frozen_string_literal: true class Webhooks::Slack::TopicAddedToMap < Webhooks::Slack::Base def text - "New #{eventable.mappable.metacode.name} topic *#{eventable.mappable.name}* was added to the map *#{view_map_on_metamaps}*" + "*#{eventable.name}* was added by *#{event.user.name}* to the map *#{view_map_on_metamaps}*" end # TODO: it would be sweet if it sends it with the metacode as the icon_url - - def attachment_fallback - '' # {}"*#{eventable.name}*\n#{eventable.description}\n" - end - - def attachment_title - '' # proposal_link(eventable) - end - - def attachment_text - '' # "#{eventable.description}\n" - end - - def attachment_fields - [{ - title: 'nothing', - value: 'nothing' - }] # [motion_vote_field] - end end diff --git a/app/models/webhooks/slack/topic_moved_on_map.rb b/app/models/webhooks/slack/topic_moved_on_map.rb new file mode 100644 index 00000000..dfe088ed --- /dev/null +++ b/app/models/webhooks/slack/topic_moved_on_map.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +class Webhooks::Slack::TopicMovedOnMap < Webhooks::Slack::Base + def text + "*#{eventable.name}* was moved by *#{event.user.name}* on the map *#{view_map_on_metamaps}*" + end +end diff --git a/app/models/webhooks/slack/topic_removed_from_map.rb b/app/models/webhooks/slack/topic_removed_from_map.rb new file mode 100644 index 00000000..05a79c3b --- /dev/null +++ b/app/models/webhooks/slack/topic_removed_from_map.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +class Webhooks::Slack::TopicRemovedFromMap < Webhooks::Slack::Base + def text + "*#{eventable.name}* was removed by *#{event.user.name}* from the map *#{view_map_on_metamaps}*" + end +end diff --git a/app/models/webhooks/slack/user_present_on_map.rb b/app/models/webhooks/slack/user_present_on_map.rb index c3185e48..4cee2992 100644 --- a/app/models/webhooks/slack/user_present_on_map.rb +++ b/app/models/webhooks/slack/user_present_on_map.rb @@ -3,24 +3,4 @@ class Webhooks::Slack::UserPresentOnMap < Webhooks::Slack::Base def text "Mapper *#{event.user.name}* has joined the map *#{event.map.name}*. #{view_map_on_metamaps('Map with them')}" end - # TODO: it would be sweet if it sends it with the metacode as the icon_url - - def attachment_fallback - '' # {}"*#{eventable.name}*\n#{eventable.description}\n" - end - - def attachment_title - '' # proposal_link(eventable) - end - - def attachment_text - '' # "#{eventable.description}\n" - end - - def attachment_fields - [{ - title: 'nothing', - value: 'nothing' - }] # [motion_vote_field] - end end diff --git a/app/serializers/api/v2/mapping_serializer.rb b/app/serializers/api/v2/mapping_serializer.rb index 19e7318e..30c9bd7f 100644 --- a/app/serializers/api/v2/mapping_serializer.rb +++ b/app/serializers/api/v2/mapping_serializer.rb @@ -14,6 +14,7 @@ module Api def self.embeddable { user: {}, + updated_by: {}, map: {} } end diff --git a/app/serializers/webhook_serializer.rb b/app/serializers/webhook_serializer.rb index a2acf869..c1f0e266 100644 --- a/app/serializers/webhook_serializer.rb +++ b/app/serializers/webhook_serializer.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class WebhookSerializer < ActiveModel::Serializer - attributes :text, :username, :icon_url # , :attachments + attributes :text, :username, :icon_url attribute :channel, if: :has_channel? def has_channel? diff --git a/db/migrate/20161214140124_add_meta_to_events.rb b/db/migrate/20161214140124_add_meta_to_events.rb new file mode 100644 index 00000000..edbee3d6 --- /dev/null +++ b/db/migrate/20161214140124_add_meta_to_events.rb @@ -0,0 +1,5 @@ +class AddMetaToEvents < ActiveRecord::Migration[5.0] + def change + add_column :events, :meta, :json + end +end diff --git a/db/migrate/20161216174257_add_updated_by_to_mappings.rb b/db/migrate/20161216174257_add_updated_by_to_mappings.rb new file mode 100644 index 00000000..e28b8281 --- /dev/null +++ b/db/migrate/20161216174257_add_updated_by_to_mappings.rb @@ -0,0 +1,5 @@ +class AddUpdatedByToMappings < ActiveRecord::Migration[5.0] + def change + add_reference :mappings, :updated_by, foreign_key: {to_table: :users} + end +end diff --git a/db/schema.rb b/db/schema.rb index 5839929c..b30d597e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161125175229) do +ActiveRecord::Schema.define(version: 20161216174257) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -49,6 +49,7 @@ ActiveRecord::Schema.define(version: 20161125175229) do t.integer "map_id" t.datetime "created_at" t.datetime "updated_at" + t.json "meta" t.index ["eventable_type", "eventable_id"], name: "index_events_on_eventable_type_and_eventable_id", using: :btree t.index ["map_id"], name: "index_events_on_map_id", using: :btree t.index ["user_id"], name: "index_events_on_user_id", using: :btree @@ -128,10 +129,12 @@ ActiveRecord::Schema.define(version: 20161125175229) do t.datetime "updated_at", null: false t.integer "mappable_id" t.string "mappable_type" + t.integer "updated_by_id" t.index ["map_id", "synapse_id"], name: "index_mappings_on_map_id_and_synapse_id", using: :btree t.index ["map_id", "topic_id"], name: "index_mappings_on_map_id_and_topic_id", using: :btree t.index ["map_id"], name: "index_mappings_on_map_id", using: :btree t.index ["mappable_id", "mappable_type"], name: "index_mappings_on_mappable_id_and_mappable_type", using: :btree + t.index ["updated_by_id"], name: "index_mappings_on_updated_by_id", using: :btree t.index ["user_id"], name: "index_mappings_on_user_id", using: :btree end @@ -336,5 +339,6 @@ ActiveRecord::Schema.define(version: 20161125175229) do add_foreign_key "mailboxer_conversation_opt_outs", "mailboxer_conversations", column: "conversation_id", name: "mb_opt_outs_on_conversations_id" add_foreign_key "mailboxer_notifications", "mailboxer_conversations", column: "conversation_id", name: "notifications_on_conversation_id" add_foreign_key "mailboxer_receipts", "mailboxer_notifications", column: "notification_id", name: "receipts_on_notification_id" + add_foreign_key "mappings", "users", column: "updated_by_id" add_foreign_key "tokens", "users" end diff --git a/doc/api/apis/mappings.raml b/doc/api/apis/mappings.raml index 00298387..af4965cb 100644 --- a/doc/api/apis/mappings.raml +++ b/doc/api/apis/mappings.raml @@ -1,6 +1,6 @@ #type: collection get: - is: [ embeddable: { embedFields: "user,map" }, orderable, pageable ] + is: [ embeddable: { embedFields: "user,updated_by,map" }, orderable, pageable ] securedBy: [ null, token, oauth_2_0, cookie ] responses: 200: @@ -31,7 +31,7 @@ post: /{id}: #type: item get: - is: [ embeddable: { embedFields: "user,map" } ] + is: [ embeddable: { embedFields: "user,updated_by,map" } ] securedBy: [ null, token, oauth_2_0, cookie ] responses: 200: diff --git a/doc/api/examples/mapping.json b/doc/api/examples/mapping.json index c4aa87bf..93d38bdb 100644 --- a/doc/api/examples/mapping.json +++ b/doc/api/examples/mapping.json @@ -6,6 +6,7 @@ "mappable_id": 1, "mappable_type": "Synapse", "user_id": 1, + "updated_by_id": 1, "map_id": 1 } } diff --git a/doc/api/examples/mappings.json b/doc/api/examples/mappings.json index 5a4a99c3..99f2e58d 100644 --- a/doc/api/examples/mappings.json +++ b/doc/api/examples/mappings.json @@ -8,6 +8,7 @@ "mappable_type": "Topic", "updated_at": "2016-03-25T08:44:07.152Z", "user_id": 1, + "updated_by_id": 1, "xloc": -271, "yloc": 22 }, @@ -19,6 +20,7 @@ "mappable_type": "Topic", "updated_at": "2016-03-25T08:44:13.907Z", "user_id": 1, + "updated_by_id": 1, "xloc": -12, "yloc": 61 }, @@ -30,6 +32,7 @@ "mappable_type": "Topic", "updated_at": "2016-03-25T08:44:19.333Z", "user_id": 1, + "updated_by_id": 1, "xloc": -93, "yloc": -90 }, @@ -40,7 +43,8 @@ "mappable_id": 1, "mappable_type": "Synapse", "updated_at": "2016-03-25T08:44:21.337Z", - "user_id": 1 + "user_id": 1, + "updated_by_id": 1 } ], "page": { diff --git a/doc/api/schemas/_mapping.json b/doc/api/schemas/_mapping.json index 8789c5ec..efd12c92 100644 --- a/doc/api/schemas/_mapping.json +++ b/doc/api/schemas/_mapping.json @@ -35,6 +35,12 @@ }, "user": { "$ref": "_user.json" + }, + "updated_by_id": { + "$ref": "_id.json" + }, + "updated_by": { + "$ref": "_user.json" } }, "required": [ @@ -56,6 +62,12 @@ { "required": [ "user_id" ] }, { "required": [ "user" ] } ] + }, + { + "oneOf": [ + { "required": [ "updated_by_id" ] }, + { "required": [ "updated_by" ] } + ] } ] }