Skip to content

Commit

Permalink
Merge branch 'staging' into feat/filter-app-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
aminedhobb committed Oct 8, 2024
2 parents 797c789 + a9915cf commit e846af2
Show file tree
Hide file tree
Showing 75 changed files with 835 additions and 176 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ BREVO_USERNAME=change_me
BREVO_INBOUND_PASSWORD=change_me
## Monitoring
SENTRY_DSN=change_me
SENTRY_ENVIRONMENT=change_me
ENVIRONMENT_NAME=change_me

# ActiveStorage uploads
SCALEWAY_ACCESS_KEY_ID=change_me
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem "byebug", platforms: [:mri, :mingw, :x64_mingw]
gem "rspec-rails"
# Strategies for cleaning databases. Can be used to ensure a clean slate for testing.
gem "database_cleaner"
gem "factory_bot_rails"
gem "rubocop"
gem "rubocop-rails"
Expand Down
9 changes: 8 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ GEM
crass (1.0.6)
css_parser (1.16.0)
addressable
database_cleaner (2.0.2)
database_cleaner-active_record (>= 2, < 3)
database_cleaner-active_record (2.2.0)
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
date (3.3.4)
diff-lcs (1.5.0)
dotenv (2.8.1)
Expand Down Expand Up @@ -577,7 +583,7 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
webrick (1.8.2)
websocket (1.2.10)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
Expand Down Expand Up @@ -610,6 +616,7 @@ DEPENDENCIES
byebug
capybara (>= 2.15)
chartkick
database_cleaner
dotenv-rails
factory_bot_rails
faraday
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Le site est disponible

