@tricoteuses/senat 3.1.18 → 3.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/config.d.ts +0 -22
- package/lib/src/config.js +7 -17
- package/lib/src/conversion_textes.js +1 -5
- package/lib/src/databases.d.ts +2 -0
- package/lib/src/databases.js +26 -0
- package/lib/src/datasets.d.ts +0 -4
- package/lib/src/datasets.js +2 -16
- package/lib/src/git.d.ts +0 -1
- package/lib/src/git.js +11 -45
- package/lib/src/loaders.d.ts +12 -12
- package/lib/src/loaders.js +8 -14
- package/lib/src/model/agenda.d.ts +1 -1
- package/lib/src/model/agenda.js +3 -3
- package/lib/src/model/ameli.d.ts +52 -64
- package/lib/src/model/ameli.js +145 -147
- package/lib/src/model/commission.d.ts +4 -5
- package/lib/src/model/commission.js +6 -6
- package/lib/src/model/debats.d.ts +66 -38
- package/lib/src/model/debats.js +93 -110
- package/lib/src/model/documents.d.ts +12 -32
- package/lib/src/model/documents.js +130 -171
- package/lib/src/model/dosleg.d.ts +5 -142
- package/lib/src/model/dosleg.js +156 -298
- package/lib/src/model/index.d.ts +7 -7
- package/lib/src/model/index.js +7 -7
- package/lib/src/model/questions.d.ts +45 -54
- package/lib/src/model/questions.js +87 -89
- package/lib/src/model/scrutins.d.ts +13 -48
- package/lib/src/model/scrutins.js +111 -118
- package/lib/src/model/seance.d.ts +1 -1
- package/lib/src/model/seance.js +7 -7
- package/lib/src/model/sens.d.ts +179 -109
- package/lib/src/model/sens.js +484 -384
- package/lib/src/model/util.d.ts +8 -0
- package/lib/src/model/util.js +23 -0
- package/lib/src/raw_types/ameli.d.ts +800 -1648
- package/lib/src/raw_types/ameli.js +5 -1074
- package/lib/src/raw_types/debats.d.ts +180 -353
- package/lib/src/raw_types/debats.js +5 -266
- package/lib/src/raw_types/dosleg.d.ts +1523 -2858
- package/lib/src/raw_types/dosleg.js +5 -2005
- package/lib/src/raw_types/questions.d.ts +395 -671
- package/lib/src/raw_types/questions.js +5 -493
- package/lib/src/raw_types/senat.d.ts +11372 -0
- package/lib/src/raw_types/senat.js +5 -0
- package/lib/src/raw_types/sens.d.ts +8148 -7743
- package/lib/src/raw_types/sens.js +5 -4691
- package/lib/src/raw_types_schemats/ameli.d.ts +2 -4
- package/lib/src/raw_types_schemats/debats.d.ts +2 -2
- package/lib/src/raw_types_schemats/dosleg.d.ts +2 -2
- package/lib/src/raw_types_schemats/questions.d.ts +2 -2
- package/lib/src/raw_types_schemats/sens.d.ts +4235 -29
- package/lib/src/scripts/retrieve_videos.js +5 -1
- package/lib/src/scripts/test_iter_load.d.ts +1 -0
- package/lib/src/scripts/test_iter_load.js +12 -0
- package/lib/src/types/ameli.d.ts +4 -4
- package/lib/src/types/dosleg.d.ts +39 -39
- package/lib/src/types/questions.d.ts +2 -2
- package/lib/src/types/sens.d.ts +2 -0
- package/lib/src/types/texte.d.ts +2 -2
- package/lib/src/utils/reunion_odj_building.js +27 -11
- package/package.json +1 -1
- package/lib/src/databases_postgres.d.ts +0 -4
- package/lib/src/databases_postgres.js +0 -23
- package/lib/src/scripts/debug_dosleg_query.d.ts +0 -6
- package/lib/src/scripts/debug_dosleg_query.js +0 -50
|
@@ -42,7 +42,11 @@ function shouldSkipDownload(agenda, baseDir) {
|
|
|
42
42
|
const cutoff = now - options["only-recent"] * 24 * 3600 * 1000;
|
|
43
43
|
const reunionTs = Date.parse(agenda.date);
|
|
44
44
|
if (reunionTs >= cutoff)
|
|
45
|
-
return false;
|
|
45
|
+
return false; // recent: always try
|
|
46
|
+
// Old meeting with no captation: will never match (minAccept=0.9), skip
|
|
47
|
+
if (!agenda.captationVideo)
|
|
48
|
+
return true;
|
|
49
|
+
// Old meeting with captation: skip only if already downloaded
|
|
46
50
|
const dataNvsPath = path.join(baseDir, "data.nvs");
|
|
47
51
|
const finalplayerNvsPath = path.join(baseDir, "finalplayer.nvs");
|
|
48
52
|
return fs.existsSync(dataNvsPath) && fs.existsSync(finalplayerNvsPath);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { iterLoadSenatTextes, } from "../loaders";
|
|
2
|
+
import commandLineArgs from "command-line-args";
|
|
3
|
+
import { dataDirDefaultOption } from "./shared/cli_helpers";
|
|
4
|
+
const optionsDefinitions = [dataDirDefaultOption];
|
|
5
|
+
const options = commandLineArgs(optionsDefinitions);
|
|
6
|
+
const session = 2025;
|
|
7
|
+
const sinceCommit = undefined;
|
|
8
|
+
for (const { item: texte } of iterLoadSenatTextes(options["dataDir"], session, {
|
|
9
|
+
sinceCommit: sinceCommit,
|
|
10
|
+
})) {
|
|
11
|
+
console.log(texte);
|
|
12
|
+
}
|
package/lib/src/types/ameli.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export interface
|
|
4
|
-
subids?:
|
|
1
|
+
import { ses as Ses, sub as Sub, subFields, txt_ameli } from "../raw_types_schemats/ameli";
|
|
2
|
+
export type { Ses, Sub };
|
|
3
|
+
export interface TxtAmeli extends txt_ameli {
|
|
4
|
+
subids?: subFields.id[];
|
|
5
5
|
}
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export type {
|
|
6
|
-
export interface Aud extends
|
|
1
|
+
import { txt_ameliFields } from "../raw_types_schemats/ameli";
|
|
2
|
+
import { ass as Ass, aud, audFields, auteur, date_seance, date_seanceFields as dateSeanceFields, deccoc as DecCoc, denrap as DenRap, docatt, docattFields, ecr, ecrFields, etaloi as EtaLoi, lecass, lecassFields, lecassrap, lecture, lectureFields, loi, org as Org, oritxt as OriTxt, qua as Qua, rap, raporg as RapOrg, raporgFields, scr as Scr, texte, texteFields, typatt as TypAtt, typlec as TypLec, typloi as TypLoi, typtxt as TypTxt, typurl as TypUrl, typurlFields } from "../raw_types_schemats/dosleg";
|
|
3
|
+
import { Debat } from "./debats";
|
|
4
|
+
import { TxtAmeli } from "./ameli";
|
|
5
|
+
export type { Ass, DecCoc, DenRap, EtaLoi, Org, OriTxt, Qua, RapOrg, Scr, TypAtt, TypLec, TypLoi, TypTxt, TypUrl };
|
|
6
|
+
export interface Aud extends aud {
|
|
7
7
|
org?: Org;
|
|
8
8
|
}
|
|
9
|
-
export interface Auteur extends
|
|
9
|
+
export interface Auteur extends auteur {
|
|
10
10
|
qua?: Qua;
|
|
11
11
|
}
|
|
12
|
-
export interface DateSeance extends
|
|
13
|
-
debat?:
|
|
12
|
+
export interface DateSeance extends date_seance {
|
|
13
|
+
debat?: Debat;
|
|
14
14
|
scrids?: string[];
|
|
15
15
|
scrs?: Scr[];
|
|
16
16
|
}
|
|
17
|
-
export interface DocAtt extends
|
|
18
|
-
rap?:
|
|
19
|
-
typatt?:
|
|
17
|
+
export interface DocAtt extends docatt {
|
|
18
|
+
rap?: Rap;
|
|
19
|
+
typatt?: TypAtt;
|
|
20
20
|
}
|
|
21
|
-
export interface Ecr extends
|
|
21
|
+
export interface Ecr extends ecr {
|
|
22
22
|
aut?: Auteur;
|
|
23
23
|
}
|
|
24
|
-
export interface LecAss extends
|
|
24
|
+
export interface LecAss extends lecass {
|
|
25
25
|
ass?: Ass;
|
|
26
26
|
auds?: Aud[];
|
|
27
|
-
audcles?:
|
|
27
|
+
audcles?: audFields.audcle[];
|
|
28
28
|
datesSeances?: DateSeance[];
|
|
29
|
-
datesSeancesCodes?:
|
|
29
|
+
datesSeancesCodes?: dateSeanceFields.code[];
|
|
30
30
|
debatdatseas: Date[];
|
|
31
31
|
lecassraps?: LecAssRap[];
|
|
32
32
|
lecassrapids?: string[];
|
|
33
33
|
org?: Org;
|
|
34
|
-
texcods:
|
|
34
|
+
texcods: texteFields.texcod[];
|
|
35
35
|
textes?: Texte[];
|
|
36
36
|
}
|
|
37
|
-
export interface LecAssRap extends
|
|
38
|
-
rap?:
|
|
37
|
+
export interface LecAssRap extends lecassrap {
|
|
38
|
+
rap?: Rap;
|
|
39
39
|
}
|
|
40
|
-
export interface Lecture extends
|
|
41
|
-
typlec?:
|
|
42
|
-
lecassidts?:
|
|
40
|
+
export interface Lecture extends lecture {
|
|
41
|
+
typlec?: TypLec;
|
|
42
|
+
lecassidts?: lecassFields.lecassidt[];
|
|
43
43
|
lecasss?: LecAss[];
|
|
44
44
|
}
|
|
45
|
-
export interface Loi extends
|
|
46
|
-
deccoc?:
|
|
47
|
-
etaloi?:
|
|
48
|
-
lecidts?:
|
|
45
|
+
export interface Loi extends loi {
|
|
46
|
+
deccoc?: DecCoc;
|
|
47
|
+
etaloi?: EtaLoi;
|
|
48
|
+
lecidts?: lectureFields.lecidt[];
|
|
49
49
|
lectures?: Lecture[];
|
|
50
|
-
typloi?:
|
|
50
|
+
typloi?: TypLoi;
|
|
51
51
|
}
|
|
52
|
-
export interface Rap extends
|
|
53
|
-
denrap?:
|
|
54
|
-
docattcles?:
|
|
52
|
+
export interface Rap extends rap {
|
|
53
|
+
denrap?: DenRap;
|
|
54
|
+
docattcles?: docattFields.docattcle[];
|
|
55
55
|
docatts?: DocAtt[];
|
|
56
|
-
ecrnums?:
|
|
56
|
+
ecrnums?: ecrFields.ecrnum[];
|
|
57
57
|
ecrs?: Ecr[];
|
|
58
|
-
orgcods?:
|
|
58
|
+
orgcods?: raporgFields.orgcod[];
|
|
59
59
|
orgs?: Org[];
|
|
60
60
|
}
|
|
61
|
-
export interface Texte extends
|
|
61
|
+
export interface Texte extends texte {
|
|
62
62
|
ecrs?: Ecr[];
|
|
63
|
-
ecrnums?:
|
|
64
|
-
libtypurl?:
|
|
63
|
+
ecrnums?: ecrFields.ecrnum[];
|
|
64
|
+
libtypurl?: typurlFields.libtypurl;
|
|
65
65
|
org?: Org;
|
|
66
|
-
oritxt:
|
|
67
|
-
typtxt?:
|
|
68
|
-
txtAmeli?:
|
|
69
|
-
txtAmeliId:
|
|
66
|
+
oritxt: OriTxt;
|
|
67
|
+
typtxt?: TypTxt;
|
|
68
|
+
txtAmeli?: TxtAmeli;
|
|
69
|
+
txtAmeliId: txt_ameliFields.id;
|
|
70
70
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type {
|
|
1
|
+
import { tam_questions as Question } from "../raw_types_schemats/questions";
|
|
2
|
+
export type { Question };
|
package/lib/src/types/sens.d.ts
CHANGED
package/lib/src/types/texte.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentResult } from "../loaders
|
|
1
|
+
import { DocumentResult } from "../loaders";
|
|
2
2
|
export declare enum DivisionType {
|
|
3
3
|
tome = 1,
|
|
4
4
|
part = 2,
|
|
@@ -23,7 +23,7 @@ export interface DocumentMetadata {
|
|
|
23
23
|
url_html: URL;
|
|
24
24
|
url_pdf: URL;
|
|
25
25
|
}
|
|
26
|
-
export interface FlatTexte extends
|
|
26
|
+
export interface FlatTexte extends DocumentResult {
|
|
27
27
|
titre: string | null;
|
|
28
28
|
titre_court: string | null;
|
|
29
29
|
url_dossier_senat: string | null;
|
|
@@ -14,16 +14,32 @@ function buildReunionLookupKey(date, organe) {
|
|
|
14
14
|
const o = normalizeOrganeForMatch(organe || "");
|
|
15
15
|
return `${d}|${o}`;
|
|
16
16
|
}
|
|
17
|
+
function organeWordOverlap(a, b) {
|
|
18
|
+
const wordsA = new Set(a.split(/\s+/).filter((w) => w.length >= 5));
|
|
19
|
+
const wordsB = new Set(b.split(/\s+/).filter((w) => w.length >= 5));
|
|
20
|
+
if (wordsA.size === 0 || wordsB.size === 0)
|
|
21
|
+
return 0;
|
|
22
|
+
let overlap = 0;
|
|
23
|
+
for (const w of wordsA) {
|
|
24
|
+
if (wordsB.has(w))
|
|
25
|
+
overlap++;
|
|
26
|
+
}
|
|
27
|
+
return overlap / Math.min(wordsA.size, wordsB.size);
|
|
28
|
+
}
|
|
17
29
|
export function buildOdj(events, dossierBySenatUrl, doslegReunionIndex) {
|
|
18
30
|
const byObjet = new Map();
|
|
19
31
|
let lastCodeEtape = null;
|
|
20
32
|
let lastFlatActes;
|
|
21
33
|
for (const ev of events) {
|
|
22
34
|
const objetKey = (ev.objet ?? "").trim();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
// Prefer the dosleg reunion index (source officielle, dosleg_aud) over the URL scraped
|
|
36
|
+
// from the agenda HTML, which can contain wrong links (senat.fr bug).
|
|
37
|
+
let dossier = doslegReunionIndex
|
|
38
|
+
? lookupDossierFromDoslegReunion(ev, doslegReunionIndex)
|
|
39
|
+
: null;
|
|
40
|
+
if (!dossier) {
|
|
41
|
+
const url = normalizeSenatUrl(ev.urlDossierSenat) ?? undefined;
|
|
42
|
+
dossier = url ? (dossierBySenatUrl[url] ?? null) : null;
|
|
27
43
|
}
|
|
28
44
|
const dossierUid = dossier ? pickDossierUid(dossier) : undefined;
|
|
29
45
|
if (dossier) {
|
|
@@ -59,7 +75,9 @@ function scoreCandidate(c, evText) {
|
|
|
59
75
|
if (evText.includes(dosSignet))
|
|
60
76
|
score += 10;
|
|
61
77
|
if (c.reunionTitre) {
|
|
62
|
-
const reunionWords = normalizeOrganeForMatch(c.reunionTitre)
|
|
78
|
+
const reunionWords = normalizeOrganeForMatch(c.reunionTitre)
|
|
79
|
+
.split(/\s+/)
|
|
80
|
+
.filter((w) => w.length >= 5);
|
|
63
81
|
score += reunionWords.filter((w) => evText.includes(w)).length;
|
|
64
82
|
}
|
|
65
83
|
const dossierTitre = normalizeOrganeForMatch(c.dossier.titre ?? "");
|
|
@@ -91,7 +109,9 @@ function lookupDossierFromDoslegReunion(ev, index) {
|
|
|
91
109
|
for (const [k, v] of index) {
|
|
92
110
|
if (k.startsWith(evDate + "|") && k !== key) {
|
|
93
111
|
const kOrgane = k.split("|")[1] || "";
|
|
94
|
-
if (evOrgane &&
|
|
112
|
+
if (evOrgane &&
|
|
113
|
+
kOrgane &&
|
|
114
|
+
(evOrgane.includes(kOrgane) || kOrgane.includes(evOrgane) || organeWordOverlap(evOrgane, kOrgane) >= 0.6)) {
|
|
95
115
|
dateOnlyCandidates.push(...v);
|
|
96
116
|
}
|
|
97
117
|
}
|
|
@@ -191,11 +211,7 @@ function computeCodeEtape(ev, dossier, flatActes) {
|
|
|
191
211
|
const cleanCode = (code) => code.replace(/-SEANCE$/, "");
|
|
192
212
|
const lecture = detectLecture(ev.objet ?? "");
|
|
193
213
|
const organeLower = (ev.organe ?? "").toLowerCase();
|
|
194
|
-
const nature = organeLower.includes("commission")
|
|
195
|
-
? "COM"
|
|
196
|
-
: organeLower.includes("séance publique")
|
|
197
|
-
? "DEBATS"
|
|
198
|
-
: "";
|
|
214
|
+
const nature = organeLower.includes("commission") ? "COM" : organeLower.includes("séance publique") ? "DEBATS" : "";
|
|
199
215
|
const evDate = ev.date.split("T")[0];
|
|
200
216
|
const flat = flatActes ?? buildFlatActes(dossier);
|
|
201
217
|
// 1) Strict matching: same date + same nature
|
package/package.json
CHANGED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import postgres from "postgres";
|
|
2
|
-
export type SqlValue = postgres.ParameterOrJSON<never>;
|
|
3
|
-
export declare const sql: postgres.Sql<{}>;
|
|
4
|
-
export declare function streamUnsafeQuery<T>(query: string, params?: readonly unknown[], batchSize?: number): AsyncGenerator<T, void, unknown>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import postgres from "postgres";
|
|
2
|
-
import config from "./config.js";
|
|
3
|
-
export const sql = postgres({
|
|
4
|
-
database: config.db.name,
|
|
5
|
-
host: config.db.host,
|
|
6
|
-
password: config.db.password,
|
|
7
|
-
port: config.db.port,
|
|
8
|
-
transform: {
|
|
9
|
-
undefined: null,
|
|
10
|
-
},
|
|
11
|
-
user: config.db.user,
|
|
12
|
-
});
|
|
13
|
-
function toSqlValue(value) {
|
|
14
|
-
return value;
|
|
15
|
-
}
|
|
16
|
-
export async function* streamUnsafeQuery(query, params = [], batchSize = 100) {
|
|
17
|
-
const values = params.map(toSqlValue);
|
|
18
|
-
for await (const rows of sql.unsafe(query, values).cursor(batchSize)) {
|
|
19
|
-
for (const row of rows) {
|
|
20
|
-
yield row;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Debug script to check the DosLeg query compilation
|
|
4
|
-
* Helps identify the "column undefined" error
|
|
5
|
-
*/
|
|
6
|
-
import { db } from "../server/databases_postgres.js";
|
|
7
|
-
import { jsonArrayFrom } from "kysely/helpers/postgres";
|
|
8
|
-
import { sql } from "kysely";
|
|
9
|
-
async function debugDoslegQuery() {
|
|
10
|
-
console.log("=== Debugging DosLeg Query ===\n");
|
|
11
|
-
try {
|
|
12
|
-
// Build the same query as findAllDossiers but capture SQL
|
|
13
|
-
const query = db
|
|
14
|
-
.withSchema("senat")
|
|
15
|
-
.selectFrom("dosleg_loi as loi")
|
|
16
|
-
.leftJoin("dosleg_typloi as typloi", "typloi.typloicod", "loi.typloicod")
|
|
17
|
-
.leftJoin("dosleg_etaloi as etaloi", "etaloi.etaloicod", "loi.etaloicod")
|
|
18
|
-
.leftJoin("dosleg_deccoc as deccoc", "deccoc.deccoccod", "loi.deccoccod")
|
|
19
|
-
.select((eb) => [
|
|
20
|
-
sql `rtrim(${eb.ref("loi.loicod")})`.as("code"),
|
|
21
|
-
"loi.numero as numero",
|
|
22
|
-
"loi.signet as signet",
|
|
23
|
-
]);
|
|
24
|
-
const compiled = query.compile();
|
|
25
|
-
console.log("✓ Query compiled successfully (basic columns)\n");
|
|
26
|
-
console.log("SQL:", compiled.sql);
|
|
27
|
-
console.log("\n");
|
|
28
|
-
// Try with simple lectures first
|
|
29
|
-
const queryWithLectures = db
|
|
30
|
-
.withSchema("senat")
|
|
31
|
-
.selectFrom("dosleg_loi as loi")
|
|
32
|
-
.select((eb) => [
|
|
33
|
-
"loi.signet as signet",
|
|
34
|
-
jsonArrayFrom(eb.withSchema("senat").selectFrom("dosleg_lecture as lecture").select(["lecture.lecidt as id"])).as("lectures"),
|
|
35
|
-
]);
|
|
36
|
-
const compiledWithLectures = queryWithLectures.compile();
|
|
37
|
-
console.log("✓ Query with simple lectures compiled successfully\n");
|
|
38
|
-
console.log("SQL:", compiledWithLectures.sql);
|
|
39
|
-
console.log("\n");
|
|
40
|
-
console.log("✅ Basic query structures seem valid");
|
|
41
|
-
console.log("\nThe issue is likely in one of the nested subqueries with cross-references.");
|
|
42
|
-
console.log("Try running findAllDossiers with the verbose flag to see exactly where it fails.");
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error("❌ Error during query compilation:");
|
|
46
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
debugDoslegQuery().catch(console.error);
|