Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ group :development do
gem 'bullet'

gem 'dotenv-rails'

end

gem 'rack-cors'
Expand Down
21 changes: 7 additions & 14 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,10 @@ GEM
net-smtp (0.5.0)
net-protocol
nio4r (2.7.3)
nokogiri (1.16.7-arm64-darwin)
racc (~> 1.4)
nokogiri (1.16.7-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.16.7-x86_64-linux)
nokogiri (1.16.7-x64-mingw-ucrt)
racc (~> 1.4)
orm_adapter (0.5.0)
pg (1.5.8)
pg (1.5.8-x64-mingw-ucrt)
psych (5.1.2)
stringio
puma (6.4.3)
Expand Down Expand Up @@ -259,9 +255,7 @@ GEM
skinny (0.2.2)
eventmachine (~> 1.0)
thin
sqlite3 (2.1.0-arm64-darwin)
sqlite3 (2.1.0-x86_64-darwin)
sqlite3 (2.1.0-x86_64-linux-gnu)
sqlite3 (2.1.0-x64-mingw-ucrt)
sqlite3-ruby (1.3.3)
sqlite3 (>= 1.3.3)
stringio (3.1.1)
Expand All @@ -275,6 +269,8 @@ GEM
timeout (0.4.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2024.2)
tzinfo (>= 1.0.0)
uniform_notifier (1.16.0)
warden (1.2.9)
rack (>= 2.0.9)
Expand All @@ -295,10 +291,7 @@ GEM
zeitwerk (2.7.1)

PLATFORMS
arm64-darwin-22
x86_64-darwin-19
x86_64-darwin-21
x86_64-linux
x64-mingw-ucrt

DEPENDENCIES
bootsnap
Expand All @@ -322,7 +315,7 @@ DEPENDENCIES
web-console

RUBY VERSION
ruby 3.3.2p78
ruby 3.3.2p79

BUNDLED WITH
2.5.11
178 changes: 178 additions & 0 deletions app/controllers/api/v1/patient_profiles_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# frozen_string_literal: true
module Api
module V1
class PatientProfilesController < ApplicationController
before_action :sanitize_request_path
skip_before_action :authenticate_user!, only: [:index]

# POST /patient_profiles
def create
ActiveRecord::Base.transaction do
address_params = params.require(:address).permit(:address_line_1, :address_line_2, :city, :state, :country, :pincode)
address = Address.create!(address_params)

establishment_defaults = {
name: "Default Hospital",
latitude: 0.0,
longitude: 0.0,
maps_location: "https://maps.example.com/default_location"
}

establishment_params = params.fetch(:establishment, {}).permit(:name, :latitude, :longitude, :maps_location).to_h
establishment = Establishment.create!(
establishment_defaults.merge(establishment_params).merge(address: address)
)

patient_params = params.require(:patient_profile).permit(:name, :gender, :dob, :blood_group)
patient_profile = PatientProfile.create!(
patient_params.merge(address: address, establishment: establishment, user_id: current_user.id)
)

current_user.update!(patient_profile_id: patient_profile.id)

render json: {
code: 201,
message: 'Patient profile created successfully.',
patient_profile: patient_profile,
}, status: :created
end
rescue ActiveRecord::RecordInvalid => e
render json: { error: e.message }, status: :unprocessable_entity
rescue StandardError => e
render json: { error: "An unexpected error occurred: #{e.message}" }, status: :internal_server_error
end

# GET /all patient_profiles
def index

patient_profiles = PatientProfile.includes(:address, :user)

patient_profiles = patient_profiles.where("name ILIKE ?", "%#{params[:name]}%") if params[:name].present?
patient_profiles = patient_profiles.joins(:address).where("addresses.city ILIKE ?", "%#{params[:city]}%") if params[:city].present?
patient_profiles = patient_profiles.joins(:address).where("addresses.state ILIKE ?", "%#{params[:state]}%") if params[:state].present?
patient_profiles = patient_profiles.joins(:address).where("addresses.country ILIKE ?", "%#{params[:country]}%") if params[:country].present?
patient_profiles = patient_profiles.joins(:address).where("addresses.pincode = ?", params[:pincode]) if params[:pincode].present?
patient_profiles = patient_profiles.joins(:user).where(users: { patient_profile_id: params[:patient_profile_id] }) if params[:patient_profile_id].present?

if patient_profiles.empty?
render json: {
code: 404,
message: 'No patient profiles found for the given filters.'
}, status: :not_found
else

render json: {
code: 200,
message: 'Patient profiles retrieved successfully.',
data: patient_profiles.as_json(
include: {
address: {},
user: { only: [:id, :email, :patient_profile_id] }
}
)
}, status: :ok
end
end


# GET /patient_profiles/:user_id

def show

user = current_user

patient_profile = PatientProfile.includes(:address, :user).find_by(id: params[:id], user_id: user.id)

if patient_profile
render json: {
code: 200,
message: 'Patient profile retrieved successfully.',
data: patient_profile.as_json(include: {
address: { only: [:id, :address_line_1, :city, :state, :country, :pincode] },
user: { only: [:id, :email, :patient_profile_id] }
})
}, status: :ok
else
render json: {
code: 404,
message: 'Patient profile not found or you are not authorized to view it.'
}, status: :not_found
end
end

# DELETE /patient_profiles/:user_id
def destroy

user = current_user

patient_profile = PatientProfile.find_by(id: params[:id], user_id: user.id)

if patient_profile

patient_profile.destroy

render json: {
code: 200,
message: 'Patient profile deleted successfully.'
}, status: :ok
else

render json: {
code: 404,
message: 'Patient profile not found or you are not authorized to delete it.'
}, status: :not_found
end
end

# PATCH/PUT /patient_profiles/:id
def update

user = current_user

patient_profile = PatientProfile.find_by(id: params[:id], user_id: user.id)

if patient_profile.nil?
render json: {
code: 404,
message: 'Patient profile not found or you are not authorized to update it.'
}, status: :not_found
return
end

if patient_profile.update(patient_profile_params) && patient_profile.address.update(address_params)
render json: {
code: 200,
message: 'Patient profile updated successfully.',
data: patient_profile.as_json(include: :address)
}, status: :ok
else
render json: {
code: 422,
message: 'Failed to update patient profile.',
errors: patient_profile.errors.full_messages + patient_profile.address.errors.full_messages
}, status: :unprocessable_entity
end
end

private

def address_params
params.require(:address).permit(
:address_line_1,
:address_line_2,
:city,
:state,
:country,
:pincode
)
end
def sanitize_request_path
request.path.gsub!(/\s+/, '')
end
def patient_profile_params
params.require(:patient_profile).permit(:name, :gender, :dob, :blood_group)
end

end
end
end
23 changes: 18 additions & 5 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
# frozen_string_literal: true

class ApplicationController < ActionController::API

include Devise::Controllers::Helpers

before_action :authenticate_user!

before_action :configure_permitted_parameters, if: :devise_controller?

rescue_from Devise::MissingWarden do
render json: { error: 'User not authenticated' }, status: :unauthorized
end

protected

def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) do |user_params|
user_params.permit(:email, :password, :password_confirmation, :user_type)
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) do |user_params|
user_params.permit(:email, :password, :password_confirmation, :user_type)
end
def authenticate_user!
super
rescue Devise::MissingWarden
render json: { error: 'User not authenticated' }, status: :unauthorized
end

end

end
34 changes: 20 additions & 14 deletions app/controllers/users/registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,43 @@
# frozen_string_literal: true

class Users::RegistrationsController < Devise::RegistrationsController
include RackSessionFix
respond_to :json

def create
user = User.new(
email: params[:user][:email],
password: params[:user][:password],
password_confirmation: params[:user][:password_confirmation]
)
user_type = params[:user][:user_type]
user.create_empty_profile!(user_type)
user.save
respond_with user
@user = User.new(user_params)

if @user.save
respond_with(@user)
else
render_error(@user.errors.full_messages.to_sentence)
end
end

private

def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :user_type)
end

def render_error(message, status = :unprocessable_entity)
render json: { message: "User could not be created successfully. #{message}" }, status: status
end

def respond_with(resource, _opts = {})
if request.method == 'POST' && resource.persisted?
render json: {
code: 200,
code: 201,
message: 'Signed up successfully.',
data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
}, status: :ok
}, status: :created
elsif request.method == 'DELETE'
render json: {
code: 200,
message: 'Account deleted successfully.'
}, status: :ok
else
render json: {
message: "User could not be created successfully. #{resource.errors.full_messages.to_sentence}"
}, status: :unprocessable_entity
render_error(resource.errors.full_messages.to_sentence)
end
end
end
4 changes: 3 additions & 1 deletion app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ class Users::SessionsController < Devise::SessionsController
private

def respond_with(resource, _opts = {})
token = Warden::JWTAuth::UserEncoder.new.call(resource, :user, nil)[0]
render json: {
code: 200,
message: 'Logged in successfully.',
data: UserSerializer.new(resource).serializable_hash[:data][:attributes]
data: UserSerializer.new(resource).serializable_hash[:data][:attributes],
token: token
}, status: :ok
end

Expand Down
5 changes: 5 additions & 0 deletions app/models/address.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
class Address < ApplicationRecord
has_many :patient_profiles, dependent: :destroy

# Validations
validates :address_line_1, :city, :state, :country, :pincode, presence: true
validates :pincode, numericality: { only_integer: true }
end
2 changes: 2 additions & 0 deletions app/models/establishment.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
class Establishment < ApplicationRecord
belongs_to :address
has_many :patient_profiles, dependent: :destroy
end
20 changes: 19 additions & 1 deletion app/models/patient_profile.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
class PatientProfile < ApplicationRecord
belongs_to :address, optional: true
has_one :user
belongs_to :establishment, optional: true
belongs_to :user, optional: true


# Validations for PatientProfile fields
validates :name, presence: true, length: { minimum: 1, message: "cannot be blank" }
validates :gender, inclusion: { in: %w[male female other], message: "must be male, female, or other" }, allow_blank: true
validates :blood_group, inclusion: { in: %w[A+ A- B+ B- AB+ AB- O+ O-], message: "is invalid" }, allow_blank: true
validate :dob_in_the_past, if: -> { dob.present? }


# Custom validation for date_of_birth
private

def dob_in_the_past
if dob > Date.today
errors.add(:dob, 'must be in the past')
end
end
end
Loading