- En production sur [rdv-insertion.fr/](https://rdv-insertion.fr/).
- En démo sur [www.rdv-insertion-demo.fr](https://www.rdv-insertion-demo.fr).
- En staging sur [staging.rdv-insertion.fr](https://staging.rdv-insertion.fr).

## Installation

Expand Down
2 changes: 1 addition & 1 deletion app/clients/mattermost_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def send_to_private_channel(text)
private

def send_message(url, text)
return unless ENV["SENTRY_ENVIRONMENT"] == "production"
return unless ENV["ENVIRONMENT_NAME"] == "production"

Faraday.post(
url,
Expand Down
8 changes: 8 additions & 0 deletions app/clients/rdv_solidarites_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ def create_user(request_body)
)
end

def get_user(user_id)
Faraday.get(
"#{@url}/api/rdvinsertion/users/#{user_id}",
{},
request_headers
)
end

def create_user_profiles(user_id, organisation_ids)
Faraday.post(
"#{@url}/api/rdvinsertion/user_profiles/create_many",
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def sync_user_with_rdv_solidarites(user)
return if sync.success?

respond_to do |format|
format.turbo_stream { flash.now[:error] = "L'utilisateur n'est plus lié à rdv-solidarités: #{sync.errors}" }
format.turbo_stream { flash.now[:error] = "L'usager n'est plus lié à rdv-solidarités: #{sync.errors}" }
format.json { render json: { errors: sync.errors }, status: :unprocessable_entity }
end
end
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/tags_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def create
@organisation.tags << tag

redirect_to organisation_category_configurations_path(@organisation)
rescue ActiveRecord::ActiveRecordError => e
turbo_stream_display_error_modal(e.record.errors.full_messages)
end

def destroy
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def set_organisation_at_department_level
end

def set_structure_orientations
@structure_orientations = Orientation.active.where(organisation: @current_organisations)
@structure_orientations = Orientation.active.where(user: @users)
end

def set_orientation_types
Expand Down
12 changes: 8 additions & 4 deletions app/dashboards/motif_category_dashboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ class MotifCategoryDashboard < Administrate::BaseDashboard
ATTRIBUTE_TYPES = {
id: Field::Number,
category_configurations: Field::HasMany,
leads_to_orientation: Field::Boolean,
motifs: Field::HasMany,
name: Field::String,
motif_category_type: Field::Select.with_options(
searchable: false,
collection: ->(field) { field.resource.class.send(field.attribute.to_s.pluralize).keys }
),
optional_rdv_subscription: Field::Boolean,
follow_ups: Field::HasMany,
rdv_solidarites_motif_category_id: Field::Number,
Expand All @@ -30,6 +33,7 @@ class MotifCategoryDashboard < Administrate::BaseDashboard
COLLECTION_ATTRIBUTES = %i[
id
name
motif_category_type
].freeze

# SHOW_PAGE_ATTRIBUTES
Expand All @@ -39,8 +43,8 @@ class MotifCategoryDashboard < Administrate::BaseDashboard
name
short_name
template
motif_category_type
motifs
leads_to_orientation
optional_rdv_subscription
created_at
updated_at
Expand All @@ -53,13 +57,13 @@ class MotifCategoryDashboard < Administrate::BaseDashboard
name
short_name
template
leads_to_orientation
motif_category_type
optional_rdv_subscription
].freeze

FORM_ATTRIBUTES_EDIT = %i[
template
leads_to_orientation
motif_category_type
optional_rdv_subscription
].freeze

Expand Down
12 changes: 10 additions & 2 deletions app/helpers/environments_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ module EnvironmentsHelper
private

def production_env?
ENV["SENTRY_ENVIRONMENT"] == "production"
ENV["ENVIRONMENT_NAME"] == "production"
end

def staging_env?
ENV["SENTRY_ENVIRONMENT"] == "staging"
ENV["ENVIRONMENT_NAME"] == "staging"
end

def demo_env?
ENV["ENVIRONMENT_NAME"] == "demo"
end

def development_env?
Rails.env.development?
end
end
10 changes: 5 additions & 5 deletions app/helpers/rdv_insertion_instance_name_helper.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module RdvInsertionInstanceNameHelper
def rdv_insertion_instance_name
return if production_env?

if Rails.env.development?
Rails.env
else
if development_env?
"Développement"
elsif staging_env?
"Staging"
elsif demo_env?
"Démo"
end
end
Expand Down
12 changes: 2 additions & 10 deletions app/javascript/react/actions/assignReferent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,9 @@ import appFetch from "../../lib/appFetch";

const assignReferent = async (
userId,
referentEmail,
departmentId,
organisationId,
isDepartmentLevel
referentEmail
) => {
let url;
if (isDepartmentLevel) {
url = `/departments/${departmentId}/referent_assignations`;
} else {
url = `/organisations/${organisationId}/referent_assignations`;
}
const url = `/users/${userId}/referent_assignations`;
return appFetch(url, "POST", {
referent_assignation: { user_id: userId, agent_email: referentEmail },
});
Expand Down
13 changes: 12 additions & 1 deletion app/javascript/react/components/user/InvitationCells.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@ export default function InvitationCells({ user }) {
/* ----------------------------- Disabled invitations cases -------------------------- */
user.isArchived() ? (
<td colSpan={user.list.invitationsColSpan}>
Dossier archivé
Dossier archivé
{user.isArchivedInCurrentOrganisation() && (
<Tippy
content={
<>
Usager archivé pour le motif suivant : {user.archiveInCurrentOrganisation().archiving_reason}
</>
}
>
<i className="ms-2 fas fa-info-circle" />
</Tippy>
)}
</td>
) : user.createdAt && user.list.isDepartmentLevel && !user.linkedToCurrentCategory() ? (
<td colSpan={user.list.invitationsColSpan}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function EnrichWithContactFile({ handleContactsFile, fileSize })
placement="right"
content={
<span>
Les informations de contact ne sont pas ajoutées aux utilisateurs déjà créés.
Les informations de contact ne sont pas ajoutées aux usagers déjà créés.
</span>
}
>
Expand Down
4 changes: 2 additions & 2 deletions app/javascript/react/lib/createInvitationLetter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ const createInvitationLetter = async (
const result = await response.json();
if (result.errors[0] === "Le format de l'adresse est invalide") {
Swal.fire({
title: "Impossible d'inviter l'utilisateur",
title: "Impossible d'inviter l'usager",
html: "L'adresse n'est pas complète ou elle n'est pas enregistrée correctement",
icon: "error",
});
} else {
Swal.fire("Impossible d'inviter l'utilisateur", result.errors[0], "error");
Swal.fire("Impossible d'inviter l'usager", result.errors[0], "error");
}
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/react/lib/handleUserCreation.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const handleUserCreation = async (user, organisationId, options = { raiseError:
if (result.success) {
user.updateWith(result.user);
} else if (options.raiseError)
Swal.fire("Impossible de créer l'utilisateur", result.errors[0], "error");
Swal.fire("Impossible de créer l'usager", result.errors[0], "error");
return result;
};

Expand Down
2 changes: 1 addition & 1 deletion app/javascript/react/lib/handleUserInvitation.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const handleUserInvitation = async (
);
if (!result.success && options.raiseError) {
Swal.fire(
"Impossible d'inviter l'utilisateur",
"Impossible d'inviter l'usager",
result.errors && result.errors.join("<br/><br/>"),
"error"
);
Expand Down
4 changes: 2 additions & 2 deletions app/javascript/react/lib/retrieveUpToDateUsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const retrieveUsersFromApp = async (
return result.users;
}
Swal.fire(
"Une erreur s'est produite en récupérant les infos utilisateurs sur le serveur",
"Une erreur s'est produite en récupérant les infos des usagers sur le serveur",
result.errors && result.errors.join(" - "),
"warning"
);
Expand Down Expand Up @@ -56,7 +56,7 @@ const retrieveUpToDateUsers = async (usersFromList, departmentId) => {
(a.email &&
a.email === user.email &&
a.first_name.split(" ")[0].toLowerCase() ===
user.firstName.split(" ")[0].toLowerCase()) ||
user.firstName.split(" ")[0].toLowerCase()) ||
(a.phone_number &&
// since the phone are not formatted in the file we compare the 8 last digits
a.phone_number.slice(-8) === user.phoneNumber?.slice(-8) &&
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/react/lib/trackUserListComposition.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const trackUserListComposition = async (users) => {

window._mtm.push(payload)
} catch (error) {
console.warn("Impossible de tracker la composition de la liste d'utilisateurs", error);
console.warn("Impossible de tracker la composition de la liste des usagers", error);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
font: 700 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
z-index: 9999;
pointer-events: auto;
a:not([href]):not([class]) {
a:not([class]), span {
color: #fff;
text-decoration: none;
text-shadow: 0 -1px rgba(0, 0, 0, 0.5);
Expand Down
10 changes: 5 additions & 5 deletions app/jobs/alert_motif_category_has_changed_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ def perform(motif_id)
private

def alert_message
@alert_message ||= "
⚠️ Le motif #{motif.name} (#{motif.id}) vient de changer
de catégory malgré la présence de #{motif.rdvs.count} associés.
"
@alert_message ||=
"⚠️ Le motif #{motif.name} (ID rdv-sp: #{motif.rdv_solidarites_motif_id}) de l'organisation" \
" #{motif.organisation.name} (ID rdv-sp: #{motif.organisation.rdv_solidarites_organisation_id})" \
" vient de changer de catégorie malgré la présence de #{motif.rdvs.count} rendez-vous associés."
end

def alert_on_mattermost
MattermostClient.send_to_notif_channel(alert_message)
MattermostClient.send_to_private_channel(alert_message)
end

def alert_on_sentry
Expand Down
33 changes: 33 additions & 0 deletions app/jobs/concerns/locked_and_ordered_jobs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module LockedAndOrderedJobs
extend ActiveSupport::Concern
# This will wrap the hook inside the perform_with_lock method
prepend LockedJobs

CACHED_TIMESTAMP_EXPIRATION_TIME = 30.minutes

included do
around_perform :perform_in_order
end

private

def perform_in_order
RedisConnection.with_redis do |redis|
cache_key = self.class.lock_key(*arguments)
cached_timestamp = redis.get(cache_key)
job_timestamp = self.class.job_timestamp(*arguments)

next if cached_timestamp.present? && cached_timestamp.to_datetime > job_timestamp.to_datetime

yield

redis.set(cache_key, job_timestamp.to_s, ex: CACHED_TIMESTAMP_EXPIRATION_TIME)
end
end

class_methods do
def job_timestamp(_job_args)
raise NoMethodError
end
end
end
23 changes: 23 additions & 0 deletions app/jobs/concerns/locked_jobs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module LockedJobs
extend ActiveSupport::Concern

included do
around_perform :perform_with_lock
end

private

def perform_with_lock(&block)
# if the lock is not available, we raise an WithAdvisoryLock::FailedToAcquireLockError
# and the job will be retried
ActiveRecord::Base.with_advisory_lock!(
self.class.lock_key(*arguments), timeout_seconds: 0, &block
)
end

class_methods do
def lock_key(_job_args)
raise NoMethodError
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module InboundWebhooks
module RdvSolidarites
class LockedAndOrderedJobBase < ApplicationJob
include LockedAndOrderedJobs

def self.job_timestamp(_data, meta)
meta["timestamp"]
end
end
end
end
Loading

0 comments on commit e846af2

Please sign in to comment.