added 260907 version of worker toolkit
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
module Api
|
||||
module V1
|
||||
class AwsSesController < ApplicationController
|
||||
skip_authorize_resource only: [:mail_it, :notification]
|
||||
skip_before_action :authenticate_user!, only: [:mail_it, :notification]
|
||||
|
||||
def notification
|
||||
message_type = request.headers["x-amz-sns-message-type"]
|
||||
# sns_topic = request.headers['x-amz-sns-topic-arn']
|
||||
raw_post = request.raw_post
|
||||
|
||||
if message_type.include? "Confirmation"
|
||||
send_subscription_confirmation(raw_post)
|
||||
elsif message_type.include? "Notification"
|
||||
EmailRejectDispatcher.perform_async(raw_post)
|
||||
end
|
||||
|
||||
render nothing: true, status: 200
|
||||
end
|
||||
|
||||
def send_subscription_confirmation(raw_post)
|
||||
json = JSON.parse(raw_post)
|
||||
|
||||
open(json["SubscribeURL"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
module Api
|
||||
module V1
|
||||
class ChartListsController < ApplicationController
|
||||
def show
|
||||
render json: ChartListService.new(current_user: current_user).as_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
module Api
|
||||
module V1
|
||||
class ChartsController < ApplicationController
|
||||
def show
|
||||
chart = Chart.new(chart_params)
|
||||
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail(ActiveRecord::RecordInvalid, chart) if chart.invalid?
|
||||
# rubocop:enable Style/SignalException
|
||||
|
||||
render json: chart
|
||||
end
|
||||
|
||||
def chart_params
|
||||
includes_params = {
|
||||
tags: [],
|
||||
foods: [],
|
||||
symptoms: [],
|
||||
conditions: [],
|
||||
treatments: [],
|
||||
weathersMeasures: [],
|
||||
harveyBradshawIndices: []
|
||||
}
|
||||
|
||||
params.permit(:id, :start_at, :end_at, includes: includes_params).tap do |whitelist|
|
||||
whitelist[:user] = current_user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
module Api
|
||||
module V1
|
||||
class ChartsPatternController < ApplicationController
|
||||
skip_before_action :authenticate_user!, only: [:index]
|
||||
|
||||
def index
|
||||
offset = charts_pattern_params[:offset].to_i
|
||||
start_at = (charts_pattern_params[:start_at].to_date - offset.days).to_s
|
||||
|
||||
end_date = charts_pattern_params[:end_at].to_date
|
||||
end_at = ((Time.current.to_date == end_date) ? end_date : (end_date + offset.days)).to_s
|
||||
|
||||
@patterns = Pattern.where(id: {"$in": charts_pattern_params[:pattern_ids] || []})
|
||||
|
||||
@extended_patterns = @patterns.map do |pattern|
|
||||
pattern.extend(PatternExtender).form_chart_data(start_at: start_at,
|
||||
end_at: end_at,
|
||||
pattern: pattern)
|
||||
end
|
||||
|
||||
render json: @extended_patterns, meta: {color_ids: Flaredown::Colorable::IDS}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def charts_pattern_params
|
||||
params.permit(:start_at, :end_at, :offset, pattern_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
module Api
|
||||
module V1
|
||||
class CheckinsController < ApplicationController
|
||||
def index
|
||||
date = params[:date]
|
||||
|
||||
if date.blank? && params.require(:page)
|
||||
render json: current_user.checkins.where(:note.nin => [nil, ""]).order_by(date: :desc).page(params[:page]).per(10)
|
||||
else
|
||||
render json: current_user.checkins.includes([:harvey_bradshaw_index, :promotion_rate, :conditions, :symptoms, :treatments]).select { |x|
|
||||
x.date.to_date == Date.parse(date)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
render json: Checkin.find(id)
|
||||
end
|
||||
|
||||
def create
|
||||
date = params.require(:checkin).require(:date)
|
||||
parsed = DateTime.parse(date)
|
||||
now = DateTime.current
|
||||
save_date = DateTime.new(parsed.year, parsed.month, parsed.day, now.hour, now.minute, now.second)
|
||||
checkin = Checkin::Creator.new(current_user.id, save_date).create!
|
||||
render json: checkin
|
||||
end
|
||||
|
||||
def update
|
||||
render json: Checkin::Updater.new(current_user, params).update!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def id
|
||||
params.require(:id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
module Api
|
||||
module V1
|
||||
class CommentsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:index]
|
||||
|
||||
def index
|
||||
render json: @comments.where(:id.in => params[:ids]).order_by(created_at: :asc)
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @comment
|
||||
end
|
||||
|
||||
def create
|
||||
@comment.encrypted_user_id = current_user.encrypted_id
|
||||
|
||||
if @comment.save
|
||||
UpdatePostCountersJob.perform_async(parent_id: create_params[:post_id], parent_type: "Post")
|
||||
|
||||
unless @comment.encrypted_user_id == @comment.post.encrypted_user_id
|
||||
Notification.create(
|
||||
kind: :comment,
|
||||
notificateable: @comment,
|
||||
encrypted_user_id: @comment.encrypted_user_id,
|
||||
encrypted_notify_user_id: @comment.post.encrypted_user_id
|
||||
)
|
||||
end
|
||||
|
||||
DiscussionMention.perform_async(current_user.encrypted_id, @comment.id.to_s)
|
||||
|
||||
render json: @comment, status: :created
|
||||
else
|
||||
render json: {errors: @comment.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:comment).permit(:body, :post_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
module Api
|
||||
module V1
|
||||
class ConditionsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:show]
|
||||
|
||||
def index
|
||||
@conditions = @conditions.includes(:translations)
|
||||
@conditions = ids.present? ? @conditions.where(id: ids) : @conditions.order(:name).limit(50)
|
||||
|
||||
render json: @conditions
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @condition
|
||||
end
|
||||
|
||||
def create
|
||||
render json: TrackableCreator.new(@condition, current_user).create!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:condition).permit(:name)
|
||||
end
|
||||
|
||||
def ids
|
||||
@ids ||= params[:ids] if params[:ids].is_a?(Array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
module Api
|
||||
module V1
|
||||
class CountriesController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
render json: Country.all, each_serializer: CountrySerializer
|
||||
end
|
||||
|
||||
def show
|
||||
country = Country.find_country_by_alpha2(alpha2)
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail ActiveRecord::RecordNotFound if country.nil?
|
||||
# rubocop:enable Style/SignalException
|
||||
render json: country, serializer: CountrySerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def alpha2
|
||||
id = params.require(:id)
|
||||
match_data = /^[[:alpha:]]{2}$/.match(id)
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail(ActionController::BadRequest, "id param must be a 2 alphabetic characters string") if match_data.nil?
|
||||
# rubocop:enable Style/SignalException
|
||||
match_data[0]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
module Api
|
||||
module V1
|
||||
class DataExportSchedulesController < ApplicationController
|
||||
def create
|
||||
DataExportJob.perform_later(current_user.id)
|
||||
|
||||
head :created
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
module Api
|
||||
module V1
|
||||
class DayHabitsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
render json: DayHabit.all
|
||||
end
|
||||
|
||||
def show
|
||||
day_habit = DayHabit.find(day_habit_id)
|
||||
render json: day_habit
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def day_habit_id
|
||||
id = params.require(:id)
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail(ActionController::BadRequest, "id param is not a valid day_habit id") unless DayHabit.all_ids.include?(id)
|
||||
# rubocop:enable Style/SignalException
|
||||
id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
module Api
|
||||
module V1
|
||||
class DiscoursesController < ApplicationController
|
||||
def create
|
||||
render json: {url: DiscourseClient.new(current_user, params).generate_url}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
module Api
|
||||
module V1
|
||||
class EducationLevelsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
render json: EducationLevel.all
|
||||
end
|
||||
|
||||
def show
|
||||
education_level = EducationLevel.find(education_level_id)
|
||||
render json: education_level
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def education_level_id
|
||||
id = params.require(:id)
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
unless EducationLevel.all_ids.include?(id)
|
||||
fail(ActionController::BadRequest, "id param is not a valid education_level id")
|
||||
end
|
||||
# rubocop:enable Style/SignalException
|
||||
id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
module Api
|
||||
module V1
|
||||
class EthnicitiesController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
render json: Ethnicity.all
|
||||
end
|
||||
|
||||
def show
|
||||
ethnicity = Ethnicity.find(ethnicity_id)
|
||||
render json: ethnicity
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ethnicity_id
|
||||
id = params.require(:id)
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail(ActionController::BadRequest, "id param is not a valid ethnicity id") unless Ethnicity.all_ids.include?(id)
|
||||
# rubocop:enable Style/SignalException
|
||||
id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
module Api
|
||||
module V1
|
||||
class FoodsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
@foods = @foods.includes(:translations)
|
||||
|
||||
foods =
|
||||
if ids.present?
|
||||
@foods.where(id: ids)
|
||||
elsif scope.present?
|
||||
CollectionRetriever.new(Food, scope, current_user).retrieve
|
||||
end
|
||||
|
||||
render json: foods
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @food
|
||||
end
|
||||
|
||||
def create
|
||||
render json: TrackableCreator.new(@food, current_user).create!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
{long_desc: params.require(:food).require(:name)}
|
||||
end
|
||||
|
||||
def ids
|
||||
@ids ||= params[:ids]
|
||||
end
|
||||
|
||||
def scope
|
||||
@scope ||= params[:scope]&.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
module Api
|
||||
module V1
|
||||
class HarveyBradshawIndicesController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
def show
|
||||
render json: @harvey_bradshaw_index
|
||||
end
|
||||
|
||||
def create
|
||||
@harvey_bradshaw_index.save
|
||||
|
||||
render json: @harvey_bradshaw_index
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:harvey_bradshaw_index).permit(
|
||||
:abdominal_mass, :abdominal_pain, :abscess,
|
||||
:anal_fissure, :aphthous_ulcers, :arthralgia,
|
||||
:checkin_id, :erythema_nodosum, :new_fistula,
|
||||
:pyoderma_gangrenosum, :stools, :uveitis, :well_being
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
module Api
|
||||
module V1
|
||||
class InvitationsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
render json: Invitation.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
invitation = Invitation.find(params[:id])
|
||||
invitation.accept!(
|
||||
params.require(:invitation).permit(:email, :password, :password_confirmation)
|
||||
)
|
||||
render json: invitation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
module Api
|
||||
module V1
|
||||
class NotificationsController < ApplicationController
|
||||
def index
|
||||
notifications = Notification.where(encrypted_notify_user_id: current_user.encrypted_id)
|
||||
|
||||
authorize_collection :index, notifications
|
||||
|
||||
render json: {notifications: notifications.aggregated_by_kind_and_subject}
|
||||
end
|
||||
|
||||
def update
|
||||
notifications = Notification.where(notification_params)
|
||||
|
||||
authorize_collection :update, notifications
|
||||
|
||||
if notifications.update_all(unread: false)
|
||||
render json: {notifications: notifications.aggregated_by_kind_and_subject}
|
||||
else
|
||||
render json: {errors: notifications.map(&:errors).compact}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
notifications = Notification.where(notification_params)
|
||||
|
||||
authorize_collection :destroy, notifications
|
||||
|
||||
if notifications.destroy
|
||||
head :no_content
|
||||
else
|
||||
render json: {errors: notifications.map(&:errors).compact}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def notification_params
|
||||
parameters = params.permit(:notificateable_id, :notificateable_type)
|
||||
|
||||
parameters[:notificateable_type] = parameters[:notificateable_type].titleize
|
||||
parameters[:encrypted_notify_user_id] = current_user.encrypted_id
|
||||
|
||||
parameters
|
||||
end
|
||||
|
||||
def authorize_collection(name, collection)
|
||||
collection.each { |element| authorize! name, element }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
module Api
|
||||
module V1
|
||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
Devise.omniauth_providers.each do |provider|
|
||||
define_method provider do
|
||||
handle_omniauth
|
||||
end
|
||||
end
|
||||
|
||||
def failure
|
||||
Rails.logger.warn("Api::V1::OmniauthCallbacksController#failure: #{failure_message}".yellow)
|
||||
render json: {errors: failure_message}, status: 401
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_omniauth
|
||||
user = User.find_for_database_authentication(email: email_param)
|
||||
if user && user.invitation_token.nil?
|
||||
render json: user, root: false, serializer: SessionSerializer
|
||||
else
|
||||
render json: {errors: "User not found"}, status: 401
|
||||
end
|
||||
end
|
||||
|
||||
def oauth_params
|
||||
@oauth_params ||= ActionController::Parameters.new(request.env["omniauth.auth"])
|
||||
end
|
||||
|
||||
def email_param
|
||||
oauth_params.fetch(:info).fetch(:email)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
module Api
|
||||
module V1
|
||||
class OracleRequestsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
serialization_scope :oracle_token
|
||||
|
||||
load_resource
|
||||
|
||||
def show
|
||||
render json: @oracle_request
|
||||
end
|
||||
|
||||
def create
|
||||
if oracle_token.present?
|
||||
@oracle_request.token = oracle_token
|
||||
else
|
||||
loop do
|
||||
@oracle_request.token = SecureRandom.uuid
|
||||
|
||||
break unless OracleRequest.where(token: @oracle_request.token).exists?
|
||||
end
|
||||
end
|
||||
|
||||
@oracle_request.save
|
||||
|
||||
render json: @oracle_request, serializer: OracleRequestWithTokenSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
if @oracle_request.can_edit?(oracle_token)
|
||||
@oracle_request.update!(create_params)
|
||||
|
||||
render json: @oracle_request
|
||||
else
|
||||
render json: {errors: "Unauthorized"}, status: :unauthorised
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:oracle_request).permit(
|
||||
:age,
|
||||
:sex_id,
|
||||
responce: [
|
||||
:name,
|
||||
:confidence,
|
||||
:correction
|
||||
],
|
||||
symptom_ids: []
|
||||
)
|
||||
end
|
||||
|
||||
def oracle_token
|
||||
request.headers["X-Oracle-Token"]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
module Api
|
||||
module V1
|
||||
class PasswordsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
user = user_signed_in? ? current_user : User.with_reset_password_token(params[:id])
|
||||
|
||||
if user.blank?
|
||||
raise ActiveRecord::RecordNotFound, "User not found"
|
||||
else
|
||||
render json: user, token: params[:id], serializer: PasswordSerializer
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
user = User.find_by!(email: email_param.downcase)
|
||||
|
||||
return unless user.send_reset_password_instructions
|
||||
|
||||
render json: user, serializer: PasswordSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
if user_signed_in?
|
||||
if current_user.update_with_password(update_password_params)
|
||||
render json: current_user, token: params[:id], serializer: PasswordSerializer
|
||||
else
|
||||
render json: {errors: current_user.errors}, status: :unprocessable_entity
|
||||
end
|
||||
else
|
||||
user = User.reset_password_by_token(update_password_by_token_params)
|
||||
if user.errors.empty?
|
||||
render json: user, token: params[:id], serializer: PasswordSerializer
|
||||
else
|
||||
render json: {errors: user.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def email_param
|
||||
params.require(:password).fetch(:email)
|
||||
end
|
||||
|
||||
def update_password_params
|
||||
params.require(:password).permit(:current_password, :password, :password_confirmation)
|
||||
end
|
||||
|
||||
def update_password_by_token_params
|
||||
params.require(:password).permit(:reset_password_token, :password, :password_confirmation)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
module Api
|
||||
module V1
|
||||
class PatternsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:index]
|
||||
|
||||
def index
|
||||
page = params[:page] || 1
|
||||
pattern_ids = params[:pattern_ids]
|
||||
|
||||
@patterns =
|
||||
if pattern_ids.present?
|
||||
Pattern.where(id: {"$in" => pattern_ids})
|
||||
else
|
||||
Pattern.accessible_by(current_ability).where(encrypted_user_id: encrypted_user_id)
|
||||
end
|
||||
|
||||
render json: @patterns.page(page).per(10)
|
||||
end
|
||||
|
||||
def show
|
||||
pattern = Pattern.find_by(id: pattern_params[:id])
|
||||
|
||||
render json: pattern
|
||||
end
|
||||
|
||||
def create
|
||||
@pattern = PatternCreator.new(pattern_params.to_h).create
|
||||
|
||||
render json: @pattern
|
||||
end
|
||||
|
||||
def update
|
||||
@pattern.update(pattern_params)
|
||||
|
||||
render json: @pattern
|
||||
end
|
||||
|
||||
def destroy
|
||||
pattern = Pattern.find_by(id: params[:id])
|
||||
|
||||
authorize! :destroy, pattern
|
||||
|
||||
if pattern.destroy
|
||||
head :no_content
|
||||
else
|
||||
render json: {errors: pattern.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pattern_params
|
||||
params.require(:pattern)
|
||||
.permit(:name, :start_at, :end_at, includes: [:id, :category, :label])
|
||||
.merge(user_id: current_user.id)
|
||||
end
|
||||
|
||||
def current_ability
|
||||
@current_ability ||= Ability.new(current_user)
|
||||
end
|
||||
|
||||
def encrypted_user_id
|
||||
@encrypted_user_id ||= SymmetricEncryption.encrypt(current_user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
module Api
|
||||
module V1
|
||||
class PostablesController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
render json: PostableSerializer.new(
|
||||
@postables
|
||||
.where(encrypted_user_id: current_user.encrypted_id)
|
||||
.order_by(created_at: :desc)
|
||||
.page(params[:page])
|
||||
.per(20),
|
||||
current_user
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
module Api
|
||||
module V1
|
||||
class PostsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:index, :show]
|
||||
|
||||
def index
|
||||
if params[:summary]
|
||||
render json: SummaryPosts.new(current_user).show_list
|
||||
else
|
||||
@posts = DiscussionPosts.new(params, current_user).show_list
|
||||
|
||||
results = @posts
|
||||
.includes([:comments, :notifications, :reactions])
|
||||
.order(last_commented: :desc, created_at: :desc)
|
||||
.page(params[:page])
|
||||
.per(10)
|
||||
render json: results
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @post
|
||||
end
|
||||
|
||||
def create
|
||||
@post.encrypted_user_id = current_user.encrypted_id
|
||||
|
||||
if @post.save
|
||||
render json: @post, status: :created
|
||||
else
|
||||
render json: {errors: @post.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:post).permit(
|
||||
:title, :body,
|
||||
tag_ids: [], symptom_ids: [], condition_ids: [], treatment_ids: []
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,75 @@
|
||||
module Api
|
||||
module V1
|
||||
class ProfilesController < ApplicationController
|
||||
require "sidekiq/api"
|
||||
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:index]
|
||||
|
||||
def index
|
||||
post = Post.find(params[:post_id])
|
||||
|
||||
encrypted_user_ids =
|
||||
(post.comments.distinct(:encrypted_user_id) << post.encrypted_user_id).uniq.map do |encrypted_id|
|
||||
SymmetricEncryption.decrypt(encrypted_id)
|
||||
end
|
||||
|
||||
@profiles = Profile.where(user_id: encrypted_user_ids).where.not(slug_name: nil)
|
||||
render json: @profiles.map { |profile| profile.attributes.slice("screen_name", "slug_name") }
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @profile
|
||||
end
|
||||
|
||||
def update
|
||||
initial_onboarding_reminder = params.dig(:profile, :onboarding_reminder)
|
||||
|
||||
@profile.assign_attributes(update_params.merge(transform_hash_time))
|
||||
time_changed = @profile.checkin_reminder_at_changed? || @profile.time_zone_name_changed?
|
||||
@profile.save!
|
||||
|
||||
if time_changed || initial_onboarding_reminder
|
||||
delete_old_job(@profile.reminder_job_id)
|
||||
|
||||
job_id = CheckinReminderJob.perform_in(get_reminder_time.minutes, @profile.id, @profile.checkin_reminder_at)
|
||||
@profile.update_column(:reminder_job_id, job_id)
|
||||
end
|
||||
|
||||
current_user.profile.reload
|
||||
set_locale
|
||||
render json: @profile
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_params
|
||||
params.require(:profile).permit(
|
||||
:country_id, :sex_id, :onboarding_step_id, :birth_date,
|
||||
:day_habit_id, :education_level_id, :day_walking_hours,
|
||||
:pressure_units, :temperature_units, :screen_name, :notify,
|
||||
:checkin_reminder, :time_zone_name, :notify_top_posts, ethnicity_ids: []
|
||||
)
|
||||
end
|
||||
|
||||
def transform_hash_time
|
||||
checkin_reminder_at = params.require(:profile)[:checkin_reminder_at]
|
||||
user_time = checkin_reminder_at && checkin_reminder_at.values.join(":")
|
||||
|
||||
{checkin_reminder_at: user_time.try(:to_time, :utc)}
|
||||
end
|
||||
|
||||
def get_reminder_time
|
||||
time_zone_name = @profile.time_zone_name
|
||||
checkin_at_timezone = @profile.checkin_reminder_at.strftime("%H:%M").in_time_zone(time_zone_name)
|
||||
|
||||
# Select minutes
|
||||
(checkin_at_timezone - Time.current.in_time_zone(time_zone_name)).divmod(1.day)[1].divmod(1.minute)[0]
|
||||
end
|
||||
|
||||
def delete_old_job(enqueued_job_id)
|
||||
Sidekiq::ScheduledSet.new.find_job(enqueued_job_id)&.delete
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
module Api
|
||||
module V1
|
||||
class PromotionRatesController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
def show
|
||||
render json: @promotion_rate
|
||||
end
|
||||
|
||||
def create
|
||||
@promotion_rate.save
|
||||
|
||||
render json: @promotion_rate
|
||||
end
|
||||
|
||||
def update
|
||||
@promotion_rate.update(resource_params.merge(additional_params))
|
||||
|
||||
render json: @promotion_rate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:promotion_rate).permit(:checkin_id, :score, :feedback)
|
||||
end
|
||||
|
||||
def additional_params
|
||||
user = @promotion_rate.checkin.user
|
||||
|
||||
{user_created_at: user.created_at}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
module Api
|
||||
module V1
|
||||
class PushersController < ApplicationController
|
||||
def create
|
||||
render json: Flaredown.pusher.authenticate!(current_user, socket_id)
|
||||
rescue
|
||||
render json: {errors: "Bad authentication"}, status: "403"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def socket_id
|
||||
params.require(:socket_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
module Api
|
||||
module V1
|
||||
class ReactionsController < ApplicationController
|
||||
def create
|
||||
react(__method__)
|
||||
end
|
||||
|
||||
def update
|
||||
react(__method__)
|
||||
end
|
||||
|
||||
def destroy
|
||||
reaction = Reaction.where(reaction_params).first
|
||||
|
||||
authorize! :destroy, reaction
|
||||
|
||||
if reaction.destroy
|
||||
UpdatePostCountersJob.perform_async(parent_id: reaction_params[:reactable_id],
|
||||
parent_type: reaction_params[:reactable_type])
|
||||
|
||||
head :no_content
|
||||
else
|
||||
render json: {errors: reaction.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def react(method_name)
|
||||
reaction = Reaction.find_or_initialize_by(reaction_params)
|
||||
|
||||
authorize! method_name, reaction
|
||||
|
||||
if reaction.save
|
||||
UpdatePostCountersJob.perform_async(parent_id: reaction_params[:reactable_id],
|
||||
parent_type: reaction_params[:reactable_type])
|
||||
|
||||
unless reaction.encrypted_user_id == reaction.reactable.encrypted_user_id
|
||||
Notification.create(
|
||||
kind: :reaction,
|
||||
notificateable: reaction.reactable,
|
||||
encrypted_user_id: reaction.encrypted_user_id,
|
||||
encrypted_notify_user_id: reaction.reactable.encrypted_user_id
|
||||
)
|
||||
end
|
||||
|
||||
reaction.id = params[:id] if params[:id].present?
|
||||
|
||||
render json: serialized_reaction(reaction), status: :created
|
||||
else
|
||||
render json: {errors: reaction.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def reaction_params
|
||||
reaction = params.require(:reaction)
|
||||
|
||||
{
|
||||
value: reaction[:value],
|
||||
reactable_id: reaction[:reactable_id],
|
||||
reactable_type: reaction[:reactable_type].titleize,
|
||||
encrypted_user_id: current_user.encrypted_id
|
||||
}
|
||||
end
|
||||
|
||||
def serialized_reaction(reaction)
|
||||
ReactionSerializer
|
||||
.new(
|
||||
Reaction.similar_to(reaction).values_count_with_participated(current_user.encrypted_id),
|
||||
reaction.reactable_id.to_s,
|
||||
reaction.reactable_type
|
||||
)
|
||||
.serialize_one
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
module Api
|
||||
module V1
|
||||
class RegistrationsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
render json: Registration.create!(params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
render json: Registration.delete!(params)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
module Api
|
||||
module V1
|
||||
class SearchesController < ApplicationController
|
||||
SEARCH_MAPPER = {
|
||||
"dose" => Search::ForDose,
|
||||
"food" => Search::ForFood,
|
||||
"topic" => Search::ForTopic
|
||||
}.freeze
|
||||
|
||||
skip_before_action :authenticate_user!, only: :show
|
||||
|
||||
def show
|
||||
search = (SEARCH_MAPPER[resource_param] || Search).new(search_params)
|
||||
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail(ActiveRecord::RecordInvalid, search) if search.invalid?
|
||||
# rubocop:enable Style/SignalException
|
||||
|
||||
render json: search, serializer: SearchSerializer
|
||||
end
|
||||
|
||||
def search_params
|
||||
params.permit(:resource, :scope, query: [:name, :treatment_id]).tap do |params|
|
||||
params[:user] = current_user
|
||||
end
|
||||
end
|
||||
|
||||
def resource_param
|
||||
params[:resource]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
module Api
|
||||
module V1
|
||||
class SessionsController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail "missing information" if params[:user].nil?
|
||||
fail "invalid email or password" if user.nil?
|
||||
# rubocop:enable Style/SignalException
|
||||
|
||||
render json: user, root: false, serializer: SessionSerializer
|
||||
rescue => e
|
||||
render json: {errors: Array(e.message)}, status: 401
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user
|
||||
@user ||=
|
||||
begin
|
||||
user = User.find_for_database_authentication(email: params[:user][:email])
|
||||
user if user && user.valid_password?(params[:user][:password])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
module Api
|
||||
module V1
|
||||
class SexesController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
render json: Sex.all
|
||||
end
|
||||
|
||||
def show
|
||||
sex = Sex.find(sex_id)
|
||||
render json: sex
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sex_id
|
||||
id = params.require(:id)
|
||||
# FIXME
|
||||
# rubocop:disable Style/SignalException
|
||||
fail(ActionController::BadRequest, "id param is not a valid sex id") unless Sex.all_ids.include?(id)
|
||||
# rubocop:enable Style/SignalException
|
||||
id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
module Api
|
||||
module V1
|
||||
class SymptomsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:show]
|
||||
|
||||
def index
|
||||
@symptoms = @symptoms.includes(:translations)
|
||||
@symptoms = ids.present? ? @symptoms.where(id: ids) : @symptoms.order(:name).limit(50)
|
||||
|
||||
render json: @symptoms
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @symptom
|
||||
end
|
||||
|
||||
def create
|
||||
render json: TrackableCreator.new(@symptom, current_user).create!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:symptom).permit(:name)
|
||||
end
|
||||
|
||||
def ids
|
||||
@ids ||= params[:ids] if params[:ids].is_a?(Array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
module Api
|
||||
module V1
|
||||
class TagsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:show]
|
||||
|
||||
def index
|
||||
@tags = @tags.includes(:translations)
|
||||
if ids.present?
|
||||
@tags = @tags.where(id: ids)
|
||||
elsif scope.present?
|
||||
@tags = CollectionRetriever.new(Tag, scope, current_user).retrieve
|
||||
end
|
||||
render json: @tags
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @tag
|
||||
end
|
||||
|
||||
def create
|
||||
render json: TrackableCreator.new(@tag, current_user).create!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:tag).permit(:name)
|
||||
end
|
||||
|
||||
def ids
|
||||
@ids ||= params[:ids]
|
||||
end
|
||||
|
||||
def scope
|
||||
@scope ||= params[:scope].try(:to_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
module Api
|
||||
module V1
|
||||
class TopicFollowingsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
def show
|
||||
render json: @topic_following
|
||||
end
|
||||
|
||||
def update
|
||||
if @topic_following.update(update_params)
|
||||
render json: @topic_following, status: :ok
|
||||
else
|
||||
render json: {errors: @topic_following.errors}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_params
|
||||
empty_params = {
|
||||
"tag_ids" => [],
|
||||
"symptom_ids" => [],
|
||||
"condition_ids" => [],
|
||||
"treatment_ids" => []
|
||||
}
|
||||
|
||||
empty_params.merge(params.require(:topic_following).permit(empty_params))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
module Api
|
||||
module V1
|
||||
class TrackingsController < ApplicationController
|
||||
load_and_authorize_resource except: :create
|
||||
|
||||
def index
|
||||
render json: @trackings.by_trackable_type(trackable_type).active_at(at)
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @tracking
|
||||
end
|
||||
|
||||
def create
|
||||
tracking = Tracking.new(create_params.merge(start_at: Time.zone.today, user: current_user))
|
||||
|
||||
authorize! :create, tracking
|
||||
|
||||
tracking.save!
|
||||
|
||||
current_user.topic_following.add_topic("#{tracking.trackable_type.downcase}_ids", tracking.trackable_id)
|
||||
|
||||
render json: tracking
|
||||
end
|
||||
|
||||
def destroy
|
||||
TrackingDestroyer.new(current_user, @tracking, Time.zone.today).destroy
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def at
|
||||
Time.zone.parse(params.require(:at))
|
||||
end
|
||||
|
||||
def trackable_type
|
||||
params.require(:trackable_type)
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:tracking).permit(:trackable_id, :trackable_type, :color_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
module Api
|
||||
module V1
|
||||
class TreatmentsController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
skip_before_action :authenticate_user!, only: [:show]
|
||||
|
||||
def index
|
||||
@treatments = @treatments.includes(:translations)
|
||||
@treatments = ids.present? ? @treatments.where(id: ids) : @treatments.order(:name).limit(50)
|
||||
|
||||
render json: @treatments
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @treatment
|
||||
end
|
||||
|
||||
def create
|
||||
render json: TrackableCreator.new(@treatment, current_user).create!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_params
|
||||
params.require(:treatment).permit(:name)
|
||||
end
|
||||
|
||||
def ids
|
||||
@ids ||= params[:ids] if params[:ids].is_a?(Array)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
module Api
|
||||
module V1
|
||||
class UnsubscribesController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
def update
|
||||
@profile = Profile.find_by(notify_token: activation_params[:notify_token])
|
||||
@profile&.update_column(attribute_dispatcher_key, false)
|
||||
|
||||
render json: @profile
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def activation_params
|
||||
params.permit(:notify_token, :notify_top_posts, :stop_remind)
|
||||
end
|
||||
|
||||
def attribute_dispatcher_key
|
||||
if activation_params[:stop_remind]
|
||||
:checkin_reminder
|
||||
elsif activation_params[:notify_top_posts]
|
||||
:notify_top_posts
|
||||
else
|
||||
:notify
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
module Api
|
||||
module V1
|
||||
class UsersController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
|
||||
def show
|
||||
render json: @user
|
||||
end
|
||||
|
||||
def update
|
||||
@user.update!(user_params)
|
||||
|
||||
render json: @user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:email)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
module Api
|
||||
module V1
|
||||
class WeathersController < ApplicationController
|
||||
def index
|
||||
unless params[:postal_code].blank?
|
||||
weather = WeatherRetriever.get(Date.parse(params.require(:date)), params.require(:postal_code))
|
||||
end
|
||||
|
||||
authorize! :read, weather
|
||||
|
||||
if weather.present?
|
||||
render json: weather
|
||||
else
|
||||
render json: {weathers: []}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
class ApplicationController < ActionController::API
|
||||
include CanCan::ControllerAdditions
|
||||
include ActionController::Serialization
|
||||
include ExceptionLogger
|
||||
|
||||
before_action :authenticate_user_from_token!, if: :presence_of_authentication_token?
|
||||
before_action :authenticate_user!, except: [:root]
|
||||
before_action :set_locale
|
||||
|
||||
def root
|
||||
render json: {
|
||||
ios: {
|
||||
major: 0,
|
||||
minor: 0
|
||||
},
|
||||
android: {
|
||||
major: 0,
|
||||
minor: 0
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_locale
|
||||
I18n.locale = user_signed_in? ? current_user.locale : I18n.default_locale
|
||||
rescue I18n::InvalidLocale
|
||||
# FIXME
|
||||
Rails.logger.warn("'#{current_user.profile.locale}' locale for user '#{current_user.email}' not available or invalid, using default")
|
||||
I18n.locale = I18n.default_locale
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticate_user_from_token!
|
||||
user = User.find_by(authorization)
|
||||
sign_in user, store: false if user
|
||||
end
|
||||
|
||||
def authorization
|
||||
@authorization ||=
|
||||
/^Token token="(?<token>.*)", email="(?<email>.*)"$/.match(request.headers["Authorization"]) || {}
|
||||
|
||||
{authentication_token: @authorization[:token], email: @authorization[:email]}
|
||||
end
|
||||
|
||||
def presence_of_authentication_token?
|
||||
authorization[:authentication_token].present?
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
module ExceptionLogger
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
# keep this on top
|
||||
if Rails.env.production?
|
||||
rescue_from "Exception" do |exception|
|
||||
render json: {errors: exception.message}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
rescue_from "ActiveRecord::RecordNotFound", "Mongoid::Errors::DocumentNotFound" do
|
||||
render json: {errors: ["Resource Not Found"]}, status: 404
|
||||
end
|
||||
|
||||
rescue_from "ActionController::UnknownFormat" do
|
||||
render json: {errors: ["Format not supported"]}, status: 406
|
||||
end
|
||||
|
||||
rescue_from "ActiveRecord::RecordInvalid", "Mongoid::Errors::Validations" do |exception|
|
||||
log_exception(exception)
|
||||
render json: {errors: exception.record.errors}, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
rescue_from "ActionController::ParameterMissing" do |exception|
|
||||
render json: {errors: ["Required parameter missing: #{exception.param}"]}, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
rescue_from "ActionController::BadRequest" do |exception|
|
||||
render json: {errors: ["Bad request: #{exception.message}"]}, status: :bad_request
|
||||
end
|
||||
|
||||
rescue_from "CanCan::AccessDenied" do |exception|
|
||||
log_exception(exception)
|
||||
render json: {errors: ["Unauthorized"]}, status: :unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# --- FOR RAILS 4: ---
|
||||
## @exception = env["action_dispatch.exception"]
|
||||
## exception_wrapper = ActionDispatch::ExceptionWrapper.new(env, @exception)
|
||||
|
||||
# --- FOR RAILS 5: ---
|
||||
|
||||
def log_exception(exception)
|
||||
application_trace = ActionDispatch::ExceptionWrapper.new(request.env["action_dispatch.backtrace_cleaner"], exception)
|
||||
|
||||
trace = application_trace.application_trace
|
||||
|
||||
trace = trace.map! { |t| " #{t}\n" }
|
||||
|
||||
Rails.logger.error "\n#{exception.class.name} (#{exception.message}):\n#{trace.join}"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user