feat: ajout nbFamillesResistantesAssumantDesMissionsEL

This commit is contained in:
Sébastien Arod 2025-01-16 14:42:28 +01:00
parent 3d6b9a873e
commit a64557c5b4
9 changed files with 93 additions and 4 deletions

7
src/data/Contact.ts Normal file
View file

@ -0,0 +1,7 @@
import { Mission } from "./Mission";
export type Contact = {
notionId: string;
notionIdFamille: string;
Missions: Mission[];
};

View file

@ -11,6 +11,7 @@ import {
} from "./StatutFamille";
import { StatutSocial } from "./StatutSocial";
import { StatutPenal } from "./StatutPenal";
import { Mission } from "./Mission";
export type Famille = Readonly<{
notionId: string;
@ -34,6 +35,7 @@ export type Famille = Readonly<{
EvenementsApresEL: EvenementFamille[];
DerniereModification: Date;
Missions: Mission[];
}>;
export function periodOfResistance(

6
src/data/Mission.ts Normal file
View file

@ -0,0 +1,6 @@
export type Mission = {
notionId: string;
Nom: string;
Equipe: string;
ContactsNotionIds: string[];
};

View file

@ -1,2 +1,5 @@
export const familEventsDbId: string = "c4d434b4603c4481a4d445618ecdf999";
export const departementsDbId: string = "787779be614544069f609bf9d2a7cd15";
export const contactsDbId: string = "be112427dd314c14b93dfd027323c908";
export const missionsDbId: string = "fa2ab021a5dc4e239b7e7201ae579162";

View file

@ -12,7 +12,12 @@ import { statusPropertyToText } from "../utils/properties/statusPropertyToText";
import { titlePropertyToText } from "../utils/properties/titlePropertyToText";
import { queryAllDbResults } from "../utils/queryAllDbResults";
import { richTextPropertyToPlainText } from "../utils/text/richTextPropertyToPlainText";
import { departementsDbId, familEventsDbId } from "./dbIds";
import {
contactsDbId,
departementsDbId,
familEventsDbId,
missionsDbId,
} from "./dbIds";
import {
propContexteEntree,
familiesDbId,
@ -22,6 +27,9 @@ import {
} from "./dbfamilleDesc";
import { StatutPenal } from "../../data/StatutPenal";
import { StatutSocial } from "../../data/StatutSocial";
import { Contact } from "../../data/Contact";
import { Mission } from "../../data/Mission";
import { relationPropertyToPageIds } from "../utils/properties/relationPropertyToPageIds";
type Departement = {
notionId: string;
@ -42,6 +50,18 @@ export async function fetchFamiliesWithEventsFromNotion(
})
).filter(isFullPage);
const contactPages = (
await queryAllDbResults(notionClient, {
database_id: contactsDbId,
})
).filter(isFullPage);
const missionsPages = (
await queryAllDbResults(notionClient, {
database_id: missionsDbId,
})
).filter(isFullPage);
const departementPages = (
await queryAllDbResults(notionClient, {
database_id: departementsDbId,
@ -53,13 +73,35 @@ export async function fetchFamiliesWithEventsFromNotion(
name: titlePropertyToText(page.properties, "Nom"),
}));
const missions: Mission[] = missionsPages.map((page) => ({
notionId: page.id,
Nom: titlePropertyToText(page.properties, "Nom"),
Equipe: selectPropertyToText(page.properties, "Équipe")!,
ContactsNotionIds: relationPropertyToPageIds(
page.properties,
"📔 Contacts"
),
}));
const contacts: Contact[] = contactPages.map((page) => ({
notionId: page.id,
name: titlePropertyToText(page.properties, "Nom"),
notionIdFamille: relationPropertyToPageId(page.properties, "Famille")!,
Missions: missions.filter((m) => m.ContactsNotionIds.includes(page.id)),
}));
const familyEvents = eventPages.map((pageObjectResponse) => {
return buildFamilyEvent(pageObjectResponse);
});
const familles: Famille[] = await Promise.all(
familyPages.map((pageObjectResponse) => {
return buildFamily(pageObjectResponse, familyEvents, departements);
return buildFamily(
pageObjectResponse,
familyEvents,
departements,
contacts
);
})
);
return familles;
@ -85,7 +127,8 @@ function buildFamilyEvent(page: PageObjectResponse): EvenementFamille {
function buildFamily(
page: PageObjectResponse,
familyEvents: EvenementFamille[],
departements: Departement[]
departements: Departement[],
contacts: Contact[]
): Famille {
const pageProperties = page.properties;
@ -93,6 +136,7 @@ function buildFamily(
const departement = departementId
? departements.find((d) => d.notionId === departementId)
: null;
const family: Famille = {
notionId: page.id,
Titre: titlePropertyToText(pageProperties, ""),
@ -115,6 +159,9 @@ function buildFamily(
)!,
Penal: statusPropertyToText(pageProperties, propPenal) as StatutPenal,
Social: statusPropertyToText(pageProperties, propSocial) as StatutSocial,
Missions: contacts
.filter((c) => c.notionIdFamille === page.id)
.flatMap((c) => c.Missions),
};
return family;
}

View file

@ -0,0 +1,15 @@
import { PageProperties } from "../types/PageProperties";
import { extractPagePropertyValue } from "./extractPagePropertyValue";
export function relationPropertyToPageIds(
pageProperties: PageProperties,
propName: string
): string[] {
const propValue = extractPagePropertyValue(pageProperties, propName);
if (propValue.type !== "relation") {
throw new Error(
`Property ${propName} was expected to have type "relation" but got "${propValue.type}".`
);
}
return propValue.relation.map((v) => v.id);
}

View file

@ -22,7 +22,7 @@ type CacheConfig =
export async function queryAllDbResults(
notion: Client,
dbQuery: QueryDatabaseParameters,
{ cache: cacheConfig }: QueryExtraOptions = { cache: false }
{ cache: cacheConfig }: QueryExtraOptions = { cache: { ttl: 3600 * 1000 } }
): Promise<QueryDatabaseResponse["results"]> {
const queryHash = createHash("sha1")
.update(JSON.stringify(dbQuery))

View file

@ -41,6 +41,9 @@ export const statsGeneralesDesc = {
label: "Nb familles actuellement résistante par département",
type: "multi",
},
nbFamillesResistantesAssumantDesMissionsEL: {
label: "Nb familles actuellement résistante assumant des missions EL",
},
},
} as const;

View file

@ -24,6 +24,10 @@ export function computeStatsGenerales(familles: Famille[]): StatsGenerales {
const dureesResistances = famillesResistantesOrEx.map(
(f) => dureeResistanceInDays(f)!
);
const famillesResistantesAssumantDesMissionsEL = famillesResistantes.filter(
(f) => f.Missions.length > 0
);
const statsGenerales: StatsGenerales = {
nbFamillesResistantesActuelles:
nbFamillesAvecPagesLiees(famillesResistantes),
@ -49,6 +53,8 @@ export function computeStatsGenerales(familles: Famille[]): StatsGenerales {
isIntegrationEnCours(f.Statut)
).length,
nbFicheFamillesParStatut: sortByKey(countBy(familles, (f) => f.Statut)),
nbFamillesResistantesAssumantDesMissionsEL:
famillesResistantesAssumantDesMissionsEL.length,
};
return statsGenerales;
}