@tricoteuses/senat 3.1.18 → 3.1.19

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.
Files changed (65) hide show
  1. package/lib/src/config.d.ts +0 -22
  2. package/lib/src/config.js +7 -17
  3. package/lib/src/conversion_textes.js +1 -5
  4. package/lib/src/databases.d.ts +2 -0
  5. package/lib/src/databases.js +26 -0
  6. package/lib/src/datasets.d.ts +0 -4
  7. package/lib/src/datasets.js +2 -16
  8. package/lib/src/git.d.ts +0 -1
  9. package/lib/src/git.js +11 -45
  10. package/lib/src/loaders.d.ts +12 -12
  11. package/lib/src/loaders.js +8 -14
  12. package/lib/src/model/agenda.d.ts +1 -1
  13. package/lib/src/model/agenda.js +3 -3
  14. package/lib/src/model/ameli.d.ts +52 -64
  15. package/lib/src/model/ameli.js +145 -147
  16. package/lib/src/model/commission.d.ts +4 -5
  17. package/lib/src/model/commission.js +6 -6
  18. package/lib/src/model/debats.d.ts +66 -38
  19. package/lib/src/model/debats.js +93 -110
  20. package/lib/src/model/documents.d.ts +12 -32
  21. package/lib/src/model/documents.js +130 -171
  22. package/lib/src/model/dosleg.d.ts +5 -142
  23. package/lib/src/model/dosleg.js +156 -298
  24. package/lib/src/model/index.d.ts +7 -7
  25. package/lib/src/model/index.js +7 -7
  26. package/lib/src/model/questions.d.ts +45 -54
  27. package/lib/src/model/questions.js +87 -89
  28. package/lib/src/model/scrutins.d.ts +13 -48
  29. package/lib/src/model/scrutins.js +111 -118
  30. package/lib/src/model/seance.d.ts +1 -1
  31. package/lib/src/model/seance.js +7 -7
  32. package/lib/src/model/sens.d.ts +179 -109
  33. package/lib/src/model/sens.js +484 -384
  34. package/lib/src/model/util.d.ts +8 -0
  35. package/lib/src/model/util.js +23 -0
  36. package/lib/src/raw_types/ameli.d.ts +800 -1648
  37. package/lib/src/raw_types/ameli.js +5 -1074
  38. package/lib/src/raw_types/debats.d.ts +180 -353
  39. package/lib/src/raw_types/debats.js +5 -266
  40. package/lib/src/raw_types/dosleg.d.ts +1523 -2858
  41. package/lib/src/raw_types/dosleg.js +5 -2005
  42. package/lib/src/raw_types/questions.d.ts +395 -671
  43. package/lib/src/raw_types/questions.js +5 -493
  44. package/lib/src/raw_types/senat.d.ts +11372 -0
  45. package/lib/src/raw_types/senat.js +5 -0
  46. package/lib/src/raw_types/sens.d.ts +8148 -7743
  47. package/lib/src/raw_types/sens.js +5 -4691
  48. package/lib/src/raw_types_schemats/ameli.d.ts +2 -4
  49. package/lib/src/raw_types_schemats/debats.d.ts +2 -2
  50. package/lib/src/raw_types_schemats/dosleg.d.ts +2 -2
  51. package/lib/src/raw_types_schemats/questions.d.ts +2 -2
  52. package/lib/src/raw_types_schemats/sens.d.ts +4235 -29
  53. package/lib/src/scripts/test_iter_load.d.ts +1 -0
  54. package/lib/src/scripts/test_iter_load.js +12 -0
  55. package/lib/src/types/ameli.d.ts +4 -4
  56. package/lib/src/types/dosleg.d.ts +39 -39
  57. package/lib/src/types/questions.d.ts +2 -2
  58. package/lib/src/types/sens.d.ts +2 -0
  59. package/lib/src/types/texte.d.ts +2 -2
  60. package/lib/src/utils/reunion_odj_building.js +27 -11
  61. package/package.json +1 -1
  62. package/lib/src/databases_postgres.d.ts +0 -4
  63. package/lib/src/databases_postgres.js +0 -23
  64. package/lib/src/scripts/debug_dosleg_query.d.ts +0 -6
  65. package/lib/src/scripts/debug_dosleg_query.js +0 -50
