Generate git repository of a consolidated law as it applies on a given date and no more as it is published

This commit is contained in:
Emmanuel 2024-12-18 00:23:46 +01:00
parent fb4f36ae81
commit 648fc3d0f4

View file

@ -38,26 +38,29 @@ type Action = "CREATE" | "DELETE"
interface Context { interface Context {
articleById: Record<string, JorfArticle | LegiArticle> articleById: Record<string, JorfArticle | LegiArticle>
consolidatedIdsByActionByModifyingTextIdByDate: Record<
string,
Record<string, Partial<Record<Action, Set<string>>>>
>
consolidatedTextCid: string consolidatedTextCid: string
consolidatedTextInternalIds: Set<string> consolidatedTextInternalIds: Set<string>
consolidatedTextModifyingTextsIdsByActionByPublicationDate: Record< // consolidatedTextModifyingTextsIdsByActionByPublicationDate: Record<
string, // string,
Partial<Record<Action, Set<string>>> // Partial<Record<Action, Set<string>>>
> // >
// Current content of a text at a given date // Current content of a text at a given date
currentInternalIds: Set<string> currentInternalIds: Set<string>
idsByActionByTexteMoficateurId: Record< hasModifyingTextIdByActionByConsolidatedId: Record<
string, string,
Partial<Record<Action, Set<string>>> Partial<Record<Action, boolean>>
> >
// When a LEGI article, sectionTa or text has been created by the same JORF // When a LEGI article, sectionTa or text has been created by the same JORF
// article, sectionIa or text, ID of this JORF object // article, sectionIa or text, ID of this JORF object
jorfCreatorIdById: Record<string, string> jorfCreatorIdByConsolidatedId: Record<string, string>
modifyingArticleIdByActionById: Record< modifyingArticleIdByActionById: Record<
string, string,
Partial<Record<Action, string>> Partial<Record<Action, string>>
> >
modifyingTextIdByActionById: Record<string, Partial<Record<Action, string>>>
sectionTaById: Record<string, LegiSectionTa> sectionTaById: Record<string, LegiSectionTa>
targetDir: string targetDir: string
texteManquantById: Record<string, TexteManquant> texteManquantById: Record<string, TexteManquant>
@ -253,26 +256,26 @@ async function addModifyingArticleId(
`Article modificateur ${modifyingArticleId} of ${modifiedId} has no CONTEXTE.TEXTE["@date_publi"]`, `Article modificateur ${modifyingArticleId} of ${modifiedId} has no CONTEXTE.TEXTE["@date_publi"]`,
) )
} }
if ( // if (
action === "CREATE" && // action === "CREATE" &&
modifyingArticlePublicationDate !== "2999-01-01" && // modifyingArticlePublicationDate !== "2999-01-01" &&
modifyingArticlePublicationDate > modifiedDateDebut // modifyingArticlePublicationDate > modifiedDateDebut
) { // ) {
console.warn( // console.warn(
`Ignoring article créateur ${modifyingArticleId} because its publication date ${modifyingArticlePublicationDate} doesn't match start date ${modifiedDateDebut} of ${modifiedId}`, // `Ignoring article créateur ${modifyingArticleId} because its publication date ${modifyingArticlePublicationDate} doesn't match start date ${modifiedDateDebut} of ${modifiedId}`,
) // )
return // return
} // }
if ( // if (
action === "DELETE" && // action === "DELETE" &&
modifyingArticlePublicationDate !== "2999-01-01" && // modifyingArticlePublicationDate !== "2999-01-01" &&
modifyingArticlePublicationDate > modifiedDateFin // modifyingArticlePublicationDate > modifiedDateFin
) { // ) {
console.warn( // console.warn(
`Ignoring article suppresseur ${modifyingArticleId} because its publication date ${modifyingArticlePublicationDate} doesn't match end date ${modifiedDateFin} of ${modifiedId}`, // `Ignoring article suppresseur ${modifyingArticleId} because its publication date ${modifyingArticlePublicationDate} doesn't match end date ${modifiedDateFin} of ${modifiedId}`,
) // )
return // return
} // }
if (modifiedId.startsWith("LEGITEXT")) { if (modifiedId.startsWith("LEGITEXT")) {
// A consolidated text doesn't change. Only its content changes. // A consolidated text doesn't change. Only its content changes.
@ -335,63 +338,33 @@ async function addModifyingTextId(
if (modifiedId.startsWith("JORFTEXT") || modifiedId.startsWith("LEGITEXT")) { if (modifiedId.startsWith("JORFTEXT") || modifiedId.startsWith("LEGITEXT")) {
// A consolidated text doesn't change. Only its content changes. // A consolidated text doesn't change. Only its content changes.
const publicationDate = // const publicationDate =
modifyingTexteVersion.META.META_SPEC.META_TEXTE_CHRONICLE.DATE_PUBLI // modifyingTexteVersion.META.META_SPEC.META_TEXTE_CHRONICLE.DATE_PUBLI
const consolidatedTextModifyingTextsIdsByAction = // const consolidatedTextModifyingTextsIdsByAction =
(context.consolidatedTextModifyingTextsIdsByActionByPublicationDate[ // (context.consolidatedTextModifyingTextsIdsByActionByPublicationDate[
publicationDate // publicationDate
] ??= {}) // ] ??= {})
const consolidatedTextModifyingTextsIds = // const consolidatedTextModifyingTextsIds =
(consolidatedTextModifyingTextsIdsByAction[action] ??= new Set()) // (consolidatedTextModifyingTextsIdsByAction[action] ??= new Set())
consolidatedTextModifyingTextsIds.add(modifyingTextId) // consolidatedTextModifyingTextsIds.add(modifyingTextId)
// ;(context.hasModifyingTextIdByActionByConsolidatedId[modifiedId] ??= {})[
// action
// ] = true
} else { } else {
if ( // Modified object is an article.
action === "CREATE" && if (action === "CREATE" && modifiedDateDebut !== "2999-01-01") {
modifyingTextPublicationDate !== "2999-01-01" && ;(((context.consolidatedIdsByActionByModifyingTextIdByDate[
modifyingTextPublicationDate > modifiedDateDebut modifiedDateDebut
) { ] ??= {})[modifyingTextId] ??= {}).CREATE ??= new Set()).add(modifiedId)
console.warn( ;(context.hasModifyingTextIdByActionByConsolidatedId[modifiedId] ??=
`Ignoring creating text ${modifyingTextId} because its publication date ${modifyingTextPublicationDate} doesn't match start date ${modifiedDateDebut} of ${modifiedId}`, {}).CREATE = true
)
return
} }
if ( if (action === "DELETE" && modifiedDateFin !== "2999-01-01") {
action === "DELETE" && ;(((context.consolidatedIdsByActionByModifyingTextIdByDate[
modifyingTextPublicationDate !== "2999-01-01" && modifiedDateFin
modifyingTextPublicationDate > modifiedDateFin ] ??= {})[modifyingTextId] ??= {}).DELETE ??= new Set()).add(modifiedId)
) { ;(context.hasModifyingTextIdByActionByConsolidatedId[modifiedId] ??=
console.warn( {}).DELETE = true
`Ignoring texte suppresseur ${modifyingTextId} because its publication date ${modifyingTextPublicationDate} doesn't match end date ${modifiedDateFin} of ${modifiedId}`,
)
return
}
const modifyingTextIdByAction = (context.modifyingTextIdByActionById[
modifiedId
] ??= {})
const existingModifyingTextId = modifyingTextIdByAction[action]
if (
existingModifyingTextId === undefined ||
context.texteManquantById[existingModifyingTextId] !== undefined
) {
modifyingTextIdByAction[action] = modifyingTextId
;((context.idsByActionByTexteMoficateurId[modifyingTextId] ??= {})[
action
] ??= new Set()).add(modifiedId)
} else if (existingModifyingTextId !== modifyingTextId) {
const existingModifyingTexteVersion = (await getOrLoadTexteVersion(
context,
existingModifyingTextId,
))!
if (
existingModifyingTexteVersion.META.META_SPEC.META_TEXTE_CHRONICLE
.DATE_PUBLI! < modifyingTextPublicationDate
) {
modifyingTextIdByAction[action] = modifyingTextId
;((context.idsByActionByTexteMoficateurId[modifyingTextId] ??= {})[
action
] ??= new Set()).add(modifiedId)
}
} }
} }
} }
@ -408,20 +381,21 @@ async function cleanHtmlFragment(
}, },
) )
} }
async function exportConsolidatedTextToGit( async function exportConsolidatedTextToGit(
consolidatedTextId: string, consolidatedTextId: string,
targetDir: string, targetDir: string,
): Promise<void> { ): Promise<void> {
const context: Context = { const context: Context = {
articleById: {}, articleById: {},
consolidatedIdsByActionByModifyingTextIdByDate: {},
consolidatedTextCid: consolidatedTextId, // Temporary value, overrided below consolidatedTextCid: consolidatedTextId, // Temporary value, overrided below
consolidatedTextInternalIds: new Set([consolidatedTextId]), consolidatedTextInternalIds: new Set([consolidatedTextId]),
consolidatedTextModifyingTextsIdsByActionByPublicationDate: {}, // consolidatedTextModifyingTextsIdsByActionByPublicationDate: {},
currentInternalIds: new Set(), currentInternalIds: new Set(),
idsByActionByTexteMoficateurId: {}, hasModifyingTextIdByActionByConsolidatedId: {},
jorfCreatorIdById: {}, jorfCreatorIdByConsolidatedId: {},
modifyingArticleIdByActionById: {}, modifyingArticleIdByActionById: {},
modifyingTextIdByActionById: {},
sectionTaById: {}, sectionTaById: {},
targetDir, targetDir,
textelrById: {}, textelrById: {},
@ -439,7 +413,8 @@ async function exportConsolidatedTextToGit(
)) as LegiTexteVersion )) as LegiTexteVersion
assert.notStrictEqual(consolidatedTexteVersion, null) assert.notStrictEqual(consolidatedTexteVersion, null)
const meta = consolidatedTexteVersion.META const meta = consolidatedTexteVersion.META
context.consolidatedTextCid = meta.META_SPEC.META_TEXTE_CHRONICLE.CID const metaTexteChronicle = meta.META_SPEC.META_TEXTE_CHRONICLE
context.consolidatedTextCid = metaTexteChronicle.CID
// It seems that the CID of a LEGI text is the ID of the original JORF text // It seems that the CID of a LEGI text is the ID of the original JORF text
// that created the first version of the law. // that created the first version of the law.
// Most texts of LOI nature (except 191 / 3533) have a JORFTEXT CID. // Most texts of LOI nature (except 191 / 3533) have a JORFTEXT CID.
@ -450,7 +425,8 @@ async function exportConsolidatedTextToGit(
// is not created from a single JORF law. // is not created from a single JORF law.
const jorfCreatorArticleIdByNum: Record<string, string> = {} const jorfCreatorArticleIdByNum: Record<string, string> = {}
if (context.consolidatedTextCid.startsWith("JORFTEXT")) { if (context.consolidatedTextCid.startsWith("JORFTEXT")) {
context.jorfCreatorIdById[consolidatedTextId] = context.consolidatedTextCid context.jorfCreatorIdByConsolidatedId[consolidatedTextId] =
context.consolidatedTextCid
// Map JORF articles by their number, to be able to associate them with the LEGI article that they // Map JORF articles by their number, to be able to associate them with the LEGI article that they
// create. // create.
@ -505,13 +481,18 @@ async function exportConsolidatedTextToGit(
const liensArticles = consolidatedTextelrStructure?.LIEN_ART const liensArticles = consolidatedTextelrStructure?.LIEN_ART
if (liensArticles !== undefined) { if (liensArticles !== undefined) {
for (const lienArticle of liensArticles) { for (const lienArticle of liensArticles) {
context.consolidatedTextInternalIds.add(lienArticle["@id"]) const articleId = lienArticle["@id"]
context.consolidatedTextInternalIds.add(articleId)
if (lienArticle["@num"] !== undefined) { if (
lienArticle["@debut"] === metaTexteChronicle.DATE_PUBLI &&
lienArticle["@num"] !== undefined
) {
const jorfCreatorArticleId = const jorfCreatorArticleId =
jorfCreatorArticleIdByNum[lienArticle["@num"]] jorfCreatorArticleIdByNum[lienArticle["@num"]]
if (jorfCreatorArticleId !== undefined) { if (jorfCreatorArticleId !== undefined) {
context.jorfCreatorIdById[lienArticle["@id"]] = jorfCreatorArticleId context.jorfCreatorIdByConsolidatedId[articleId] =
jorfCreatorArticleId
} }
} }
} }
@ -524,13 +505,18 @@ async function exportConsolidatedTextToGit(
const liensArticles = sectionTa?.STRUCTURE_TA?.LIEN_ART const liensArticles = sectionTa?.STRUCTURE_TA?.LIEN_ART
if (liensArticles !== undefined) { if (liensArticles !== undefined) {
for (const lienArticle of liensArticles) { for (const lienArticle of liensArticles) {
context.consolidatedTextInternalIds.add(lienArticle["@id"]) const articleId = lienArticle["@id"]
context.consolidatedTextInternalIds.add(articleId)
if (lienArticle["@num"] !== undefined) { if (
lienArticle["@debut"] === metaTexteChronicle.DATE_PUBLI &&
lienArticle["@num"] !== undefined
) {
const jorfCreatorArticleId = const jorfCreatorArticleId =
jorfCreatorArticleIdByNum[lienArticle["@num"]] jorfCreatorArticleIdByNum[lienArticle["@num"]]
if (jorfCreatorArticleId !== undefined) { if (jorfCreatorArticleId !== undefined) {
context.jorfCreatorIdById[lienArticle["@id"]] = jorfCreatorArticleId context.jorfCreatorIdByConsolidatedId[articleId] =
jorfCreatorArticleId
} }
} }
} }
@ -582,44 +568,44 @@ async function exportConsolidatedTextToGit(
} }
} }
// Sort textes modificateurs by date // // Sort textes modificateurs by date
const modifyingTextsIds = new Set<string>() // const modifyingTextsIds = new Set<string>()
for (const modifyingTextIdByAction of Object.values( // for (const modifyingTextIdByAction of Object.values(
context.modifyingTextIdByActionById, // context.modifyingTextIdByActionById,
)) { // )) {
if (modifyingTextIdByAction.CREATE !== undefined) { // if (modifyingTextIdByAction.CREATE !== undefined) {
modifyingTextsIds.add(modifyingTextIdByAction.CREATE) // modifyingTextsIds.add(modifyingTextIdByAction.CREATE)
} // }
if (modifyingTextIdByAction.DELETE !== undefined) { // if (modifyingTextIdByAction.DELETE !== undefined) {
modifyingTextsIds.add(modifyingTextIdByAction.DELETE) // modifyingTextsIds.add(modifyingTextIdByAction.DELETE)
} // }
} // }
const modifyingTextsIdByPublicationDate: Record<string, string[]> = {} // const modifyingTextsIdByPublicationDate: Record<string, string[]> = {}
for (const modifyingTextId of modifyingTextsIds) { // for (const modifyingTextId of modifyingTextsIds) {
let modifyingTexteVersion: // let modifyingTexteVersion:
| JorfTexteVersion // | JorfTexteVersion
| LegiTexteVersion // | LegiTexteVersion
| TexteManquant = context.texteManquantById[ // | TexteManquant = context.texteManquantById[
modifyingTextId // modifyingTextId
] as TexteManquant // ] as TexteManquant
let publicationDate: string // let publicationDate: string
if (modifyingTexteVersion === undefined) { // if (modifyingTexteVersion === undefined) {
modifyingTexteVersion = (await getOrLoadTexteVersion( // modifyingTexteVersion = (await getOrLoadTexteVersion(
context, // context,
modifyingTextId, // modifyingTextId,
)) as JorfTexteVersion | LegiTexteVersion // )) as JorfTexteVersion | LegiTexteVersion
publicationDate = // publicationDate =
modifyingTexteVersion.META.META_SPEC.META_TEXTE_CHRONICLE.DATE_PUBLI // modifyingTexteVersion.META.META_SPEC.META_TEXTE_CHRONICLE.DATE_PUBLI
} else { // } else {
publicationDate = modifyingTexteVersion.publicationDate // publicationDate = modifyingTexteVersion.publicationDate
} // }
const modifyingTextsId = (modifyingTextsIdByPublicationDate[ // const modifyingTextsId = (modifyingTextsIdByPublicationDate[
publicationDate // publicationDate
] ??= []) // ] ??= [])
modifyingTextsId.push(modifyingTextId) // modifyingTextsId.push(modifyingTextId)
} // }
// Generation of Git repository // Generation of Git repository
@ -734,48 +720,86 @@ async function exportConsolidatedTextToGit(
message: "Création du dépôt Git", message: "Création du dépôt Git",
}) })
for (const [publicationDate, modifyingTextsId] of Object.entries( for (const [date, consolidatedIdsByActionByModifyingTextId] of Object.entries(
modifyingTextsIdByPublicationDate, context.consolidatedIdsByActionByModifyingTextIdByDate,
).toSorted(([date1], [date2]) => date1.localeCompare(date2))) { ).toSorted(([date1], [date2]) => date1.localeCompare(date2))) {
console.log(publicationDate) console.log(date)
for (const modifyingTextId of modifyingTextsId.toSorted()) { let timestamp = Math.floor(new Date(date).getTime() / 1000)
// Generate tree of SectionTa & articles at this date if (timestamp < minDateTimestamp) {
const t0 = performance.now() const diffDays = Math.round((minDateTimestamp - timestamp) / oneDay)
timestamp = minDateTimestamp - diffDays
}
const timezoneOffset = 0
const modifyingTexteVersionArray: Array<
JorfTexteVersion | LegiTexteVersion | TexteManquant
> = []
for (const modifyingTextId of Object.keys(
consolidatedIdsByActionByModifyingTextId,
)) {
let modifyingTexteVersion: let modifyingTexteVersion:
| JorfTexteVersion | JorfTexteVersion
| LegiTexteVersion | LegiTexteVersion
| TexteManquant = context.texteManquantById[ | TexteManquant = context.texteManquantById[
modifyingTextId modifyingTextId
] as TexteManquant ] as TexteManquant
let modifyingTextTitle: string
if (modifyingTexteVersion === undefined) { if (modifyingTexteVersion === undefined) {
modifyingTexteVersion = (await getOrLoadTexteVersion( modifyingTexteVersion = (await getOrLoadTexteVersion(
context, context,
modifyingTextId, modifyingTextId,
)) as JorfTexteVersion | LegiTexteVersion )) as JorfTexteVersion | LegiTexteVersion
assert.notStrictEqual(modifyingTexteVersion, null) assert.notStrictEqual(modifyingTexteVersion, null)
}
modifyingTexteVersionArray.push(modifyingTexteVersion)
}
modifyingTexteVersionArray.sort(
(modifyingTexteVersion1, modifyingTexteVersion2) => {
const publicationDate1 =
(modifyingTexteVersion1 as TexteManquant).publicationDate ??
(modifyingTexteVersion1 as JorfTexteVersion | LegiTexteVersion).META
.META_SPEC.META_TEXTE_CHRONICLE.DATE_PUBLI
const publicationDate2 =
(modifyingTexteVersion2 as TexteManquant).publicationDate ??
(modifyingTexteVersion2 as JorfTexteVersion | LegiTexteVersion).META
.META_SPEC.META_TEXTE_CHRONICLE.DATE_PUBLI
return publicationDate1.localeCompare(publicationDate2)
},
)
for (const modifyingTexteVersion of modifyingTexteVersionArray) {
const t0 = performance.now()
let modifyingTextId: string
let modifyingTextTitle: string
if (
(modifyingTexteVersion as TexteManquant).publicationDate === undefined
) {
modifyingTextId = (
modifyingTexteVersion as JorfTexteVersion | LegiTexteVersion
).META.META_COMMUN.ID
modifyingTextTitle = ( modifyingTextTitle = (
modifyingTexteVersion.META.META_SPEC.META_TEXTE_VERSION.TITREFULL ?? (modifyingTexteVersion as JorfTexteVersion | LegiTexteVersion).META
modifyingTexteVersion.META.META_SPEC.META_TEXTE_VERSION.TITRE ?? .META_SPEC.META_TEXTE_VERSION.TITREFULL ??
modifyingTexteVersion.META.META_COMMUN.ID (modifyingTexteVersion as JorfTexteVersion | LegiTexteVersion).META
.META_SPEC.META_TEXTE_VERSION.TITRE ??
modifyingTextId
) )
.replace(/\s+/g, " ") .replace(/\s+/g, " ")
.trim() .trim()
.replace(/\s+\(\d+\)$/, "") .replace(/\s+\(\d+\)$/, "")
} else { } else {
modifyingTextTitle = `!!! Texte non trouvé ${publicationDate} !!!` modifyingTextId = "ZZZZ TEXTE MANQUANT"
modifyingTextTitle = `!!! Texte non trouvé ${date} !!!`
} }
console.log(` ${modifyingTextId} ${modifyingTextTitle}`) console.log(` ${modifyingTextId} ${modifyingTextTitle}`)
const idsByAction = const consolidatedIdsByAction =
context.idsByActionByTexteMoficateurId[modifyingTextId] consolidatedIdsByActionByModifyingTextId[modifyingTextId]
if (idsByAction.DELETE !== undefined) { if (consolidatedIdsByAction.DELETE !== undefined) {
console.log( console.log(
` DELETE: ${[...idsByAction.DELETE].toSorted().join(", ")}`, ` DELETE: ${[...consolidatedIdsByAction.DELETE].toSorted().join(", ")}`,
) )
} }
if (idsByAction.CREATE !== undefined) { if (consolidatedIdsByAction.CREATE !== undefined) {
console.log( console.log(
` CREATE: ${[...idsByAction.CREATE].toSorted().join(", ")}`, ` CREATE: ${[...consolidatedIdsByAction.CREATE].toSorted().join(", ")}`,
) )
} }
@ -786,16 +810,14 @@ async function exportConsolidatedTextToGit(
for (const action of ["DELETE", "CREATE"] as Action[]) { for (const action of ["DELETE", "CREATE"] as Action[]) {
for (const lienArticle of liensArticles) { for (const lienArticle of liensArticles) {
const articleId = lienArticle["@id"] const articleId = lienArticle["@id"]
const modifyingTextIdByAction =
context.modifyingTextIdByActionById[articleId]
if (context.currentInternalIds.has(articleId)) { if (context.currentInternalIds.has(articleId)) {
if (modifyingTextIdByAction.DELETE === modifyingTextId) { if (consolidatedIdsByAction.DELETE?.has(articleId)) {
if (action === "DELETE") { if (action === "DELETE") {
context.currentInternalIds.delete(articleId) context.currentInternalIds.delete(articleId)
} }
continue continue
} }
} else if (modifyingTextIdByAction.CREATE === modifyingTextId) { } else if (consolidatedIdsByAction.CREATE?.has(articleId)) {
if (action === "CREATE") { if (action === "CREATE") {
context.currentInternalIds.add(articleId) context.currentInternalIds.add(articleId)
} }
@ -808,7 +830,7 @@ async function exportConsolidatedTextToGit(
await addArticleToTree( await addArticleToTree(
context, context,
tree, tree,
publicationDate, date,
encounteredArticlesIds, encounteredArticlesIds,
lienArticle, lienArticle,
) )
@ -824,16 +846,14 @@ async function exportConsolidatedTextToGit(
for (const action of ["DELETE", "CREATE"] as Action[]) { for (const action of ["DELETE", "CREATE"] as Action[]) {
for (const lienArticle of liensArticles) { for (const lienArticle of liensArticles) {
const articleId = lienArticle["@id"] const articleId = lienArticle["@id"]
const modifyingTextIdByAction =
context.modifyingTextIdByActionById[articleId]
if (context.currentInternalIds.has(articleId)) { if (context.currentInternalIds.has(articleId)) {
if (modifyingTextIdByAction.DELETE === modifyingTextId) { if (consolidatedIdsByAction.DELETE?.has(articleId)) {
if (action === "DELETE") { if (action === "DELETE") {
context.currentInternalIds.delete(articleId) context.currentInternalIds.delete(articleId)
} }
continue continue
} }
} else if (modifyingTextIdByAction.CREATE === modifyingTextId) { } else if (consolidatedIdsByAction.CREATE?.has(articleId)) {
if (action === "CREATE") { if (action === "CREATE") {
context.currentInternalIds.add(articleId) context.currentInternalIds.add(articleId)
} }
@ -846,7 +866,7 @@ async function exportConsolidatedTextToGit(
await addArticleToTree( await addArticleToTree(
context, context,
tree, tree,
publicationDate, date,
encounteredArticlesIds, encounteredArticlesIds,
lienArticle, lienArticle,
) )
@ -946,14 +966,6 @@ async function exportConsolidatedTextToGit(
.map(([key, value]) => `${key}: ${value}`) .map(([key, value]) => `${key}: ${value}`)
.join("\n") .join("\n")
} }
let timestamp = Math.floor(new Date(publicationDate).getTime() / 1000)
if (timestamp < minDateTimestamp) {
const diffDays = Math.round(
Math.abs((minDateTimestamp - timestamp) / oneDay),
)
timestamp = minDateTimestamp - diffDays
}
const timezoneOffset = 0
await git.commit({ await git.commit({
dir: targetDir, dir: targetDir,
fs, fs,
@ -1389,15 +1401,44 @@ async function registerLegiArticleModifiers(
article: LegiArticle, article: LegiArticle,
): Promise<void> { ): Promise<void> {
const articleId = article.META.META_COMMUN.ID const articleId = article.META.META_COMMUN.ID
const articleIds = [articleId, context.jorfCreatorIdById[articleId]].filter( if (articleId === "LEGIARTI000049255019") debugger
(id) => id !== undefined, const articleIds = [
) articleId,
context.jorfCreatorIdByConsolidatedId[articleId],
].filter((id) => id !== undefined)
const articleDateDebut = article.META.META_SPEC.META_ARTICLE.DATE_DEBUT const articleDateDebut = article.META.META_SPEC.META_ARTICLE.DATE_DEBUT
const articleDateFin = article.META.META_SPEC.META_ARTICLE.DATE_FIN const articleDateFin = article.META.META_SPEC.META_ARTICLE.DATE_FIN
console.log( console.log(
`${lienArticle["@id"]} ${" ".repeat(depth)}Article ${lienArticle["@num"]} (${lienArticle["@debut"]}${lienArticle["@fin"] === "2999-01-01" ? "…" : lienArticle["@fin"]}, ${lienArticle["@etat"]})`, `${lienArticle["@id"]} ${" ".repeat(depth)}Article ${lienArticle["@num"]} (${lienArticle["@debut"]}${lienArticle["@fin"] === "2999-01-01" ? "…" : lienArticle["@fin"]}, ${lienArticle["@etat"]})`,
) )
// if (jorfCreatorId !== undefined) {
// await addModifyingArticleId(
// context,
// jorfCreatorId,
// "CREATE",
// articleId,
// articleDateDebut,
// articleDateFin,
// )
// // Delete another version of the same article that existed before the newly created one.
// for (const articleVersion of article.VERSIONS.VERSION) {
// if (articleVersion.LIEN_ART["@id"] === articleId) {
// continue
// }
// if (articleVersion.LIEN_ART["@fin"] === articleDateDebut) {
// await addModifyingArticleId(
// context,
// jorfCreatorId,
// "DELETE",
// articleVersion.LIEN_ART["@id"],
// articleVersion.LIEN_ART["@debut"],
// articleVersion.LIEN_ART["@fin"],
// )
// }
// }
// }
for (const articleLien of await db<ArticleLienDb[]>` for (const articleLien of await db<ArticleLienDb[]>`
SELECT * FROM article_lien WHERE id IN ${db(articleIds)} SELECT * FROM article_lien WHERE id IN ${db(articleIds)}
`) { `) {
@ -1574,7 +1615,7 @@ async function registerLegiArticleModifiers(
} }
const articleLiens = article.LIENS?.LIEN const articleLiens = article.LIENS?.LIEN
// Note: The (eventual) JORF version of article (with ID === context.jorfCreatorIdById[articleId]]) never has LIENS. // Note: The (eventual) JORF version of article (with ID === context.jorfCreatorIdByConsolidatedId[articleId]]) never has LIENS.
// => It is skipped. // => It is skipped.
if (articleLiens !== undefined) { if (articleLiens !== undefined) {
for (const articleLien of articleLiens) { for (const articleLien of articleLiens) {
@ -1723,82 +1764,92 @@ async function registerLegiArticleModifiers(
) )
} }
} }
} else { // } else {
// If article belongs directly to a text published in JORF but at a later date than the JORF text, // // If article belongs directly to a text published in JORF but at a later date than the JORF text,
// then if article has no creating text, consider that it has been created by a modifying text having the same start // // then if article has no creating text, consider that it has been created by a modifying text having the same start
// date as the article when such a text exists. // // date as the article when such a text exists.
const modifyingTextIdByAction = (context.modifyingTextIdByActionById[ // const hasModifyingTextIdByAction = (context.hasModifyingTextIdByActionByConsolidatedId[
articleId // articleId
] ??= {}) // ] ??= {})
if (modifyingTextIdByAction.CREATE === undefined) { // if (!hasModifyingTextIdByAction.CREATE) {
const consolidatedTextModifyingTextsIds = // const consolidatedTextModifyingTextsIds =
context.consolidatedTextModifyingTextsIdsByActionByPublicationDate[ // context.consolidatedTextModifyingTextsIdsByActionByPublicationDate[
articleDateDebut // articleDateDebut
]?.CREATE // ]?.CREATE
if (consolidatedTextModifyingTextsIds !== undefined) { // if (consolidatedTextModifyingTextsIds !== undefined) {
if (consolidatedTextModifyingTextsIds.size === 1) { // if (consolidatedTextModifyingTextsIds.size === 1) {
const modifyingTextId = [...consolidatedTextModifyingTextsIds][0] // const modifyingTextId = [...consolidatedTextModifyingTextsIds][0]
await addModifyingTextId( // await addModifyingTextId(
context, // context,
modifyingTextId, // modifyingTextId,
"CREATE", // "CREATE",
articleId, // articleId,
articleDateDebut, // articleDateDebut,
articleDateFin, // articleDateFin,
) // )
// Delete another version of the same article that existed before the newly created one. // // Delete another version of the same article that existed before the newly created one.
for (const articleVersion of article.VERSIONS.VERSION) { // for (const articleVersion of article.VERSIONS.VERSION) {
if (articleVersion.LIEN_ART["@id"] === articleId) { // if (articleVersion.LIEN_ART["@id"] === articleId) {
continue // continue
} // }
if (articleVersion.LIEN_ART["@fin"] === articleDateDebut) { // if (articleVersion.LIEN_ART["@fin"] === articleDateDebut) {
await addModifyingTextId( // await addModifyingTextId(
context, // context,
modifyingTextId, // modifyingTextId,
"DELETE", // "DELETE",
articleVersion.LIEN_ART["@id"], // articleVersion.LIEN_ART["@id"],
articleVersion.LIEN_ART["@debut"], // articleVersion.LIEN_ART["@debut"],
articleVersion.LIEN_ART["@fin"], // articleVersion.LIEN_ART["@fin"],
) // )
} // }
} // }
} else { // } else {
console.log( // console.log(
`Can't attach modifying article ${articleId} to a modifying text`, // `Can't attach modifying article ${articleId} to a modifying text`,
`because there are several possibilities at the date ${articleDateDebut}:`, // `because there are several possibilities at the date ${articleDateDebut}:`,
`${[...consolidatedTextModifyingTextsIds].join(", ")}`, // `${[...consolidatedTextModifyingTextsIds].join(", ")}`,
) // )
} // }
} // }
} // }
} }
} }
// If article still has no creating text at all, then create a fake one. // If article still has no creating text at all, then create a fake one.
const modifyingTextIdByAction = (context.modifyingTextIdByActionById[ const hasModifyingTextIdByAction =
articleId (context.hasModifyingTextIdByActionByConsolidatedId[articleId] ??= {})
] ??= {}) if (!hasModifyingTextIdByAction.CREATE && articleDateDebut !== "2999-01-01") {
if (modifyingTextIdByAction.CREATE === undefined) { const texteManquantId = "ZZZZ TEXTE MANQUANT"
const texteManquantId = `ZZZZ TEXTE MANQUANT ${articleDateDebut}` if (
context.texteManquantById[texteManquantId] ??= { context.consolidatedIdsByActionByModifyingTextIdByDate[
publicationDate: articleDateDebut, articleDateDebut
]?.[texteManquantId] === undefined
) {
context.texteManquantById[texteManquantId] ??= {
publicationDate: articleDateDebut,
}
} }
modifyingTextIdByAction.CREATE = texteManquantId hasModifyingTextIdByAction.CREATE = true
;((context.idsByActionByTexteMoficateurId[texteManquantId] ??= ;(((context.consolidatedIdsByActionByModifyingTextIdByDate[
{}).CREATE ??= new Set()).add(articleId) articleDateDebut
] ??= {})[texteManquantId] ??= {}).CREATE ??= new Set()).add(articleId)
// Delete another version of the same article that existed before the newly created one. // Delete another version of the same article that existed before the newly created one.
for (const articleVersion of article.VERSIONS.VERSION) { for (const articleVersion of article.VERSIONS.VERSION) {
if (articleVersion.LIEN_ART["@id"] === articleId) { if (articleVersion.LIEN_ART["@id"] === articleId) {
continue continue
} }
if (articleVersion.LIEN_ART["@fin"] === articleDateDebut) { if (articleVersion.LIEN_ART["@fin"] === articleDateDebut) {
const modifyingTextIdByAction = (context.modifyingTextIdByActionById[ const hasModifyingTextIdByAction =
articleVersion.LIEN_ART["@id"] (context.hasModifyingTextIdByActionByConsolidatedId[
] ??= {}) articleVersion.LIEN_ART["@id"]
if (modifyingTextIdByAction.DELETE === undefined) { ] ??= {})
modifyingTextIdByAction.DELETE = texteManquantId if (!hasModifyingTextIdByAction.DELETE) {
;((context.idsByActionByTexteMoficateurId[texteManquantId] ??= hasModifyingTextIdByAction.DELETE = true
{}).DELETE ??= new Set()).add(articleVersion.LIEN_ART["@id"]) ;(((context.consolidatedIdsByActionByModifyingTextIdByDate[
articleVersion.LIEN_ART["@fin"]
] ??= {})[texteManquantId] ??= {}).DELETE ??= new Set()).add(
articleVersion.LIEN_ART["@id"],
)
} }
} }
} }
@ -1812,9 +1863,10 @@ async function registerLegiTextModifiers(
texteVersion: LegiTexteVersion, texteVersion: LegiTexteVersion,
): Promise<void> { ): Promise<void> {
const legiTextId = texteVersion.META.META_COMMUN.ID const legiTextId = texteVersion.META.META_COMMUN.ID
const textIds = [legiTextId, context.jorfCreatorIdById[legiTextId]].filter( const textIds = [
(id) => id !== undefined, legiTextId,
) context.jorfCreatorIdByConsolidatedId[legiTextId],
].filter((id) => id !== undefined)
const texteVersionMeta = texteVersion.META const texteVersionMeta = texteVersion.META
const texteVersionDateDebut = const texteVersionDateDebut =
texteVersionMeta.META_SPEC.META_TEXTE_VERSION.DATE_DEBUT texteVersionMeta.META_SPEC.META_TEXTE_VERSION.DATE_DEBUT