Skip to content

Commit

Permalink
feat(open-data): add structureType
Browse files Browse the repository at this point in the history
  • Loading branch information
pYassine committed Oct 9, 2024
1 parent fe25d7c commit cf73663
Show file tree
Hide file tree
Showing 20 changed files with 326 additions and 93 deletions.
3 changes: 3 additions & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"sanitize-filename": "^1.6.3",
"sanitize-html": "^2.13.0",
"sharp": "^0.33.5",
"slug": "^9.1.0",
"sort-object": "^3.0.3",
"source-map-support": "^0.5.21",
"striptags": "^3.2.0",
Expand Down Expand Up @@ -135,6 +136,8 @@
"@types/pizzip": "^3.0.5",
"@types/rimraf": "^4.0.5",
"@types/sanitize-html": "^2.11.0",
"@types/slug": "^5.0.9",
"@types/striptags": "^3.1.1",
"@types/supertest": "^6.0.2",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^7.14.1",
Expand Down

This file was deleted.

39 changes: 39 additions & 0 deletions packages/backend/src/_migrations/1728487458329-manual-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { IsNull, MigrationInterface } from "typeorm";
import { openDataPlaceRepository } from "../database";
import { getStructureType } from "../open-data-places/functions";
import { appLogger } from "../util";
import { domifaConfig } from "../config";

export class UpdateStructureTypeMigration1728487458329
implements MigrationInterface
{
name = "UpdateStructureTypeMigration1728487458329";
public async up(): Promise<void> {
if (
domifaConfig().envId === "prod" ||
domifaConfig().envId === "preprod" ||
domifaConfig().envId === "local"
) {
appLogger.info("[MIGRATION] Update structureType for OpenData");
const places = await openDataPlaceRepository.find({
where: {
domifaStructureId: IsNull(),
},
select: ["nom", "uuid"],
});

for (const place of places) {
await openDataPlaceRepository.update(
{ uuid: place.uuid },
{
structureType: getStructureType(place.nom),
}
);
}
}
}

public async down(): Promise<void> {
//
}
}
25 changes: 25 additions & 0 deletions packages/backend/src/_migrations/1728487663488-manual-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { MigrationInterface } from "typeorm";
import { appLogsRepository } from "../database";
import { domifaConfig } from "../config";

