Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9b0ab9f
Added:
TaylorBrown96 Nov 19, 2025
d40fc01
Merge pull request #9 from cammyj1122/setupStructure
ananyarrao330 Nov 24, 2025
2c841b9
added field_mappings class
Nov 24, 2025
d851de8
Added importexport helper and import methods.
cammyj1122 Nov 26, 2025
e337816
Added capability to import users with external classes for lookup. Mo…
cammyj1122 Nov 29, 2025
dd8b30f
Finished adding the ability to have duplicate headers with comments r…
cammyj1122 Nov 29, 2025
72e49e6
Changed a small comment and moved a todo.
cammyj1122 Nov 29, 2025
85de9a4
Added the duplicate actions helper and added a place for the array of…
cammyj1122 Nov 29, 2025
3876a11
Started adding the unit tests for the helper file.
cammyj1122 Nov 30, 2025
371ca19
Added tests and fixtures for importable_exportable_helper.rb.
cammyj1122 Nov 30, 2025
0dc32fd
Updated the import controller to return the expected values.
cammyj1122 Nov 30, 2025
2643b2c
A while back the Question table was changed to the Item table. Howeve…
cammyj1122 Nov 30, 2025
afaf5cf
Added a csv file for invalid email for users.
cammyj1122 Nov 30, 2025
3d57637
Merge pull request #10 from cammyj1122/update_question_id_to_item_id
ananyarrao330 Dec 1, 2025
65ecaec
Added import export helper to the Team class
cammyj1122 Dec 1, 2025
3c63a99
Updated external classes to list their fields with the class name app…
cammyj1122 Dec 1, 2025
d13e69d
Implement assignment-specific team export functionality
TaylorBrown96 Dec 2, 2025
3430dc1
added comments that give explicitly verbose descriptions
TaylorBrown96 Dec 2, 2025
5c5dd87
Merged changes i had made to importable_exportable_helper.rb. Updated…
cammyj1122 Dec 2, 2025
58c46d0
Made small fix for user table to populate
cammyj1122 Dec 3, 2025
77e40a5
Fixed var in the backend
cammyj1122 Dec 3, 2025
c47323c
Fixed export in the backend.
cammyj1122 Dec 3, 2025
a4c8de0
Got unique actions working for imports
cammyj1122 Dec 3, 2025
2ff1fe0
Merge branch 'dev' into export
cammyj1122 Dec 3, 2025
298297f
Merge pull request #11 from cammyj1122/export
cammyj1122 Dec 3, 2025
8a46c16
Merge pull request #12 from cammyj1122/dev
cammyj1122 Dec 3, 2025
7f88a13
Added test suite
TaylorBrown96 Dec 3, 2025
e3e6898
Merge remote-tracking branch 'origin/export' into export
TaylorBrown96 Dec 3, 2025
eaa6d11
Fixed helper tests, removed commented out code.
cammyj1122 Dec 5, 2025
e4920bf
Added initial rswag tests for controller
cammyj1122 Dec 5, 2025
09551a1
Merge pull request #13 from cammyj1122/export
cammyj1122 Dec 5, 2025
b04b81d
Merge pull request #14 from cammyj1122/dev
cammyj1122 Dec 5, 2025
6117c20
Merge branch 'main' into main
vihar2712 Dec 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions app/controllers/export_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This controller handles exporting data from the application to various formats.
class ExportController < ApplicationController
before_action :export_params

def index
klass = params[:class].constantize

render json: {
mandatory_fields: klass.mandatory_fields,
optional_fields: klass.optional_fields,
external_fields: klass.external_fields
}, status: :ok
rescue StandardError => e
render json: { error: e.message }, status: :unprocessable_entity
end

def export
# Parse ordered fields from JSON, if provided
ordered_fields =
begin
JSON.parse(params[:ordered_fields]) if params[:ordered_fields]
rescue JSON::ParserError
render json: { error: "Invalid JSON for ordered_fields" }, status: :unprocessable_entity
return
end

klass = params[:class].constantize

csv_file = Export.perform(klass, ordered_fields)

render json: {
message: "#{params[:class]} has been exported!",
file: csv_file
}, status: :ok

rescue StandardError => e
render json: { error: e.message }, status: :unprocessable_entity
end

private

def export_params
params.permit(:class, :ordered_fields)
end
end
86 changes: 86 additions & 0 deletions app/controllers/import_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# This controller handles importing CSV data into any supported model.
# It exposes two endpoints:
# • GET /import -> returns field requirements for the selected class
# • POST /import -> processes the uploaded CSV file
#
# The controller delegates actual import logic to:
# klass.try_import_records(...)
#
# Each model that supports importing must implement:
# mandatory_fields
# optional_fields
# external_fields
# try_import_records(file, ordered_fields, use_header:)
#

class ImportController < ApplicationController
# Ensure strong parameters are processed before each action
before_action :import_params

##
# GET /import
#
# Returns metadata about which fields a given class requires or accepts.
# The frontend uses this to build the mapping UI (drag/drop field matching).
#
def index
imported_class = params[:class].constantize

render json: {
mandatory_fields: imported_class.mandatory_fields,
optional_fields: imported_class.optional_fields,
external_fields: imported_class.external_fields,

# Import does not provide duplicate-resolution strategies (those apply to export)
available_actions_on_dup: imported_class.available_actions_on_duplicate.map{|klass| klass.class.name},
}, status: :ok
end

##
# POST /import
#
# This action performs the actual import process. It:
# 1. Reads the uploaded CSV file
# 2. Determines whether the CSV includes headers
# 3. Applies user-chosen field ordering (if provided)
# 4. Hands off import logic to the model via `try_import_records`
#
def import
uploaded_file = params[:csv_file]

# Convert use_headers ("true"/"false") into actual boolean
use_headers = ActiveRecord::Type::Boolean.new.deserialize(params[:use_headers])

# If the user provided a custom field ordering, load it from JSON
ordered_fields = JSON.parse(params[:ordered_fields]) if params[:ordered_fields]

# Dynamically load the model class (e.g., "User", "Team", etc.)
klass = params[:class].constantize

# Load the chosen duplicate action (Skip, Update, Change)
dup_action = params[:dup_action].constantize

pp dup_action

importService = Import.new(klass: klass, file: uploaded_file, headers: ordered_fields, dup_action: dup_action.new)
result = importService.perform(use_headers)

# If no exceptions occur, return success
render json: { message: "#{klass.name} has been imported!", **result }, status: :created

rescue StandardError => e
# Catch any unexpected runtime errors
puts "An unexpected error occurred during import: #{e.message}"

render json: { error: e.message }, status: :unprocessable_entity
end

private

##
# Strong parameters for import operations
#
def import_params
params.permit(:csv_file, :use_headers, :class, :ordered_fields, :dup_action)
end
end
Loading
Loading