@@ -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
+ }
@@ -1,5 +1,5 @@
1
- import { TxtAmeli } from "../raw_types/ameli.js";
2
- import { Sub } from "../raw_types/ameli.js";
3
- export interface TxtAmeliCustom extends TxtAmeli {
4
- subids?: Sub["id"][];
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 { Ass, Aud as AudRaw, Auteur as AuteurRaw, DateSeance as DateSeanceRaw, Deccoc, Denrap, Docatt as DocattRaw, Ecr as EcrRaw, Etaloi, Lecass as LecassRaw, Lecassrap as LecassrapRaw, Lecture as LectureRaw, Loi as LoiRaw, Org, Oritxt, Qua, Rap as RapRaw, Raporg, Scr, Texte as TexteRaw, Typatt, Typlec, Typloi, Typtxt, Typurl } from "../raw_types/dosleg.js";
2
- import { TxtAmeli } from "../raw_types/ameli.js";
3
- import { Debats } from "../raw_types/debats.js";
4
- import { TxtAmeliCustom } from "./ameli.js";
5
- export type { Deccoc as DecCoc, Denrap as DenRap, Etaloi as EtaLoi, Oritxt as OriTxt, Raporg as RapOrg, Typatt as TypAtt, Typlec as TypLec, Typloi as TypLoi, Typtxt as TypTxt, Typurl as TypUrl, };
6
- export interface Aud extends AudRaw {
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 AuteurRaw {
9
+ export interface Auteur extends auteur {
10
10
  qua?: Qua;
11
11
  }
12
- export interface DateSeance extends DateSeanceRaw {
13
- debat?: Debats;
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 DocattRaw {
18
- rap?: RapRaw;
19
- typatt?: Typatt;
17
+ export interface DocAtt extends docatt {
18
+ rap?: Rap;
19
+ typatt?: TypAtt;
20
20
  }
21
- export interface Ecr extends EcrRaw {
21
+ export interface Ecr extends ecr {
22
22
  aut?: Auteur;
23
23
  }
24
- export interface LecAss extends LecassRaw {
24
+ export interface LecAss extends lecass {
25
25
  ass?: Ass;
26
26
  auds?: Aud[];
27
- audcles?: AudRaw["audcle"][];
27
+ audcles?: audFields.audcle[];
28
28
  datesSeances?: DateSeance[];
29
- datesSeancesCodes?: DateSeanceRaw["code"][];
29
+ datesSeancesCodes?: dateSeanceFields.code[];
30
30
  debatdatseas: Date[];
31
31
  lecassraps?: LecAssRap[];
32
32
  lecassrapids?: string[];
33
33
  org?: Org;
34
- texcods: TexteRaw["texcod"][];
34
+ texcods: texteFields.texcod[];
35
35
  textes?: Texte[];
36
36
  }
37
- export interface LecAssRap extends LecassrapRaw {
38
- rap?: RapRaw;
37
+ export interface LecAssRap extends lecassrap {
38
+ rap?: Rap;
39
39
  }
40
- export interface Lecture extends LectureRaw {
41
- typlec?: Typlec;
42
- lecassidts?: LecassRaw["lecassidt"][];
40
+ export interface Lecture extends lecture {
41
+ typlec?: TypLec;
42
+ lecassidts?: lecassFields.lecassidt[];
43
43
  lecasss?: LecAss[];
44
44
  }
45
- export interface Loi extends LoiRaw {
46
- deccoc?: Deccoc;
47
- etaloi?: Etaloi;
48
- lecidts?: LectureRaw["lecidt"][];
45
+ export interface Loi extends loi {
46
+ deccoc?: DecCoc;
47
+ etaloi?: EtaLoi;
48
+ lecidts?: lectureFields.lecidt[];
49
49
  lectures?: Lecture[];
50
- typloi?: Typloi;
50
+ typloi?: TypLoi;
51
51
  }
52
- export interface Rap extends RapRaw {
53
- denrap?: Denrap;
54
- docattcles?: DocattRaw["docattcle"][];
52
+ export interface Rap extends rap {
53
+ denrap?: DenRap;
54
+ docattcles?: docattFields.docattcle[];
55
55
  docatts?: DocAtt[];
56
- ecrnums?: EcrRaw["ecrnum"][];
56
+ ecrnums?: ecrFields.ecrnum[];
57
57
  ecrs?: Ecr[];
58
- orgcods?: Raporg["orgcod"][];
58
+ orgcods?: raporgFields.orgcod[];
59
59
  orgs?: Org[];
60
60
  }
61
- export interface Texte extends TexteRaw {
61
+ export interface Texte extends texte {
62
62
  ecrs?: Ecr[];
63
- ecrnums?: EcrRaw["ecrnum"][];
64
- libtypurl?: Typurl["libtypurl"];
63
+ ecrnums?: ecrFields.ecrnum[];
64
+ libtypurl?: typurlFields.libtypurl;
65
65
  org?: Org;
66
- oritxt: Oritxt;
67
- typtxt?: Typtxt;
68
- txtAmeli?: TxtAmeliCustom;
69
- txtAmeliId: TxtAmeli["id"];
66
+ oritxt: OriTxt;
67
+ typtxt?: TypTxt;
68
+ txtAmeli?: TxtAmeli;
69
+ txtAmeliId: txt_ameliFields.id;
70
70
  }
@@ -1,2 +1,2 @@
1
- import { TamQuestions } from "../raw_types/questions.js";
2
- export type { TamQuestions as Question };
1
+ import { tam_questions as Question } from "../raw_types_schemats/questions";
2
+ export type { Question };
@@ -1,3 +1,5 @@
1
+ import { sen as Sen } from "../raw_types_schemats/sens";
2
+ export type { Sen };
1
3
  export interface Photo {
2
4
  chemin: string;
3
5
  cheminMosaique: string;
@@ -1,4 +1,4 @@
1
- import { DocumentResult } from "../loaders.js";
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 Partial<DocumentResult> {
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
- const url = normalizeSenatUrl(ev.urlDossierSenat) ?? undefined;
24
- let dossier = url ? (dossierBySenatUrl[url] ?? null) : null;
25
- if (!dossier && doslegReunionIndex) {
26
- dossier = lookupDossierFromDoslegReunion(ev, doslegReunionIndex);
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).split(/\s+/).filter((w) => w.length >= 5);
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 && kOrgane && (evOrgane.includes(kOrgane) || kOrgane.includes(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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tricoteuses/senat",
3
- "version": "3.1.18",
3
+ "version": "3.1.19",
4
4
  "description": "Handle French Sénat's open data",
5
5
  "keywords": [
6
6
  "France",
@@ -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,6 +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
- export {};
@@ -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);