export class DeleteUselessLogsMigration1728487663488
implements MigrationInterface
{
name = "DeleteUselessLogsMigration1728487663488";

public async up(): Promise<void> {
if (
domifaConfig().envId === "prod" ||
domifaConfig().envId === "preprod" ||
domifaConfig().envId === "local"
) {
await appLogsRepository.delete({
action: "USAGERS_DOCS_DOWNLOAD",
});
}
}

public async down(): Promise<void> {
//
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
} from "@domifa/common";
import { MetabaseStatsDto } from "../../_dto/MetabaseStats.dto";
import { domifaConfig } from "../../../config";
import jwt from "jsonwebtoken";
import { sign } from "jsonwebtoken";
import { FindOptionsWhere } from "typeorm";
import { AppLogsService } from "../../../modules/app-logs/app-logs.service";

Expand Down Expand Up @@ -142,7 +142,7 @@ export class AdminStructuresController {
@Get("stats")
@AllowUserProfiles("super-admin-domifa")
public async stats(): Promise<AdminStructureStatsData> {
return this.adminStructuresService.getStatsDomifaAdminDashboard();
return await this.adminStructuresService.getStatsDomifaAdminDashboard();
}

@Get("last-update")
Expand Down Expand Up @@ -260,7 +260,7 @@ export class AdminStructuresController {
exp: Math.round(Date.now() / 1000) + 100 * 60, // 10 minute expiration
};

const token = jwt.sign(payload, domifaConfig().metabase.token);
const token = sign(payload, domifaConfig().metabase.token);
const url = `${METABASE_URL}embed/dashboard/${token}#bordered=false&titled=false`;

return { url };
Expand All @@ -278,7 +278,7 @@ export class AdminStructuresController {
verified: true,
};

return structureRepository.find({
return await structureRepository.find({
where: params,
select: ["id", "nom", "ville", "codePostal"],
order: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { StructureType } from "@domifa/common";
import slug from "slug";
import striptags from "striptags";

export const getStructureType = (input: string): StructureType | null => {
if (!input) {
return null;
}
const strippedInput = striptags(input).toLowerCase().trim();

const normalizedInput = slug(strippedInput, {
mode: "rfc3986" as const,
lower: true,
replacement: " ", // Utiliser des espaces au lieu des tirets
remove: /[^a-z0-9\s]/g, // Supprimer tous les caractères non alphanumériques sauf les espaces
locale: "fr",
trim: true,
});

if (!normalizedInput) {
return null;
}

if (
normalizedInput.includes("ccas") ||
normalizedInput.startsWith("commune") ||
normalizedInput.startsWith("centre communal") ||
normalizedInput.startsWith("centre communal daction sociale") ||
normalizedInput.includes("centre daction sociale") ||
normalizedInput.startsWith("mairie") ||
normalizedInput.startsWith("hotel de ville")
) {
return "ccas";
}

if (
normalizedInput.startsWith("cias") ||
normalizedInput.startsWith("centre intercommunal") ||
normalizedInput.includes("communaute de communes") ||
normalizedInput.includes("centre intercommunal daction sociale") ||
normalizedInput.includes("intercommunal")
) {
return "cias";
}

return "asso";
};
2 changes: 2 additions & 0 deletions packages/backend/src/open-data-places/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @index('./*.ts', f => `export * from '${f.path}'`)
export * from "./getStructureType";
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const STRUCTURE_NAMES = {
"4AJ Plateforme Logement Jeunes CLLAJ ARRAS": "asso",
"A fratellanza": "asso",
"Abri de la Providence": "asso",
"ACCEPTESS-T": "asso",
ACCES: "asso",
"Accueil de Jour Association Eole": "asso",
"Accueil de jour de Douai Croix rouge Française": "asso",
"AHLIS 46": "asso",
"AIDE A L'INSERTION DES DEMANDEURS D'ASILE": "asso",
AVAF: "asso",
"BOUTIQUE SOLIDARITÉ EMMAÜS DE BEAUVAIS": "asso",
"Boutique Solidarité": "asso",
Bruillot: "asso",
"C.C.A.S de la commune de Martillac": "ccas",
"C.C.A.S DE PAMIERS": "ccas",
"CIAS de Domène": "cias",
Vista: "asso",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { getStructureType } from "../getStructureType";
import { STRUCTURE_NAMES } from "./STRUCTURE_NAMES.const";

describe("checkOrganizationType", () => {
it("should correctly identify organization types for all entries", () => {
Object.entries(STRUCTURE_NAMES).forEach(([name, expectedType]) => {
const result = getStructureType(name);
expect(result).toBe(expectedType);
});
});

it("should return an empty string for unrecognized inputs", () => {
const unrecognizedInputs = [
"Random Organization",
"Just a regular company",
];

unrecognizedInputs.forEach((input) => {
expect(getStructureType(input)).toBe("asso");
});
});

it("should handle edge cases correctly", () => {
const edgeCases = {
"": null,
" ": null,
CCAS: "ccas",
cias: "cias",
Association: "asso",
"<script>CCAS</script>": "ccas",
"C.C.A.S.": "ccas",
"Centre Communal d'Action Sociale": "ccas",
"MAIRIE-CCAS": "ccas",
"Organisme-Association": "asso",
};

Object.entries(edgeCases).forEach(([input, expected]) => {
expect(getStructureType(input)).toBe(expected);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AppEntity } from "@domifa/common";
import { AppEntity, StructureType } from "@domifa/common";

export interface OpenDataPlace extends AppEntity {
nom: string;
Expand All @@ -17,4 +17,5 @@ export interface OpenDataPlace extends AppEntity {
mail: string | null;
soliguideStructureId: number;
mssId: string | null;
structureType: StructureType | null;
}
27 changes: 14 additions & 13 deletions packages/backend/src/open-data-places/load-data-inclusion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,11 @@ import {
getDepartementFromCodePostal,
getRegionCodeFromDepartement,
} from "@domifa/common";
import { getStructureType } from "./functions";

let page = 1;
let nbResults = 0;

export const loadDataInclusionData = async (structureType: "CCAS" | "CIAS") => {
if (
!domifaConfig().openDataApps.dataInclusionUrl ||
!domifaConfig().openDataApps.dataInclusionToken
) {
console.log("[IMPORT DATA INCLUSION] Fail, token or url is not in env");
return;
}
appLogger.info("Import data-inclusion start 🏃‍♂️... ");

await getFromDataInclusion(structureType);
};

const getFromDataInclusion = async (structureType: "CCAS" | "CIAS") => {
let datInclusionData: DataInclusionPlace[] = [];

Expand Down Expand Up @@ -80,6 +68,7 @@ const getFromDataInclusion = async (structureType: "CCAS" | "CIAS") => {
departement,
region: getRegionCodeFromDepartement(departement),
software: "other",
structureType: getStructureType(place.nom),
latitude: place?.latitude,
longitude: place?.longitude,
source: "data-inclusion",
Expand Down Expand Up @@ -121,3 +110,15 @@ const getFromDataInclusion = async (structureType: "CCAS" | "CIAS") => {
appLogger.error("[IMPORT] Something happen", e);
}
};
export const loadDataInclusionData = async (structureType: "CCAS" | "CIAS") => {
if (
!domifaConfig().openDataApps.dataInclusionUrl ||
!domifaConfig().openDataApps.dataInclusionToken
) {
console.log("[IMPORT DATA INCLUSION] Fail, token or url is not in env");
return;
}
appLogger.info("Import data-inclusion start 🏃‍♂️... ");

await getFromDataInclusion(structureType);
};
30 changes: 16 additions & 14 deletions packages/backend/src/open-data-places/load-mss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,11 @@ import { OpenDataPlace } from "./interfaces/OpenDataPlace.interface";
import {
getDepartementFromCodePostal,
getRegionCodeFromDepartement,
getStructureType,
} from "@domifa/common";
import { MssPlace } from "./interfaces";
import { getLocation } from "../structures/services/location.service";

export const loadMssData = async () => {
if (
!domifaConfig().openDataApps.mssUrl ||
!domifaConfig().openDataApps.mssToken
) {
appLogger.info("[IMPORT DATA MSS] Fail, token or url is not in env");
return;
}
appLogger.info("Import MSS start 🏃‍♂️... ");
await getFromMss();
};

const getFromMss = async () => {
let newPlaces = 0;
let updatedPlaces = 0;
Expand All @@ -40,11 +29,11 @@ const getFromMss = async () => {

for await (const place of response.data) {
const postalCode = place.zipcode.replace(/\W/g, "");
const address = place.address + ", " + postalCode;
const address = `${place.address}, ${postalCode}`;
const position = await getLocation(address);

if (!position) {
appLogger.warn("Adresse not found " + address);
appLogger.warn(`Adresse not found ${address}`);
continue;
}

Expand All @@ -55,6 +44,7 @@ const getFromMss = async () => {
codePostal: postalCode,
ville: cleanCity(place?.city),
departement,
structureType: getStructureType(place.name),
region: getRegionCodeFromDepartement(departement),
latitude: position.coordinates[1],
longitude: position.coordinates[0],
Expand Down Expand Up @@ -123,3 +113,15 @@ const getFromMss = async () => {
);
}
};

export const loadMssData = async () => {
if (
!domifaConfig().openDataApps.mssUrl ||
!domifaConfig().openDataApps.mssToken
) {
appLogger.info("[IMPORT DATA MSS] Fail, token or url is not in env");
return;
}
appLogger.info("Import MSS start 🏃‍♂️... ");
await getFromMss();
};
Loading

0 comments on commit cf73663

Please sign in to comment.