diff --git a/app/models/outcome_import.rb b/app/models/outcome_import.rb
new file mode 100644
index 00000000000..612bd8bd0ad
--- /dev/null
+++ b/app/models/outcome_import.rb
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2018 - present Instructure, Inc.
+#
+# This file is part of Canvas.
+#
+# Canvas is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, version 3 of the License.
+#
+# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see .
+#
+
+class OutcomeImport < ApplicationRecord
+ include Workflow
+ belongs_to :context, polymorphic: %i[account course]
+ belongs_to :attachment
+ belongs_to :user
+ has_many :outcome_import_errors
+
+ validates :context_type, presence: true
+ validates :context_id, presence: true
+ validates :workflow_state, presence: true
+
+ workflow do
+ state :initializing
+ state :created
+ state :importing
+ state :imported
+ state :imported_with_messages
+ state :aborted
+ state :failed
+ state :failed_with_messages
+ end
+end
diff --git a/app/models/outcome_import_error.rb b/app/models/outcome_import_error.rb
new file mode 100644
index 00000000000..68870a59c42
--- /dev/null
+++ b/app/models/outcome_import_error.rb
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2018 - present Instructure, Inc.
+#
+# This file is part of Canvas.
+#
+# Canvas is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, version 3 of the License.
+#
+# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see .
+#
+
+class OutcomeImportError < ApplicationRecord
+ belongs_to :outcome_import, inverse_of: :outcome_import_errors
+
+ validates :outcome_import_id, presence: true
+ validates :message, presence: true
+end
diff --git a/db/migrate/20180224031729_create_outcome_imports.rb b/db/migrate/20180224031729_create_outcome_imports.rb
new file mode 100644
index 00000000000..029a654673c
--- /dev/null
+++ b/db/migrate/20180224031729_create_outcome_imports.rb
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2018 - present Instructure, Inc.
+#
+# This file is part of Canvas.
+#
+# Canvas is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, version 3 of the License.
+#
+# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see .
+#
+
+class CreateOutcomeImports < ActiveRecord::Migration[5.0]
+ tag :predeploy
+
+ def change
+ create_table :outcome_imports do |t|
+ t.string :workflow_state, null: false
+ t.integer :context_id, limit: 8, null: false
+ t.string :context_type, null: false
+ t.references :user, foreign_key: true, limit: 8
+ t.references :attachment, foreign_key: true, limit: 8
+ t.integer :progress
+ t.timestamp :ended_at
+
+ t.timestamps
+ end
+
+ add_index :outcome_imports, %i[context_type context_id]
+ end
+end
diff --git a/db/migrate/20180224031730_create_outcome_import_errors.rb b/db/migrate/20180224031730_create_outcome_import_errors.rb
new file mode 100644
index 00000000000..5cc70594584
--- /dev/null
+++ b/db/migrate/20180224031730_create_outcome_import_errors.rb
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2018 - present Instructure, Inc.
+#
+# This file is part of Canvas.
+#
+# Canvas is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, version 3 of the License.
+#
+# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see .
+#
+
+class CreateOutcomeImportErrors < ActiveRecord::Migration[5.0]
+ tag :predeploy
+
+ def change
+ create_table :outcome_import_errors do |t|
+ t.references :outcome_import, foreign_key: true, limit: 8, null: false
+ t.string :message, null: false, limit: 255
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/models/outcome_import_error_spec.rb b/spec/models/outcome_import_error_spec.rb
new file mode 100644
index 00000000000..3eb295b164c
--- /dev/null
+++ b/spec/models/outcome_import_error_spec.rb
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2018 - present Instructure, Inc.
+#
+# This file is part of Canvas.
+#
+# Canvas is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, version 3 of the License.
+#
+# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see .
+#
+
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
+
+describe OutcomeImportError, type: :model do
+ describe 'associations' do
+ it { is_expected.to belong_to(:outcome_import) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of :message }
+ it { is_expected.to validate_presence_of :outcome_import_id }
+ end
+end
diff --git a/spec/models/outcome_import_spec.rb b/spec/models/outcome_import_spec.rb
new file mode 100644
index 00000000000..b7febda8880
--- /dev/null
+++ b/spec/models/outcome_import_spec.rb
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2018 - present Instructure, Inc.
+#
+# This file is part of Canvas.
+#
+# Canvas is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, version 3 of the License.
+#
+# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see .
+#
+
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
+
+describe OutcomeImport, type: :model do
+ describe 'associations' do
+ it { is_expected.to belong_to(:context) }
+ it { is_expected.to belong_to(:attachment) }
+ it { is_expected.to belong_to(:user) }
+ it { is_expected.to have_many(:outcome_import_errors) }
+ end
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of :context_type }
+ it { is_expected.to validate_presence_of :context_id }
+ end
+end