Skip to content
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.

feat(dossier import): format email, firstName & lastName + log error from cron #108

Merged
merged 2 commits into from
Mar 22, 2022
Merged
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
3 changes: 1 addition & 2 deletions src/__tests__/api/psychologists.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe("/api/psychologists", () => {
);

expect(result.status).toEqual(200);
expect(result.data).toEqual([]);
expect(result.data.length).toBeGreaterThan(1);
});
it("should return some results if coordinates passed", async () => {
const result = await axios.get(
Expand All @@ -18,6 +18,5 @@ describe("/api/psychologists", () => {

expect(result.status).toEqual(200);
expect(result.data.length).toBeGreaterThan(1);
expect(result.data.filter((psy) => psy.distance > 1).length).toEqual(0);
});
});
7 changes: 1 addition & 6 deletions src/components/Directory/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ const Header = () => {
<div className="fr-mt-6w">
<h1>Annuaire</h1>
<h2>Trouver un psychologue partenaire près de chez soi.</h2>
<p>
Accéder rapidement aux coordonnées des psychologues partenaires du
dispositif MonPsy.
<br />
La liste des psychologues partenaires est actualisée régulièrement.
</p>
<p>La liste des psychologues partenaires est actualisée régulièrement.</p>
<Callout className="fr-mb-4w fr-callout--pink-tuile">
<CalloutTitle>A lire, avant de prendre rendez-vous :</CalloutTitle>
<div className="fr-callout__text fr-text--md">
Expand Down
2 changes: 1 addition & 1 deletion src/components/Directory/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const SearchBar = ({
}, [filterText]);

return (
<Row className="fr-pb-4w" alignItems="middle">
<Row className="fr-pb-2w" alignItems="middle">
<Col n="md-9 12">
<SearchableSelect
selected={positionFilter}
Expand Down
20 changes: 10 additions & 10 deletions src/components/Directory/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ const Directory = () => {
setIsLoading(false);
if (currentPage === 0) {
const refs = {};
if (!response.data.length) {
if (response.data[0].distance > 1) {
setNoPsychologist(true);
return;
}
response.data.forEach((x) => (refs[x.id] = createRef()));
psychologistsRefs.current = refs;
Expand Down Expand Up @@ -128,6 +127,15 @@ const Directory = () => {
loadPsychologists={loadPsychologists}
/>
<ResultWrapper className="fr-mb-8w">
{noPsychologist && (
<Alert
title="Pas encore de psychologues partenaires dans cette zone"
className="fr-mb-4w"
description="Nous mettons à jour cette liste régulièrement.
N'hésitez pas à dézoomer sur la carte (cliquer sur -) pour voir les psychologues proches de chez vous.
A noter, certains psychologues acceptent les séances à distance après la 1ère rencontre physique"
/>
)}
{psychologists?.length > 0 && (
<Results
loadMorePsychologists={loadMorePsychologists}
Expand All @@ -141,14 +149,6 @@ const Directory = () => {
/>
)}
{isLoading && <Spinner />}

{noPsychologist && (
<Alert
title="Pas encore de psychologues disponibles dans cette zone"
className="fr-mt-1w"
description="Nous mettons à jour cette liste régulièrement."
/>
)}
</ResultWrapper>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion src/cron/demarchesSimplifiees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const importData = async (): Promise<void> => {
{ where: { id: 1 } }
);

console.log(`${dsAPIData.psychologists.length} downloaded`);
console.log(`${dsAPIData.psychologists.length} saved`);
} else {
console.log("No psychologists to save");
}
Expand Down
10 changes: 4 additions & 6 deletions src/pages/api/psychologists/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ const psychologists = async (req: NextApiRequest, res: NextApiResponse) => {
const psychologists = await getAll(filters);

return res.status(200).json(
psychologists
.filter((psy) => psy.distance < 1)
.map((psy) => ({
...psy,
email: psy.displayEmail ? psy.email : undefined,
}))
psychologists.map((psy) => ({
...psy,
email: psy.displayEmail ? psy.email : undefined,
}))
);
}
};
Expand Down
40 changes: 39 additions & 1 deletion src/services/__tests__/ds-parse-psychologists.ts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("parseDossierMetadata", () => {
firstName: "Anne",
id: 0,
instructorId: "123",
lastName: "Smith",
lastName: "SMITH",
state: "Accepted",
teleconsultation: true,
});
Expand All @@ -61,6 +61,7 @@ describe("parseDossierMetadata", () => {
${"wrong:wrong"} | ${undefined}
${"wrong@com"} | ${undefined}
${"valid@email.com"} | ${"valid@email.com"}
${"vaLiD@EMAIL.com"} | ${"valid@email.com"}
`("should parse email champs for $input", async ({ input, resultValue }) => {
const dossierWithWebsite = createDossier();
dossierWithWebsite.champs.push({
Expand All @@ -80,6 +81,7 @@ describe("parseDossierMetadata", () => {
${"doctolib"} | ${undefined}
${"https://valid.com"} | ${"https://valid.com"}
${"http://valid.com"} | ${"http://valid.com"}
${"http://VALID.com"} | ${"http://valid.com"}
`(
"should parse website champs for $input",
async ({ input, resultValue }) => {
Expand Down Expand Up @@ -122,4 +124,40 @@ describe("parseDossierMetadata", () => {
expect(result.languages).toEqual(resultValue);
}
);

it.each`
input | resultValue
${"Laurence"} | ${"Laurence"}
${"lauREnce"} | ${"Laurence"}
${"Marie-Christine"} | ${"Marie-Christine"}
${"marie-christine"} | ${"Marie-Christine"}
${"MARIE-CHRISTINE"} | ${"Marie-Christine"}
${"MARIE CHRISTINE"} | ${"Marie Christine"}
${"MARIE CHRISTINE Anne-CHARlotte"} | ${"Marie Christine Anne-Charlotte"}
`(
"should format firsName champs for $input",
async ({ input, resultValue }) => {
const dossierWithLangue = createDossier();
dossierWithLangue.demandeur.prenom = input;
const result = await parseDossierMetadata(dossierWithLangue);

expect(result.firstName).toEqual(resultValue);
}
);

it.each`
input | resultValue
${"Dupont"} | ${"DUPONT"}
${"DuPOnt"} | ${"DUPONT"}
${"DuPOnt de la particule"} | ${"DUPONT DE LA PARTICULE"}
`(
"should format firsName champs for $input",
async ({ input, resultValue }) => {
const dossierWithLangue = createDossier();
dossierWithLangue.demandeur.nom = input;
const result = await parseDossierMetadata(dossierWithLangue);

expect(result.lastName).toEqual(resultValue);
}
);
});
2 changes: 1 addition & 1 deletion src/services/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default {
port: parseInt(process.env.MAIL_PORT || "25", 10),
tls: parseBoolean(process.env.MAIL_TLS),
},
minScoreAddress: parseFloat(process.env.MIN_SCORE_ADDRESS || "0.55"),
minScoreAddress: parseFloat(process.env.MIN_SCORE_ADDRESS || "0.30"),
newFeatures: parseBoolean(process.env.NEXT_PUBLIC_NEW_FEATURES),
nextAuthUrl: process.env.NEXTAUTH_URL,
postgre: {
Expand Down
4 changes: 2 additions & 2 deletions src/services/demarchesSimplifiees/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const getAllPsychologistList = async (
const apiResponse = await graphqlFunction(cursor);

const { pageInfo, nodes } = apiResponse.demarche.dossiers;

console.log("Fetch", apiResponse.demarche.dossiers.nodes.length, "dossiers");
const nextAccumulator = accumulator.concat(nodes);

if (pageInfo.hasNextPage) {
Expand All @@ -39,7 +39,7 @@ export const getPsychologistList = async (
psychologists: Psychologist[];
lastCursor: string;
}> => {
const time = `Fetching all psychologists from DS (query id #${Math.random().toString()})`;
const time = `Fetching all psychologists from DS (query id #${Math.random().toString()} with cursor ${cursor})`;

console.time(time);
const list = await getAllPsychologistList(
Expand Down
22 changes: 18 additions & 4 deletions src/services/demarchesSimplifiees/parse-psychologists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,29 @@ const emailSchema = Joi.object({
});
const isFrench = new RegExp("(français|francais)", "g");

const capitalizeFirstLetter = (word) =>
word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();

function formatFirstName(string) {
return string
.split(" ")
.map((word) => word.split("-").map(capitalizeFirstLetter).join("-"))
.join(" ");
}

const parsers = {
displayEmail: (value) => value === "true",
email: (value) =>
emailSchema.validate({ email: value }).error ? undefined : value,
emailSchema.validate({ email: value }).error
? undefined
: value.toLowerCase(),
languages: (value) =>
!value || value.trim().toLowerCase().match(isFrench) ? undefined : value,
teleconsultation: (value) => value === "true",
website: (value) =>
websiteSchema.validate({ website: value }).error ? undefined : value,
websiteSchema.validate({ website: value }).error
? undefined
: value.toLowerCase(),
};
const parseChampValue = (field, value) =>
parsers[field] ? parsers[field](value) : value;
Expand All @@ -39,10 +53,10 @@ export const parseDossierMetadata = async (
const psychologist: Partial<Psychologist> = {
archived: dossier.archived,
department: extractDepartmentNumber(dossier.groupeInstructeur.label),
firstName: dossier.demandeur.prenom,
firstName: formatFirstName(dossier.demandeur.prenom),
id: dossier.number,
instructorId: dossier.groupeInstructeur.id,
lastName: dossier.demandeur.nom,
lastName: dossier.demandeur.nom.toUpperCase(),
state: dossier.state,
};

Expand Down
25 changes: 15 additions & 10 deletions src/services/getAddressCoordinates.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
import * as Sentry from "@sentry/nextjs";
import axios, { AxiosError } from "axios";

import { Coordinates, CoordinatesAPI } from "../types/coordinates";
import config from "./config";

const ADDRESS_DELIMITER = ";";

const logError = async (error: Error | AxiosError) => {
const logError = (mesg: string) => {
Sentry.captureMessage(mesg);
console.log(mesg);
};
const extractError = (error: Error | AxiosError): void => {
if (axios.isAxiosError(error)) {
if (error.response) {
console.log("Error", error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
logError(
`Error ${error.response.data} status: ${error.response.status} headers: ${error.response.headers}`
);
} else {
console.log("Error", error.request);
logError(`Error ${error.request}`);
}
} else {
console.log("Error", error.message);
logError(`Error ${error.message}`);
}
};

Expand All @@ -24,9 +29,9 @@ const getAddressCoordinates = async (address: string): Promise<Coordinates> => {
const url = encodeURI(
`https://api-adresse.data.gouv.fr/search/?q=${firstAddress}&limit=1`
);
const response = await axios.get<CoordinatesAPI>(url).catch(logError);
const response = await axios.get<CoordinatesAPI>(url).catch(extractError);

if (response && response.data.features && response.data.features.length > 0) {
if (response && response.data.features?.length > 0) {
const feature = response.data.features[0];
const [longitude, latitude] = feature.geometry.coordinates;
const { score } = feature.properties;
Expand All @@ -37,10 +42,10 @@ const getAddressCoordinates = async (address: string): Promise<Coordinates> => {
longitude,
});
}
// Insufficient score
logError(`Error: score insuffisant: "${firstAddress}": ${score}`);
return Promise.resolve(null);
}
console.debug(`Error: address not found or error: "${firstAddress}"`);
logError(`Error: address not found or error: "${firstAddress}"`);
return Promise.resolve(null);
};

Expand Down