Files
Dalan/app/api/v2/resource/profiles.rb
2026-08-13 19:56:46 +03:30

256 lines
11 KiB
Ruby

# frozen_string_literal: true
module API::V2
module Resource
# CR functionality over profiles table
class Profiles < Grape::API
helpers do
def profile_param_keys
%w[first_name last_name dob address
postcode city country metadata national_code].freeze
end
def treasury_param_keys
%w[title data kind].freeze
end
end
desc 'Profile related routes'
resource :profiles do
desc 'Return profiles of current resource owner',
failure: [
{ code: 401, message: 'Invalid bearer token' },
{ code: 404, message: 'User has no profile' }
],
success: API::V2::Entities::Profile
get '/me' do
present current_user.profiles, with: API::V2::Entities::Profile
end
# personal info - kyc level one step one
desc 'Create Level one - step one - personal info in profiles',
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 401, message: 'Invalid bearer token' },
{ code: 409, message: 'Profile already exists' },
{ code: 422, message: 'Validation errors' }
],
success: API::V2::Entities::Profile
params do
requires :first_name, type: String, desc: 'First Name'
requires :last_name, type: String, desc: 'Last Name'
requires :dob, type: Date, desc: 'Date of Birth'
requires :national_code, type: String, desc: 'national code'
requires :upload, desc: 'Array of Rack::Multipart::UploadedFile'
optional :confirm, type: Boolean, default: true, desc: 'Profile confirmation'
end
post do
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 1
declared_params = declared(params.slice(*profile_param_keys), include_missing: false)
declared_params.merge!(state: 'submitted')
# declared_params.merge!(state: 'submitted') if params['confirm']
ActiveRecord::Base.transaction do
profile = current_user.profiles.create(declared_params)
code_error!(profile.errors.details, 422) if profile.errors.any?
doc = current_user.documents.new(upload: params[:upload],
identificator: SecureRandom.hex(16),
doc_type: 'Identity card',
doc_category: 'front_side')
code_error!(doc.errors.details, 422) unless doc.save
present profile, with: API::V2::Entities::Profile
end
end
desc 'Update a profile for current_user',
failure: [
{ code: 401, message: 'Invalid bearer token' },
{ code: 401, message: 'Invalid bearer token' },
{ code: 422, message: 'Validation errors' }
],
success: API::V2::Entities::Profile
params do
requires :first_name, type: String, desc: 'First Name'
requires :last_name, type: String, desc: 'Last Name'
requires :dob, type: Date, desc: 'Date of Birth'
requires :national_code, type: String, desc: 'national code'
requires :upload, desc: 'Array of Rack::Multipart::UploadedFile'
optional :confirm, type: Boolean, default: true, desc: 'Profile confirmation'
end
put do
target_profile = current_user.submitted_profile
error!({ errors: ['resource.profile.doesnt_exist_or_not_editable'] }, 404) if target_profile.nil?
declared_params = declared(params.slice(*profile_param_keys), include_missing: false)
# declared_params.merge!(state: 'submitted') if params['confirm']
declared_params.merge!(state: 'submitted')
ActiveRecord::Base.transaction do
code_error!(target_profile.errors.details, 422) unless target_profile.update(declared_params)
document = current_user.front_icard
document.update!(upload: params[:upload]) if document.present?
end
present target_profile, with: API::V2::Entities::Profile
end
# card bank info - kyc level one step three
resource :treasury do
# one request add iban just
desc 'Create Level one - step three - info bank ',
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 401, message: 'Invalid bearer token' },
{ code: 409, message: 'Bank info already exists' },
{ code: 422, message: 'Validation errors' }
],
success: API::V2::Entities::Profile
params do
requires :data, type: String, desc: 'treasury number'
requires :kind, type: String, desc: 'iban or card'
optional :title, type: String, desc: 'treasury name'
optional :confirm, type: Boolean, default: true, desc: 'Treasury confirmation'
end
post do
error!({ errors: ['resource.verified.profile.doesnt_exist'] }, 404) unless current_user.verified_profile.present?
declared_params = declared(params.slice(*treasury_param_keys), include_missing: false)
# declared_params.merge!(state: 'submitted') if params['confirm'].present?
declared_params.merge!(state: 'submitted')
error!({ errors: ['treasury.kind.not_exist'] }, 404) if Treasury.kinds.keys.exclude?(declared_params['kind'])
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 3 && declared_params['kind'].to_s == 'card'
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 4 && declared_params['kind'].to_s == 'iban'
treasury = current_user.treasuries.create(declared_params)
code_error!(treasury.errors.details, 422) if treasury.errors.any?
KYC.const_get(Barong::App.config.kyc_provider.capitalize, false)::TreasuryWorker.perform_async(current_user.verified_profile.id)
present treasury, with: API::V2::Entities::Treasury
end
desc 'Delete a treasury',
success: { code: 204, message: 'Successfully deleted' },
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 401, message: 'Invalid bearer token' },
{ code: 404, message: 'Record is not found' }
]
delete ':id' do
treasury = Treasury.find_by!(id: params[:id], user_id: current_user.id)
treasury.destroy
code_error!(treasury.errors.details, 422) if treasury.errors.any?
status 204
end
desc 'Return list of treasuries',
failure: [
{ code: 401, message: 'Invalid bearer token' },
{ code: 404, message: 'User has no treasuries' }
],
success: API::V2::Entities::Treasury
get '/list' do
present current_user.treasuries, with: API::V2::Entities::Treasury
end
end
resource :selfie do
# submit selfie - kyc level two step three
desc 'Create Level two - step three - selfie',
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 401, message: 'Invalid bearer token' },
{ code: 409, message: 'Selfie already exists' },
{ code: 422, message: 'Validation errors' }
],
success: API::V2::Entities::Profile
params do
requires :upload, desc: 'Array of Rack::Multipart::UploadedFile'
optional :confirm, type: Boolean, default: true, desc: 'Profile confirmation'
end
post do
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 7
target_profile = current_user.verified_profile
error!({ errors: ['resource.verified.profile.doesnt_exist'] }, 404) if target_profile.nil?
label = current_user.labels.find_by(key: 'selfie', value: 'verified')
error!({ errors: ['resource.verified.selfie.already_exist'] }, 404) if label.present?
doc = current_user.documents.find_by(doc_type: 'Selfie', state: 'pending')
if doc.present?
doc.update(upload: params[:upload])
else
doc = current_user.documents.new(upload: params[:upload],
identificator: SecureRandom.hex(16),
doc_type: 'Selfie',
doc_category: 'front_side')
code_error!(doc.errors.details, 422) unless doc.save
end
status 201
end
end
resource :address do
desc 'Adding Address',
failure: [
{ code: 400, message: 'Required params are empty' },
{ code: 401, message: 'Invalid bearer token' },
{ code: 404, message: 'needed data doesnt exist' },
{ code: 422, message: 'Validation errors' }
],
success: API::V2::Entities::Profile
params do
requires :city, type: String, desc: 'city name'
requires :province, type: String, desc: 'province name'
requires :address, type: String, desc: 'address'
requires :postcode, type: String, desc: 'post code'
requires :upload, desc: 'Array of Rack::Multipart::UploadedFile'
end
post do
error!({ errors: ['resource.address.already_exist'] }, 422) if current_user.documents.find_by(doc_type: 'Poa', state: 'verified').present?
error!({ errors: ['kyc_follow_steps'] }, 403) if current_user.kyc_info.dig(:step) < 5
declared_params = declared(params)
profile = current_user.verified_profile
# TODO change city and province to id instead of string
province = Province.find_by(name: declared_params['province'])
error!({ errors: ['resource.profile.province_doesnt_exist'] }, 404) if province.nil?
city = province.cities.find_by(name: declared_params['city'])
error!({ errors: ['resource.profile.province_doesnt_exist'] }, 404) if city.nil?
doc = current_user.documents.find_by(doc_type: 'Poa', state: 'pending')
# declared_params.merge!(state: 'submitted') if params['confirm']
ActiveRecord::Base.transaction do
profile.update(city: city, address: declared_params['address'], postcode: declared_params['postcode'])
code_error!(profile.errors.details, 422) if profile.errors.any?
if doc.present?
doc.update(upload: params[:upload])
else
doc = current_user.documents.new(upload: params[:upload],
identificator: SecureRandom.hex(16),
doc_type: 'Poa',
doc_category: 'front_side')
end
code_error!(doc.errors.details, 422) unless doc.save
present profile, with: API::V2::Entities::Profile
end
end
end
end
end
end
end