Skip to content

Commit 2490205

Browse files
committed
Update/Add controllers for school import and job tracking.
This commit modifies SchoolsController to add the endpoint for importing schools. It introduces SchoolImportJobsController as the controller for the endpoint though which clients can track job status.
1 parent 79fca5b commit 2490205

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# frozen_string_literal: true
2+
3+
module Api
4+
class SchoolImportJobsController < ApiController
5+
before_action :authorize_user
6+
7+
def show
8+
authorize! :read, :school_import_job
9+
job = find_job
10+
11+
if job.nil?
12+
render json: SchoolImportError.format_error(:job_not_found, 'Job not found'), status: :not_found
13+
return
14+
end
15+
16+
render json: build_job_response(job), status: :ok
17+
end
18+
19+
private
20+
21+
def find_job
22+
# GoodJob stores jobs in the good_jobs table as Executions
23+
# The job_id returned to users is the ActiveJob ID
24+
# We need to query by active_job_id, not by execution id
25+
job = GoodJob::Execution.find_by(active_job_id: params[:id])
26+
27+
# Verify this is an import job (security check)
28+
return nil unless job && job.job_class == 'ImportSchoolsJob'
29+
30+
job
31+
end
32+
33+
def build_job_response(job)
34+
response = {
35+
id: job.active_job_id,
36+
status: job_status(job),
37+
created_at: job.created_at,
38+
finished_at: job.finished_at,
39+
job_class: job.job_class
40+
}
41+
42+
# If job is finished successfully, get results from dedicated table
43+
if job.finished_at.present? && job.error.blank?
44+
result = SchoolImportResult.find_by(job_id: job.active_job_id)
45+
if result
46+
response[:results] = result.results
47+
else
48+
response[:message] = 'Job completed successfully'
49+
end
50+
end
51+
52+
# Include error if job failed
53+
if job.error.present?
54+
response[:error] = job.error
55+
response[:status] = 'failed'
56+
end
57+
58+
response
59+
end
60+
61+
def job_status(job)
62+
return 'failed' if job.error.present?
63+
return 'completed' if job.finished_at.present?
64+
return 'scheduled' if job.scheduled_at.present? && job.scheduled_at > Time.current
65+
return 'running' if job.performed_at.present? && job.finished_at.nil?
66+
67+
'queued'
68+
end
69+
end
70+
end

app/controllers/api/schools_controller.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Api
44
class SchoolsController < ApiController
55
before_action :authorize_user
66
load_and_authorize_resource
7+
skip_load_and_authorize_resource only: :import
78

89
def index
910
@schools = School.accessible_by(current_ability)
@@ -47,6 +48,31 @@ def destroy
4748
end
4849
end
4950

51+
def import
52+
authorize! :import, School
53+
54+
if params[:csv_file].blank?
55+
render json: SchoolImportError.format_error(:csv_file_required, 'CSV file is required'),
56+
status: :unprocessable_entity
57+
return
58+
end
59+
60+
result = School::ImportBatch.call(
61+
csv_file: params[:csv_file],
62+
current_user: current_user
63+
)
64+
65+
if result.success?
66+
render json: {
67+
job_id: result[:job_id],
68+
total_schools: result[:total_schools],
69+
message: 'Import job started successfully'
70+
}, status: :accepted
71+
else
72+
render json: result[:error], status: :unprocessable_entity
73+
end
74+
end
75+
5076
private
5177

5278
def school_params

0 commit comments

Comments
 (0)