mirror of
https://framagit.org/enfance-libre/statistiques
synced 2025-12-07 23:13:45 +00:00
feat: check db prop options outside data consistency
This commit is contained in:
parent
f54a860359
commit
a6c42aef80
6 changed files with 133 additions and 71 deletions
|
|
@ -1,6 +1,9 @@
|
||||||
export type ContexteEntreeDC =
|
export const contexteEntreeDCs = [
|
||||||
| "Pas de demande (Plein droit)"
|
"Pas de demande (Plein droit)",
|
||||||
| "Pas de demande"
|
"Pas de demande",
|
||||||
| "Après refus"
|
"Après refus",
|
||||||
| "Après mise en demeure"
|
"Après mise en demeure",
|
||||||
| "Après poursuite procureur";
|
"Après poursuite procureur",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type ContexteEntreeDC = (typeof contexteEntreeDCs)[number];
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
export type StatutFamille =
|
export const statutsFamille = [
|
||||||
| "Résistant.e"
|
"Résistant.e",
|
||||||
| "Ex résistant·e·s"
|
"Ex résistant·e·s",
|
||||||
| "À préciser"
|
"À préciser",
|
||||||
| "Se questionne"
|
"Se questionne",
|
||||||
| "Désobéissence décidée"
|
"Désobéissance décidée",
|
||||||
| "Rédaction Déclaration"
|
"Rédaction Déclaration",
|
||||||
| "Déclaration Validée - Attente éléments"
|
"Déclaration validée - Attente éléments",
|
||||||
| "Abdandon"
|
"Abandon",
|
||||||
| "Incompatible";
|
"Incompatible",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type StatutFamille = (typeof statutsFamille)[number];
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,37 @@
|
||||||
export type TypeEvenement =
|
export const typesEvenements = [
|
||||||
| "Récidive gendarmerie"
|
"Récidive gendarmerie",
|
||||||
| "Appel du jugement"
|
"Appel du jugement",
|
||||||
| "Tribunal de police judiciaire"
|
"Tribunal de police judiciaire",
|
||||||
| "Signalement au procureur"
|
"Signalement au procureur",
|
||||||
| "Mise en demeure de scolarisation"
|
"Mise en demeure de scolarisation",
|
||||||
| "Signalement"
|
"Signalement",
|
||||||
| "Audition gendarmerie / police"
|
"Audition gendarmerie / police",
|
||||||
| "Convocation procureur"
|
"Convocation procureur",
|
||||||
| "Audition procureur"
|
"Audition procureur",
|
||||||
| "Composition pénale refusée"
|
"Composition pénale refusée",
|
||||||
| "Composition pénale acceptée"
|
"Composition pénale acceptée",
|
||||||
| "Classement social sans suite"
|
"Classement social sans suite",
|
||||||
| "Classement pénal sans suite"
|
"Classement pénal sans suite",
|
||||||
| "Enquête sociale"
|
"Enquête sociale",
|
||||||
| "Information préoccupante"
|
"Information préoccupante",
|
||||||
| "Juge pour enfants"
|
"Juge pour enfants",
|
||||||
| "Tribunal correctionnel"
|
"Tribunal correctionnel",
|
||||||
| "Convocation CRPC"
|
"Convocation CRPC",
|
||||||
| "Plaidoirie"
|
"Plaidoirie",
|
||||||
| "Audience CRPC"
|
"Audience CRPC",
|
||||||
| "Refus CRPC"
|
"Refus CRPC",
|
||||||
| "Acceptation CRPC" // PLaceholder see does not exist in Notion yet // See https://discord.com/channels/990921361121746984/1245360366322585691/1248260713634336839
|
"Acceptation CRPC", // PLaceholder see does not exist in Notion yet // See https://discord.com/channels/990921361121746984/1245360366322585691/1248260713634336839
|
||||||
| "Audition des enfants"
|
"Audition des enfants",
|
||||||
| "Assistance éducative"
|
"Assistance éducative",
|
||||||
| "Contrôle forcé"
|
"Contrôle forcé",
|
||||||
| "Refus de contrôle"
|
"Refus de contrôle",
|
||||||
| "Rappel à la loi"
|
"Rappel à la loi",
|
||||||
| "Passage police municipale"
|
"Passage police municipale",
|
||||||
| "Administrateur AD'HOC"
|
"Administrateur AD'HOC",
|
||||||
| "Validation désobéissance"
|
"Validation désobéissance",
|
||||||
| "Contrôle URSSAF"
|
"Contrôle URSSAF",
|
||||||
| "Contrôle fiscal"
|
"Contrôle fiscal",
|
||||||
| "Gendarmerie/Forces de l'ordre";
|
"Gendarmerie/Forces de l'ordre",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type TypeEvenement = (typeof typesEvenements)[number];
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,11 @@ function checkFamilyDataConsistency(family: Famille): ConsistencyReport {
|
||||||
issueType: "Ex résistant.e.s sans date Sortie",
|
issueType: "Ex résistant.e.s sans date Sortie",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (family.Integration && family.Sortie && family.Integration > family.Sortie) {
|
if (
|
||||||
|
family.Integration &&
|
||||||
|
family.Sortie &&
|
||||||
|
family.Integration > family.Sortie
|
||||||
|
) {
|
||||||
consistencyErrors.push({
|
consistencyErrors.push({
|
||||||
familyId: family.Titre,
|
familyId: family.Titre,
|
||||||
issueType: "Date Intégration > date Sortie ",
|
issueType: "Date Intégration > date Sortie ",
|
||||||
|
|
@ -77,14 +81,7 @@ function checkFamilyDataConsistency(family: Famille): ConsistencyReport {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
consistencyWarnings.push(
|
|
||||||
...family.Evenements.filter((e) => !isValidEvenementFamille(e.Type)).map(
|
|
||||||
(e) => ({
|
|
||||||
familyId: family.Titre,
|
|
||||||
issueType: `Evenement ${e.notionId} a un Type non géré: "${e.Type}"`,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
consistencyWarnings.push(
|
consistencyWarnings.push(
|
||||||
...family.Evenements.filter((e) => e.Type !== null && e.Date === null).map(
|
...family.Evenements.filter((e) => e.Type !== null && e.Date === null).map(
|
||||||
(e) => ({
|
(e) => ({
|
||||||
|
|
|
||||||
39
src/notion/fetch/checkDbPropertyOptionsMatchesType.ts
Normal file
39
src/notion/fetch/checkDbPropertyOptionsMatchesType.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { GetDatabaseResponse } from "@notionhq/client/build/src/api-endpoints";
|
||||||
|
|
||||||
|
export function checkDbPropertyOptionsMatchesType(
|
||||||
|
db: GetDatabaseResponse,
|
||||||
|
propName: string,
|
||||||
|
typeOptions: readonly string[]
|
||||||
|
) {
|
||||||
|
function diff(list1: readonly string[], list2: readonly string[]): string[] {
|
||||||
|
const set = new Set(list1);
|
||||||
|
list2.forEach((item) => set.delete(item));
|
||||||
|
return [...set];
|
||||||
|
}
|
||||||
|
const dbPropOptions = propOptions(db.properties[propName]);
|
||||||
|
const notInType = diff(dbPropOptions, typeOptions);
|
||||||
|
const notInDb = diff(typeOptions, dbPropOptions);
|
||||||
|
|
||||||
|
if (notInType.length > 0) {
|
||||||
|
console.warn(
|
||||||
|
`Options for DB Property ${propName} not in Type Options: ${notInType}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notInDb.length > 0) {
|
||||||
|
console.warn(`Type Options not in for DB Property ${propName}: ${notInDb}`);
|
||||||
|
}
|
||||||
|
function propOptions(
|
||||||
|
prop: GetDatabaseResponse["properties"][string]
|
||||||
|
): string[] {
|
||||||
|
if (prop.type === "select") {
|
||||||
|
return prop.select.options.map((o) => o.name);
|
||||||
|
} else if (prop.type === "status") {
|
||||||
|
return prop.status.options.map((o) => o.name);
|
||||||
|
} else if (prop.type === "multi_select") {
|
||||||
|
return prop.multi_select.options.map((o) => o.name);
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import { Client, isFullPage } from "@notionhq/client";
|
import { Client, isFullPage } from "@notionhq/client";
|
||||||
import { PageObjectResponse } from "@notionhq/client/build/src/api-endpoints";
|
import { PageObjectResponse } from "@notionhq/client/build/src/api-endpoints";
|
||||||
import { ContexteEntreeDC } from "../../data/ContexteEntreeDC";
|
import {
|
||||||
|
ContexteEntreeDC,
|
||||||
|
contexteEntreeDCs,
|
||||||
|
} from "../../data/ContexteEntreeDC";
|
||||||
import { EvenementFamille } from "../../data/EvenementFamille";
|
import { EvenementFamille } from "../../data/EvenementFamille";
|
||||||
import { Famille } from "../../data/Famille";
|
import { Famille } from "../../data/Famille";
|
||||||
import { StatutFamille } from "../../data/StatutFamille";
|
import { StatutFamille, statutsFamille } from "../../data/StatutFamille";
|
||||||
import { TypeEvenement } from "../../data/TypeEvenement";
|
import { TypeEvenement, typesEvenements } from "../../data/TypeEvenement";
|
||||||
import { datePropertyToDate } from "../utils/properties/datePropertyToDate";
|
import { datePropertyToDate } from "../utils/properties/datePropertyToDate";
|
||||||
import { relationPropertyToPageId } from "../utils/properties/relationPropertyToPageId";
|
import { relationPropertyToPageId } from "../utils/properties/relationPropertyToPageId";
|
||||||
import { selectPropertyToText } from "../utils/properties/selectPropertyToText";
|
import { selectPropertyToText } from "../utils/properties/selectPropertyToText";
|
||||||
|
|
@ -12,6 +15,9 @@ import { statusPropertyToText } from "../utils/properties/statusPropertyToText";
|
||||||
import { titlePropertyToText } from "../utils/properties/titlePropertyToText";
|
import { titlePropertyToText } from "../utils/properties/titlePropertyToText";
|
||||||
import { queryAllDbResults } from "../utils/queryAllDbResults";
|
import { queryAllDbResults } from "../utils/queryAllDbResults";
|
||||||
import { richTextPropertyToPlainText } from "../utils/text/richTextPropertyToPlainText";
|
import { richTextPropertyToPlainText } from "../utils/text/richTextPropertyToPlainText";
|
||||||
|
import { checkDbPropertyOptionsMatchesType } from "./checkDbPropertyOptionsMatchesType";
|
||||||
|
|
||||||
|
const contexteEntreeDCPropName = "Contexte d’entrée DC";
|
||||||
|
|
||||||
export async function fetchFamiliesWithEventsFromNotion(
|
export async function fetchFamiliesWithEventsFromNotion(
|
||||||
notionClient: Client
|
notionClient: Client
|
||||||
|
|
@ -19,14 +25,25 @@ export async function fetchFamiliesWithEventsFromNotion(
|
||||||
const familiesDbId: string = "5b69e02b296d4a578f8c8ab7fe8b05da";
|
const familiesDbId: string = "5b69e02b296d4a578f8c8ab7fe8b05da";
|
||||||
const familEventsDbId: string = "c4d434b4603c4481a4d445618ecdf999";
|
const familEventsDbId: string = "c4d434b4603c4481a4d445618ecdf999";
|
||||||
|
|
||||||
|
const familyDb = await notionClient.databases.retrieve({
|
||||||
|
database_id: familiesDbId,
|
||||||
|
});
|
||||||
|
checkDbPropertyOptionsMatchesType(familyDb, "Statut", statutsFamille);
|
||||||
|
checkDbPropertyOptionsMatchesType(
|
||||||
|
familyDb,
|
||||||
|
contexteEntreeDCPropName,
|
||||||
|
contexteEntreeDCs
|
||||||
|
);
|
||||||
|
|
||||||
|
const eventsDb = await notionClient.databases.retrieve({
|
||||||
|
database_id: familEventsDbId,
|
||||||
|
});
|
||||||
|
checkDbPropertyOptionsMatchesType(eventsDb, "Type", typesEvenements);
|
||||||
|
|
||||||
const eventPages = (
|
const eventPages = (
|
||||||
await queryAllDbResults(notionClient, {
|
await queryAllDbResults(notionClient, {
|
||||||
database_id: familEventsDbId,
|
database_id: familEventsDbId,
|
||||||
sorts: [
|
sorts: [{ property: "Date", direction: "ascending" }],
|
||||||
{property: "Date",
|
|
||||||
direction: "ascending"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
).filter(isFullPage);
|
).filter(isFullPage);
|
||||||
const familyPages = (
|
const familyPages = (
|
||||||
|
|
@ -45,7 +62,7 @@ export async function fetchFamiliesWithEventsFromNotion(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
// Fix to remove the empty "Famille de résistant" page that is often created by mistake
|
// Fix to remove the empty "Famille de résistant" page that is often created by mistake
|
||||||
const filtered = familles.filter(f => f.Titre !== "Famille de résistant");
|
const filtered = familles.filter((f) => f.Titre !== "Famille de résistant");
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +95,7 @@ function buildFamily(
|
||||||
Statut: statusPropertyToText(pageProperties, "Statut") as StatutFamille,
|
Statut: statusPropertyToText(pageProperties, "Statut") as StatutFamille,
|
||||||
ContexteEntree: selectPropertyToText(
|
ContexteEntree: selectPropertyToText(
|
||||||
pageProperties,
|
pageProperties,
|
||||||
"Contexte d’entrée DC"
|
contexteEntreeDCPropName
|
||||||
) as ContexteEntreeDC,
|
) as ContexteEntreeDC,
|
||||||
Integration: datePropertyToDate(pageProperties, "Intégration"),
|
Integration: datePropertyToDate(pageProperties, "Intégration"),
|
||||||
Sortie: datePropertyToDate(pageProperties, "Sortie"),
|
Sortie: datePropertyToDate(pageProperties, "Sortie"),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue