+ {{JSON.stringify(published_session.integrations, undefined, 2)}}
+
@@ -48,6 +51,8 @@ import SessionSchedule from './session_schedule';
import SessionConflicts from '../conflicts/session_conflicts.vue'
import { sessionConflictModel } from '@/store/session_conflict.store'
import settingsMixin from "@/store/settings.mixin";
+import { personSessionMixin } from '@/mixins';
+import { publishedSessionModel } from '@/store/published_session.store';
export default {
name: "SessionTabs",
@@ -65,16 +70,20 @@ export default {
},
mixins: [
modelUtilsMixin,
- settingsMixin
+ settingsMixin,
+ personSessionMixin
],
data: () => ({
sessionAssignmentModel,
- sessionConflictModel
+ sessionConflictModel,
}),
computed: {
session() {
return this.selected_model(sessionModel);
},
+ published_session() {
+ return this.selected_model(publishedSessionModel) || {};
+ },
assignmentFilter() {
let filter = {
"op": "all",
@@ -120,6 +129,9 @@ export default {
case 4:
path = `notes/${this.id}`;
break;
+ case 5:
+ path = `integrations/${this.id}`
+ break;
}
// console.debug("****** Path:", path)
// change the router path to match the current tab
@@ -138,7 +150,10 @@ export default {
(obj) => {
this.select_model(sessionModel, obj);
}
- )
+ ),
+ this.fetch_model_by_id(publishedSessionModel, this.id).then( (obj) => {
+ this.select_model(publishedSessionModel, obj)
+ })
}
}
diff --git a/app/javascript/store/integration.store.js b/app/javascript/store/integration.store.js
new file mode 100644
index 000000000..c00767a21
--- /dev/null
+++ b/app/javascript/store/integration.store.js
@@ -0,0 +1,28 @@
+import { FETCH } from "./model.store"
+
+export const integrationModel = 'integration'
+
+export const integrationEndpoints = {
+ [integrationModel]: 'integration'
+}
+
+export const FETCH_AIRMEET_INTEGRATION = 'FETCH AIRMEET INTEGRATION'
+export const SET_AIRMEET_INTEGRATION = 'SET AIRMEET INTEGRATION'
+
+export const integrationStore = {
+ state: {
+ airmeet: {}
+ },
+ mutations: {
+ [SET_AIRMEET_INTEGRATION] (state, integration) {
+ state.airmeet = integration;
+ }
+ },
+ actions: {
+ [FETCH_AIRMEET_INTEGRATION] ({dispatch, commit}) {
+ dispatch(FETCH, {url: 'integration/airmeet'}).then(data => {
+ commit(SET_AIRMEET_INTEGRATION, data);
+ })
+ }
+ }
+}
diff --git a/app/javascript/store/model.store.js b/app/javascript/store/model.store.js
index 677963979..3f7939da2 100644
--- a/app/javascript/store/model.store.js
+++ b/app/javascript/store/model.store.js
@@ -75,9 +75,11 @@ import { configurationStore, configurationEndpoints } from './configuration.stor
// session add-ons
import { sessionAssignmentStore, sessionAssignmentEndpoints } from './session_assignment.store';
+import { publishedSessionEndpoints, publishedSessionStore } from './published_session.store';
// global app things
import { appStore } from './app.store';
+import { integrationEndpoints, integrationStore } from './integration.store';
// schedule workflow
import { scheduleWorkflowStore, scheduleWorkflowEndpoints } from './schedule_workflow/schedule_workflow.store';
@@ -106,6 +108,8 @@ const endpoints = {
// ...personExclusionEndpoints,
...scheduleWorkflowEndpoints,
...personScheduleApprovalEndpoints,
+ ...publishedSessionEndpoints,
+ ...integrationEndpoints,
}
// NOTE: this is really the store
@@ -142,6 +146,7 @@ export const store = new Vuex.Store({
...sessionConflictStore.selected,
...formatStore.selected,
...personScheduleApprovalStore.selected,
+ ...publishedSessionStore.selected,
},
...personSessionStore.state,
...settingsStore.state,
@@ -153,6 +158,7 @@ export const store = new Vuex.Store({
...roomStore.state,
...appStore.state,
...scheduleWorkflowStore.state,
+ ...integrationStore.state,
// ...mailingStore.state
},
getters: {
@@ -211,7 +217,8 @@ export const store = new Vuex.Store({
...surveyStore.mutations,
...searchStateStore.mutations,
...roomStore.mutations,
- ...appStore.mutations
+ ...appStore.mutations,
+ ...integrationStore.mutations
},
actions: {
/**
@@ -381,5 +388,6 @@ export const store = new Vuex.Store({
...sessionConflictStore.actions,
...scheduleWorkflowStore.actions,
...personScheduleApprovalStore.actions,
+ ...integrationStore.actions,
}
})
diff --git a/app/javascript/store/published_session.store.js b/app/javascript/store/published_session.store.js
new file mode 100644
index 000000000..2acf4d994
--- /dev/null
+++ b/app/javascript/store/published_session.store.js
@@ -0,0 +1,11 @@
+export const publishedSessionModel = 'published_session'
+
+export const publishedSessionEndpoints = {
+ [publishedSessionModel]: 'published_session'
+}
+
+export const publishedSessionStore = {
+ selected: {
+ [publishedSessionModel]: null
+ }
+}
diff --git a/app/models/integration.rb b/app/models/integration.rb
new file mode 100644
index 000000000..66c9978d0
--- /dev/null
+++ b/app/models/integration.rb
@@ -0,0 +1,2 @@
+class Integration < ApplicationRecord
+end
diff --git a/app/policies/integration_policy.rb b/app/policies/integration_policy.rb
new file mode 100644
index 000000000..85e09549d
--- /dev/null
+++ b/app/policies/integration_policy.rb
@@ -0,0 +1,19 @@
+class IntegrationPolicy < PlannerPolicy
+ def publish?
+ allowed?(action: :publish)
+ end
+
+ def airmeet?
+ allowed?(action: :airmeet)
+ end
+
+ def update?
+ allowed?(action: :update)
+ end
+
+ class Scope < PlannerPolicy::Scope
+ def resolve
+ scope.all
+ end
+ end
+end
diff --git a/app/policies/published_session_policy.rb b/app/policies/published_session_policy.rb
new file mode 100644
index 000000000..16736953f
--- /dev/null
+++ b/app/policies/published_session_policy.rb
@@ -0,0 +1,7 @@
+class PublishedSessionPolicy < PlannerPolicy
+ class Scope < PlannerPolicy::Scope
+ def resolve
+ scope.all
+ end
+ end
+end
diff --git a/app/serializers/integration_serializer.rb b/app/serializers/integration_serializer.rb
new file mode 100644
index 000000000..0120b3c9b
--- /dev/null
+++ b/app/serializers/integration_serializer.rb
@@ -0,0 +1,15 @@
+class IntegrationSerializer
+ include JSONAPI::Serializer
+
+ attributes :lock_version, :created_at, :updated_at,
+ :name, :id
+
+ attribute :config do |integration|
+ {airmeet_id: integration.config["airmeet_id"],
+ airmeet_host: integration.config["airmeet_host"]
+ }
+ end
+
+
+
+end
diff --git a/app/serializers/person_serializer.rb b/app/serializers/person_serializer.rb
index f58785557..f757ac4c5 100644
--- a/app/serializers/person_serializer.rb
+++ b/app/serializers/person_serializer.rb
@@ -41,7 +41,8 @@ class PersonSerializer #< ActiveModel::Serializer
:timezone,
:twelve_hour,
:attendance_type,
- :availability_notes
+ :availability_notes,
+ :integrations
# status and comments hidden except for staff
protected_attributes :con_state, :comments
diff --git a/app/serializers/published_session_serializer.rb b/app/serializers/published_session_serializer.rb
index e7bffc08a..4150e7cb1 100644
--- a/app/serializers/published_session_serializer.rb
+++ b/app/serializers/published_session_serializer.rb
@@ -1,5 +1,5 @@
class PublishedSessionSerializer
include JSONAPI::Serializer
- attributes :id, :lock_version, :created_at, :updated_at
+ attributes :id, :lock_version, :created_at, :updated_at, :integrations
end
diff --git a/app/serializers/room_serializer.rb b/app/serializers/room_serializer.rb
index a675c0b05..772c3ee93 100644
--- a/app/serializers/room_serializer.rb
+++ b/app/serializers/room_serializer.rb
@@ -5,7 +5,7 @@ class RoomSerializer
:name, :sort_order, :purpose, :comment, :capacity, :floor,
:open_for_schedule, :is_virtual, :area_of_space,
:length, :width, :height,
- :venue_id, :room_set_id
+ :venue_id, :room_set_id, :integrations
end
diff --git a/app/services/airmeet_api_service.rb b/app/services/airmeet_api_service.rb
new file mode 100644
index 000000000..16ed3e1c8
--- /dev/null
+++ b/app/services/airmeet_api_service.rb
@@ -0,0 +1,176 @@
+module AirmeetApiService
+ def self.integration
+ @integration ||= Integration.find_or_create_by({name: :airmeet})
+ end
+
+ def self.config
+ integration.config
+ end
+
+ def self.token
+ if !config['token'] || Time.at(config['token_exp']) < Time.now
+ auth
+ else
+ config['token']
+ end
+ end
+
+ def self.airmeet_id
+ config['airmeet_id']
+ end
+
+ def self.airmeet
+ @airmeet ||= Airmeet.new
+ end
+
+ def self.get_participants
+ Airmeet.get("/airmeet/#{airmeet_id}/participants")
+ end
+
+ def self.auth
+ token = airmeet.auth["token"]
+ integration.update({config: config.merge({
+ token: token,
+ token_exp: (Time.now + (29 * 24 * 60 * 60)).to_i
+ })})
+ token
+ end
+
+ def self.info
+ Airmeet.get("/airmeet/#{airmeet_id}/info")
+ end
+
+ def self.get_session(id)
+ info["sessions"].find { |s| s["sessionid"] == id }
+ end
+
+ def self.create_session(sessionTitle:, sessionStartTime:, sessionDuration:, sessionSummary:, hostEmail:, speakerEmails: [], cohostEmails: [])
+ sessionStartTime = sessionStartTime.to_i * 1000
+ Airmeet.post("/airmeet/#{airmeet_id}/session", {
+ body: {
+ sessionTitle: sessionTitle,
+ sessionStartTime: sessionStartTime,
+ sessionDuration: sessionDuration,
+ sessionSummary: sessionSummary,
+ hostEmail: hostEmail,
+ speakerEmails: speakerEmails,
+ cohostEmails: cohostEmails,
+ type: "HOSTING"
+ }.to_json
+ })
+ end
+
+ def self.create_speaker(name:, email:, organisation: "", designation: "", imageUrl: "", bio: "", city: "", country: "")
+ Airmeet.post("/airmeet/#{airmeet_id}/speaker", {
+ body: {
+ name: name,
+ email: email,
+ organisation: organisation,
+ designation: designation,
+ imageUrl: imageUrl,
+ bio: bio || " ",
+ city: city,
+ country: country,
+ }.to_json
+ })
+ end
+
+ def self.person_to_airmeet(person)
+ speaker_email = person.primary_email.email
+ country = nil
+ city = nil
+ if person.integrations["airmeet"]
+ speaker_email = person.integrations["airmeet"]["speaker_email"] || speaker_email
+ country = person.integrations["airmeet"]["country"]
+ city = person.integrations["airmeet"]["city"]
+ end
+ name = person.published_name
+ bio = person.bio
+ args = {name: name, email: speaker_email, bio: bio}
+ if country
+ args[:country] = country
+ end
+ if city
+ args[:city] = city
+ end
+ puts args
+ result = create_speaker(args)
+ puts result
+ person.update({integrations: person.integrations.merge({airmeet: {speaker_email: speaker_email, synced: true, data: args, synced_at: Time.now.iso8601}})})
+ result["email"]
+ end
+
+ def self.session_to_airmeet(session)
+ args = {sessionTitle: "#{session.room.name} - #{session.title} - #{session.format.name} - #{session.area_list.join(", ")}",
+ sessionSummary: session.description,
+ sessionDuration: session.duration,
+ sessionStartTime: session.start_time,
+ hostEmail: room_hosts[session.room_id]
+ };
+ participants = session.published_session_assignments.filter { |sa| sa.session_assignment_role_type_id == moderator_id || sa.session_assignment_role_type_id == participant_id }.map { |sa| sa.person }
+ if session.environment == "virtual"
+ args[:speakerEmails] = participants.map{|p| p.integrations["airmeet"]["speaker_email"]}
+ args[:cohostEmails] = session.published_session_assignments.filter { |sa| sa.session_assignment_role_type_id == moderator_id }.map { |sa| sa.person.integrations["airmeet"]["speaker_email"] }
+ end
+ puts args
+ result = create_session(args);
+ puts result
+ session.update({integrations: session.integrations.merge({airmeet: {session_id: result["uid"], synced: true, synced_at: Time.now(), data: args}})})
+ if session.environment == "virtual"
+ people_tokens = result["token"].inject({}) {|p,c| p[c["email"]] = c["token"]; p}
+ participants.each { |p| p.update({integrations: p.integrations.merge({airmeet: (p.integrations["airmeet"] || {}).merge({token: people_tokens[(p.integrations["airmeet"] || {})["speaker_email"]]})})})}
+ end
+ end
+
+ def self.room_hosts
+ @room_hosts ||= Room.where.not(integrations: {}).inject({}) { |p, c| p[c.id] = (c.integrations["airmeet"] || {})["room_host_email"]; p }
+ end
+
+ def self.virtual_people
+ Person.left_outer_joins(:published_session_assignments, :published_sessions, :primary_email)
+ .where(published_sessions: { environment: 'virtual' }, published_session_assignments: {session_assignment_role_type_id: [moderator_id, participant_id]})
+ .distinct
+ end
+
+ def self.virtual_sessions
+ SessionService.published_sessions.where(streamed: true)
+ end
+
+ def self.moderator_id
+ @moderator_id = SessionAssignmentRoleType.find_by(name: 'Moderator').id
+ end
+
+ def self.participant_id
+ @participant_id = SessionAssignmentRoleType.find_by(name: 'Participant').id
+ end
+
+ def self.sync_to_airmeet
+ virtual_people.map { |p| person_to_airmeet(p) }
+ virtual_sessions.map { |s| session_to_airmeet(s) }
+ puts "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA IT WORKED"
+ end
+
+ class Airmeet
+ include HTTParty
+ base_uri "https://api-gateway.airmeet.com/prod"
+
+ headers 'Content-Type' => 'application/json'
+
+ # TODO fix me for not testing
+ default_options.update(verify: false)
+
+ def auth
+ self.class.post("/auth", {
+ headers: {
+ "X-Airmeet-Access-Key": ENV["AIRMEET_ACCESS_KEY"],
+ "X-Airmeet-Secret-Key": ENV["AIRMEET_SECRET_KEY"],
+ "X-Airmeet-Access-Token": ""
+ },
+ verify: false
+ })
+ end
+
+ headers 'X-Airmeet-Access-Token' => AirmeetApiService.token
+ end
+
+end
diff --git a/config/routes.rb b/config/routes.rb
index a0f818daf..c6d9f4522 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -94,7 +94,9 @@
get 'report/schedule_reports/schedule_diff(/:from)(/:to)', to: 'reports/schedule_reports#schedule_diff'
get 'publication_date/reset', to: 'publication_dates#reset'
- resources :publication_dates, path: 'publication_date', only: [:index]
+ resources :publication_dates, path: 'publication_date', only: [:index, :update]
+ resources :integrations, path: 'integration', only: [:index, :update]
+ get 'integration/airmeet', to: 'integrations#airmeet'
resources :availabilities, path: 'availability', except: [:index]
resources :person_exclusions, path: 'person_exclusion', except: [:index]
diff --git a/db/integrations.md b/db/integrations.md
new file mode 100644
index 000000000..5df98effa
--- /dev/null
+++ b/db/integrations.md
@@ -0,0 +1,57 @@
+This page should document what data structrue is expected for the integration columns
+
+## Config
+
+ {
+ "airmeet_id": "uuid",
+ "airmeet_host": "host email",
+ "active": true,
+ "token": "jwt set by the system here"
+ "token_exp": "time set by the system here"
+ }
+
+## Session
+
+ {
+ "airmeet": {
+ "synced": true
+ "synced_at": "ISO8601 timestamp",
+ "sessionTitle": "generated string here" ,
+ "sesionStartTime": "epoch in ms",
+ "sessionDuration": "number in minutes",
+ "sessionSummary": "generated string here"
+ "hostEmail": "room email",
+ "speakerEmails": "speaker emails",
+ "cohostEmails": "moderator emails",
+ "sessionId": "??"
+ }
+ }
+
+## Person
+
+ {
+ "airmeet": {
+ "synced": true
+ "speaker_email": "speaker@email.com"
+ "bio": "bio here",
+ "name": "name here"
+ "synced_at": "ISO8601 timestamp"
+ }
+ }
+
+## Session Assignment
+
+ {
+ "airmeet": {
+ "magic_link": "here"
+ "synced_at": "ISO8601 timestamp"
+ }
+ }
+
+## Room
+
+ {
+ "airmeet": {
+ "room_host_email": "helpdesk+roomname@chicon.org"
+ }
+ }
diff --git a/db/migrate/20220818200500_create_integrations.rb b/db/migrate/20220818200500_create_integrations.rb
new file mode 100644
index 000000000..0f9e91fc2
--- /dev/null
+++ b/db/migrate/20220818200500_create_integrations.rb
@@ -0,0 +1,27 @@
+class CreateIntegrations < ActiveRecord::Migration[6.1]
+ def change
+ create_table :integrations, id: :uuid do |t|
+ t.string :name
+ t.jsonb :config, null: false, default: {}
+
+ t.timestamps
+ end
+
+ create_table :integration_publishes, id: :uuid do |t|
+ t.string :integration_name
+ t.jsonb :data, null: false, default: {}
+ t.datetime :started_at
+ t.datetime :completed_at
+ t.string :created_by
+
+ t.timestamps
+ end
+
+ # fields to hold the integration information for each session/person/session_assignment/room
+ add_column :published_sessions, :integrations, :jsonb, null: false, default: {}
+ add_column :people, :integrations, :jsonb, null: false, default: {}
+ # todo maybe i don't need this one if the tokens are always the same
+ add_column :published_session_assignments, :integrations, :jsonb, null: false, default: {}
+ add_column :rooms, :integrations, :jsonb, null: false, default: {}
+ end
+end
diff --git a/db/migrate/20220821001724_add_lock_version_to_integrations.rb b/db/migrate/20220821001724_add_lock_version_to_integrations.rb
new file mode 100644
index 000000000..842c72b2f
--- /dev/null
+++ b/db/migrate/20220821001724_add_lock_version_to_integrations.rb
@@ -0,0 +1,5 @@
+class AddLockVersionToIntegrations < ActiveRecord::Migration[6.1]
+ def change
+ add_column :integrations, :lock_version, :integer, default: 0
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 34656c4e2..4d3757d1c 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -616,7 +616,8 @@ END) STORED,
attendance_type character varying(200) DEFAULT NULL::character varying,
twelve_hour boolean DEFAULT true,
timezone character varying(500) DEFAULT NULL::character varying,
- availability_notes character varying
+ availability_notes character varying,
+ integrations jsonb DEFAULT '{}'::jsonb NOT NULL
);
@@ -926,6 +927,36 @@ CREATE TABLE public.ignored_conflicts (
);
+--
+-- Name: integration_publishes; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE public.integration_publishes (
+ id uuid DEFAULT public.gen_random_uuid() NOT NULL,
+ integration_name character varying,
+ data jsonb DEFAULT '{}'::jsonb NOT NULL,
+ started_at timestamp without time zone,
+ completed_at timestamp without time zone,
+ created_by character varying,
+ created_at timestamp(6) without time zone NOT NULL,
+ updated_at timestamp(6) without time zone NOT NULL
+);
+
+
+--
+-- Name: integrations; Type: TABLE; Schema: public; Owner: -
+--
+
+CREATE TABLE public.integrations (
+ id uuid DEFAULT public.gen_random_uuid() NOT NULL,
+ name character varying,
+ config jsonb DEFAULT '{}'::jsonb NOT NULL,
+ created_at timestamp(6) without time zone NOT NULL,
+ updated_at timestamp(6) without time zone NOT NULL,
+ lock_version integer DEFAULT 0
+);
+
+
--
-- Name: label_dimensions; Type: TABLE; Schema: public; Owner: -
--
@@ -1351,7 +1382,9 @@ CREATE TABLE public.publication_dates (
dropped_sessions integer DEFAULT 0,
new_assignments integer DEFAULT 0,
updated_assignments integer DEFAULT 0,
- dropped_assignments integer DEFAULT 0
+ dropped_assignments integer DEFAULT 0,
+ sent_external boolean DEFAULT false NOT NULL,
+ lock_version integer DEFAULT 0
);
@@ -1396,7 +1429,8 @@ CREATE TABLE public.published_session_assignments (
session_assignment_role_type_id uuid NOT NULL,
person_id uuid NOT NULL,
sort_order integer,
- visibility public.visibility_enum DEFAULT 'public'::public.visibility_enum
+ visibility public.visibility_enum DEFAULT 'public'::public.visibility_enum,
+ integrations jsonb DEFAULT '{}'::jsonb NOT NULL
);
@@ -1425,7 +1459,8 @@ CREATE TABLE public.published_sessions (
environment public.session_environments_enum DEFAULT 'unknown'::public.session_environments_enum,
minors_participation jsonb,
recorded boolean DEFAULT false NOT NULL,
- streamed boolean DEFAULT false NOT NULL
+ streamed boolean DEFAULT false NOT NULL,
+ integrations jsonb DEFAULT '{}'::jsonb NOT NULL
);
@@ -1451,7 +1486,8 @@ CREATE TABLE public.rooms (
room_set_id uuid,
length numeric,
width numeric,
- height numeric
+ height numeric,
+ integrations jsonb DEFAULT '{}'::jsonb NOT NULL
);
@@ -2210,6 +2246,22 @@ ALTER TABLE ONLY public.ignored_conflicts
ADD CONSTRAINT ignored_conflicts_pkey PRIMARY KEY (id);
+--
+-- Name: integration_publishes integration_publishes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.integration_publishes
+ ADD CONSTRAINT integration_publishes_pkey PRIMARY KEY (id);
+
+
+--
+-- Name: integrations integrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY public.integrations
+ ADD CONSTRAINT integrations_pkey PRIMARY KEY (id);
+
+
--
-- Name: label_dimensions label_dimensions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@@ -3373,6 +3425,9 @@ INSERT INTO "schema_migrations" (version) VALUES
('20220726130346'),
('20220801152151'),
('20220801173704'),
-('20220801195644');
+('20220801195644'),
+('20220818022629'),
+('20220818200500'),
+('20220821001724');
diff --git a/lib/tasks/chicon_airmeet.rake b/lib/tasks/chicon_airmeet.rake
new file mode 100644
index 000000000..a9d5de663
--- /dev/null
+++ b/lib/tasks/chicon_airmeet.rake
@@ -0,0 +1,37 @@
+namespace :chicon do
+ desc "Configure airmeet for chicon"
+ task configure_airmeet_test: :environment do
+ integration = Integration.find_or_create_by({name: :airmeet})
+ # this data is for testing. we are going to need the real information for the actual show here at some point.
+ # and/or create a ui for it but let's try this first.
+ # none of this gets you actual access to the airmeet so it's probably ok to actually check in???
+ integration.update!({
+ config: {
+ airmeet_id: "ac4b0bc0-1079-11ed-bed5-3112cc3e0b52",
+ airmeet_host: "gail.terman@chicon.org",
+ active: true
+ }
+ })
+
+ # Room.find_by({name: "Airmeet 1"}).update({integrations: {airmeet: {room_host_email: 'gail.terman@chicon.org'}}})
+ end
+
+ task configure_airmeet: :environment do
+ integration = Integration.find_or_create_by({name: :airmeet})
+ # this data is for testing. we are going to need the real information for the actual show here at some point.
+ # and/or create a ui for it but let's try this first.
+ # none of this gets you actual access to the airmeet so it's probably ok to actually check in???
+ integration.update!({
+ config: {
+ airmeet_id: "NOT SET YET",
+ airmeet_host: "NOT SET YET",
+ active: false
+ }
+ })
+ end
+
+ task sync_airmeet: :environment do
+ AirmeetApiService.sync_to_airmeet
+ end
+end
+
diff --git a/lib/tasks/rbac.rake b/lib/tasks/rbac.rake
index 8763a1d43..4ca88238c 100644
--- a/lib/tasks/rbac.rake
+++ b/lib/tasks/rbac.rake
@@ -281,6 +281,9 @@ namespace :rbac do
},
"publication_date": {
"index": false
+ },
+ "integration": {
+ "publish": false
}
})
end
@@ -590,6 +593,9 @@ namespace :rbac do
},
"publication_date": {
"index": true
+ },
+ "integration": {
+ "publish": false
}
})
end
@@ -899,6 +905,9 @@ namespace :rbac do
},
"publication_date": {
"index": true
+ },
+ "integration": {
+ "publish": true
}
})
end
diff --git a/spec/helpers/integrations_helper_spec.rb b/spec/helpers/integrations_helper_spec.rb
new file mode 100644
index 000000000..c39979c7b
--- /dev/null
+++ b/spec/helpers/integrations_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+# Specs in this file have access to a helper object that includes
+# the IntegrationsHelper. For example:
+#
+# describe IntegrationsHelper do
+# describe "string concat" do
+# it "concats two strings with spaces" do
+# expect(helper.concat_strings("this","that")).to eq("this that")
+# end
+# end
+# end
+RSpec.describe IntegrationsHelper, type: :helper do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
new file mode 100644
index 000000000..aae8d31da
--- /dev/null
+++ b/spec/models/integration_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Integration, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/requests/integrations_spec.rb b/spec/requests/integrations_spec.rb
new file mode 100644
index 000000000..5426a96db
--- /dev/null
+++ b/spec/requests/integrations_spec.rb
@@ -0,0 +1,7 @@
+require 'rails_helper'
+
+RSpec.describe "Integrations", type: :request do
+ describe "GET /index" do
+ pending "add some examples (or delete) #{__FILE__}"
+ end
+end