You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: LOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,7 @@
2
2
3
3
## 2026-07-11
4
4
5
+
- **feat geografia di nascita normalizzata — provincia, nazione, regione su entrambe le camere** (#24/#23, branch `feat/birth-geography-province-region`). Corretto un **assunto sbagliato** (era anche nel codice e nel wiki): il Senato **non** espone "solo la città". Ri-verificato con `COUNT` su tutta la leg.19 (254 senatori): `osr:cittaNascita` 254/254, `osr:provinciaNascita` 250/254 (i 4 mancanti sono i nati all'estero), `osr:nazioneNascita` 254/254 (`Italia` o stato estero). `senators list` ora restituisce `birth_province`, `birth_country`, `birth_region`. **Regione derivata** una volta sola in `src/core/province-region.ts` (modulo TS bundle-safe) da SITUAS/ISTAT report 64 via CLI `opensituas`, date-accurate (union snapshot 2010 + 2020 + più recente per le province soppresse/rinominate, + 3 alias per le forme brevi del Senato): copertura 100% (0 province non risolte). **Camera** (`deputies list`): la geografia è solo uno slug nell'URI (`comune_provincia_regione`), non triple — ora decodificata in `birth_city`/`birth_province`/`birth_country`/`birth_region` con disambiguazione dello slug a 2 parti (Valle d'Aosta / Trentino-Alto Adige `comune_regione` vs estero `comune_stato`) e `birth_region` portata alla **stessa** forma canonica del Senato (verificato: "Veneto" identico tra camere). `birth_province`/`birth_country` restano nella forma nativa di ciascuna fonte (nessun canonicalizzatore province cross-camera). Wiki `dati-anagrafici.md`/`index.md` corretti; nota ai gestori Camera (geografia non strutturata) in `docs/note-gestori-lod/`. +10 test unitari (risorsa provincia→regione + parser slug Camera), 158/158 verdi.
5
6
-**follow-up residuale commenti PR #56/#57 (`bill-progress`)**: migliorato l'hint del ramo Camera su risultato vuoto (ora segnala che i filtri `keyword`/intervallo di date o la paginazione `limit`/`offset` possono escludere tutte le righe), ordinamento timeline Camera reso stabile per paginazione con `?st` come tie-breaker in `ORDER BY` (non proiettato in `SELECT DISTINCT`, che ne altererebbe il dedup), escape robusto dei literal SPARQL per `keyword` (Senato + Camera) con helper dedicato che escapa solo `\ " newline CR` per la grammatica STRING_LITERAL2 (non `JSON.stringify`, che emette `\uXXXX` per i controlli, rifiutato da alcuni parser), e descrizioni `dateFrom/dateTo` chiarite sui due significati (presentazione Senato vs data stato-iter Camera).
6
7
-**CI PR stabilizzata su due livelli**: il check richiesto `ci` ora esegue solo build + typecheck + test deterministici (esclude `src/tools/tools.test.ts` e `src/tools/sparql.test.ts` dipendenti da endpoint live). Aggiunto job `live_integration` su PR con `continue-on-error` per mantenere visibilità sui test reali Camera/Senato senza bloccare il merge per anti-bot/instabilità esterna.
7
8
-**follow-up commenti review su `bill-progress`**: nel ramo Camera (`number + branch=C`) ora vengono applicati anche i filtri input (`keyword`, `dateFrom/dateTo`, `limit`, `offset`) invece di essere ignorati nel return anticipato. Aggiunto `hint` dinamico specifico quando la timeline Camera è vuota (evita messaggi fuorvianti orientati al Senato) e rese neutrali rispetto all'entrypoint le `describe()` di `number`/`branch` (niente grafia `--flag`, testo valido sia per CLI sia MCP). Inclusi test su paginazione e hint del ramo C.
Copy file name to clipboardExpand all lines: docs/lod-wiki/dati-anagrafici.md
+31-7Lines changed: 31 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
Dati anagrafici dei parlamentari (nascita, genere, luogo)
2
2
3
-
Cosa espone il LOD su nascita, genere e luogo di un parlamentare, e le trappole per interrogarli in massa. Verificato il 2026-07-03 su Schlein (Camera, `308930`) e La Russa/altri (Senato, `senatore/1275`, `senatore/32`).
3
+
Cosa espone il LOD su nascita, genere e luogo di un parlamentare, e le trappole per interrogarli in massa. Verificato il 2026-07-03 su Schlein (Camera, `308930`) e La Russa/altri (Senato, `senatore/1275`, `senatore/32`); copertura geografica Senato ri-verificata il 2026-07-11 con `COUNT` sull'intera leg.19.
4
4
5
5
## Camera
6
6
@@ -17,7 +17,8 @@ Proprietà anagrafiche (sul nodo persona):
-`ocd:rif_luogo` = URI `luogo.rdf/{comune}_{provincia}_{regione}` (es. `catania_catania_sicilia`); per l'estero `{citta}_{stato}` (es. `lugano_svizzera`).
20
-
-**La gerarchia geografica È presente, dentro l'URI** (stringa composta): filtrabile per comune / provincia / regione via `STRENDS`/`CONTAINS`. NON sono entità RDF distinte (non esiste un nodo "Regione Sicilia"), ma per filtri e conteggi basta il pattern sulla stringa. Es.: donne nate in Sicilia = `FILTER(STRENDS(STR(?luogo),'_sicilia'))` → 10 deputate leg.19.
20
+
-**La gerarchia geografica È presente ma NON è strutturata**: vive solo dentro la stringa dell'URI, non come triple/entità RDF (non esiste `osr:provinciaNascita`/`nazioneNascita` come alla Camera, né un nodo "Regione Sicilia"). Filtrabile per comune / provincia / regione via `STRENDS`/`CONTAINS` sull'URI. Es.: donne nate in Sicilia = `FILTER(STRENDS(STR(?luogo),'_sicilia'))` → 10 deputate leg.19.
21
+
-**Trappole di parsing dell'URI** (chi decompone lo slug `comune_provincia_regione`): (1) le regioni mono/bi-provinciali (Valle d'Aosta, Trentino-Alto Adige) compaiono a **2 parti**`comune_regione`, identiche nella forma ai nati all'estero `comune_stato` → la 2ª parte va disambiguata contro l'elenco delle regioni note; (2) i nomi-provincia dello slug divergono dallo standard ISTAT (es. `reggio-emilia` vs "Reggio nell'Emilia", `pesaro-urbino` vs "Pesaro e Urbino") → la regione va letta dallo slug stesso (parte 3), non ri-derivata dalla provincia. Il fatto che la geografia non sia esposta come triple è un limite di modellazione **segnalato ai gestori Camera**.
21
22
-**Bio testuale**: `dc:description` (titolo di studio + carriera, testo libero non strutturato).
22
23
23
24
Trappola: **serve `DISTINCT`** — il doppio `rdf:type` genera righe duplicate.
@@ -30,11 +31,18 @@ Nodo unico `osr:Senatore`. La nascita è esposta in due forme ridondanti, entram
- Il tool `senators list` già restituisce `birth_date`, `birth_city`, `gender`, `election_region` per ogni senatore.
34
34
35
-
Trappola filtro legislatura: usare `?s osr:mandato ?m . ?m osr:legislatura ?leg . FILTER(?leg={n})`. **NON** funziona `?m osr:legislatura {n}` come triple diretto (il letterale tipizzato non matcha in quella posizione → risultato vuoto).
35
+
**Geografia di nascita — a differenza di quanto si credeva, il Senato la espone strutturata** (predicati diretti, non solo la città). Ri-verificato il 2026-07-11 con `COUNT(DISTINCT ?s)` sull'intera leg.19 (254 senatori):
36
+
37
+
| predicato | valore | copertura leg.19 |
38
+
|---|---|---|
39
+
|`osr:cittaNascita`| città nuda (`Rovigo`) | 254 / 254 |
40
+
|`osr:provinciaNascita`| provincia nuda (`Rovigo`, `Potenza`) | 250 / 254 |
41
+
|`osr:nazioneNascita`| nazione (`Italia`, o stato estero) | 254 / 254 |
36
42
37
-
Limite geografico: **il luogo di nascita è solo la città, senza provincia né regione.** Nessuna gerarchia. `osr:regioneElezione` esiste ma è la regione di **elezione**, non di nascita.
43
+
I 4 senza `provinciaNascita` sono i **nati all'estero**: hanno `nazioneNascita` ≠ `Italia` (es. Argentina, Libia, Canada, Regno Unito) e nessuna provincia. `nazioneNascita` è valorizzata anche per i nati in Italia (`Italia`), quindi è il campo giusto per distinguere italiani da nati all'estero. Il tool `senators list` restituisce `birth_city`, `birth_province`, `birth_country` e `birth_region` (quest'ultima derivata, vedi sotto). `osr:regioneElezione` esiste ma è la regione di **elezione**, non di nascita.
44
+
45
+
Trappola filtro legislatura: usare `?s osr:mandato ?m . ?m osr:legislatura ?leg . FILTER(?leg={n})`. **NON** funziona `?m osr:legislatura {n}` come triple diretto (il letterale tipizzato non matcha in quella posizione → risultato vuoto).
38
46
39
47
## Conseguenze per i filtri demografici
40
48
@@ -43,9 +51,25 @@ Limite geografico: **il luogo di nascita è solo la città, senza provincia né
| intervallo data di nascita | ✅ `bio:date``YYYYMMDD`| ✅ `osr:dataNascita``YYYY-MM-DD`|
45
53
| luogo nascita — città | ✅ (dall'URI luogo) | ✅ `osr:cittaNascita`|
46
-
| luogo nascita — provincia/regione | ✅ (nell'URI luogo) | ❌ solo città |
54
+
| luogo nascita — provincia | ✅ (nell'URI luogo, non strutturata) | ✅ `osr:provinciaNascita`|
55
+
| luogo nascita — nazione | ✅ (nell'URI luogo, per l'estero) | ✅ `osr:nazioneNascita`|
56
+
| luogo nascita — regione | ✅ (nell'URI luogo) | ⚙️ derivata da provincia (vedi sotto) |
47
57
48
58
Note operative:
49
59
-**Formati data diversi** (Camera `YYYYMMDD`, Senato `YYYY-MM-DD`): i filtri per intervallo vanno costruiti per-endpoint.
50
60
-**Valori genere diversi** (`female`/`male` vs `F`/`M`): normalizzare l'input utente prima del filtro.
51
-
-**"Nato/a in regione X"**: nativo su Camera; sul Senato serve un lookup esterno comune→provincia→regione (ISTAT) su `osr:cittaNascita` — motivo per cui conviene materializzare gli elenchi distinti in CSV e normalizzare lì la geografia.
61
+
-**"Nato/a in regione X"**: entrambe le camere lo permettono, ma per vie diverse. Camera: la regione è già nello slug dell'URI luogo (parte 3). Senato: la regione **non** è esposta, si deriva da `osr:provinciaNascita` con una tabella provincia→regione (vedi sotto). Le due camere convergono sulla **stessa** stringa-regione canonica (`birth_region`), così un dataset che unisce Camera+Senato può raggruppare per regione di nascita senza riconciliazioni.
62
+
-**Solo `birth_region` è unificata cross-camera.**`birth_city`, `birth_province` e `birth_country` restano nella forma **nativa** di ciascuna fonte e possono differire per grafia/maiuscole tra le due camere (es. nato all'estero: Senato `Argentina`, Camera `argentina`; provincia: Senato `Torino`, Camera `torino`). Per aggregazioni cross-camera usare `birth_region`; per città/provincia/nazione normalizzare a valle se serve confrontarle.
63
+
64
+
## Da provincia a regione: risorsa derivata da SITUAS/ISTAT
65
+
66
+
La regione di nascita non è un dato di fonte (il Senato dà la provincia, la Camera la annega nell'URI). La materializziamo una volta sola in `src/core/province-region.ts` (modulo TS, bundle-safe per il Worker), con questa provenienza:
67
+
68
+
-**Fonte**: SITUAS/ISTAT, report 64 *"Elenco Province/Uts"*, via la CLI `opensituas` (`opensituas get 64 -o json`). Dà `DEN_UTS` (nome provincia/UTS) → `DEN_REG` (nome regione).
69
+
-**Snapshot a più date**: SITUAS è **date-accurate** — `opensituas get 64 --date DD/MM/YYYY` dà la divisione in vigore a quella data (senza `--date` restituisce il *dato più recente / fine validità*, quindi una data anche futura). Uniamo tre snapshot per coprire ogni grafia che compare nei dati anagrafici (parlamentari nati sotto province poi soppresse o rinominate): **2010** (province sarde storiche Olbia-Tempio, Carbonia-Iglesias), **2020** (era *Sud Sardegna*, le 5 province ISTAT sarde nazionali attuali), **snapshot più recente** (in Sardegna riflette la riorganizzazione **regionale**: Sulcis Iglesiente, Gallura Nord-Est Sardegna, Ogliastra, Medio Campidano). Tutte le varianti sarde ricadono comunque in `Sardegna`.
70
+
-**Normalizzazione**: chiavi confrontate senza accenti, minuscole, con apostrofi/trattini/slash resi spazio (`normProvince`), così `Forlì-Cesena`, `forli cesena`, `FORLI'-CESENA` collassano sulla stessa chiave.
71
+
-**Alias** — solo le forme brevi che il Senato usa e che SITUAS non ha a **nessuna** data (SITUAS usa i nomi estesi/bilingui): `Aosta`→Valle d'Aosta, `Bolzano`→Trentino-Alto Adige, `Monza e Brianza`→Lombardia. (`Sud Sardegna`**non** è più un alias: è nativa nello snapshot 2020.)
72
+
-**Copertura verificata**: 100% delle province di nascita distinte presenti nei dati del Senato risolvono a una regione (0 non risolte).
73
+
-**Le label Senato NON sono aggiornate/allineate all'ISTAT corrente** — non è SITUAS a sbagliare (è date-accurate), è il Senato che espone nomi non normalizzati. Su 110 province distinte, 104 combaciano esattamente con la nomenclatura UTS ISTAT; le 6 differenze sono gestite da `normProvince`+alias e sono di due tipi: **refusi ortografici** (`Forli'-Cesena` con apostrofo invece dell'accento ì, `Verbano Cusio Ossola` senza trattini) e **forme non ufficiali/datate** (`Monza e Brianza` per "Monza e della Brianza"; forme brevi non bilingui `Aosta`/`Bolzano`). `Sud Sardegna` è invece **corretta** (è il nome ISTAT nazionale in vigore fino alla riorganizzazione regionale sarda). Segnalato ai gestori Senato come miglioramento: esporre i **codici** ISTAT dei luoghi (non solo le label) renderebbe i join robusti a grafia e cambi amministrativi. Nota: il Senato espone solo le **label**, non i codici ISTAT — segnalato ai gestori come miglioramento (i codici renderebbero i join robusti alla grafia).
74
+
75
+
Quando cambiano le circoscrizioni provinciali, **non** si edita la mappa a mano: si rigenera da SITUAS con `opensituas`.
Copy file name to clipboardExpand all lines: docs/lod-wiki/index.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,4 +16,4 @@ Il differenziale rispetto a una semplice descrizione dell'ontologia sono le **tr
16
16
17
17
*[Trappole Virtuoso — funzioni stringa e confronti](trappole-virtuoso-funzioni-stringa.md) - due comportamenti non standard del motore Virtuoso (entrambi gli endpoint): `SUBSTR` fuori range aborta la query senza short-circuit; `>=`/`<=` sul risultato di funzioni stringa fa un confronto numerico che dà 0 righe se non avvolto in `STR()`. Causa frequente di SPARQL "corretto" ma non funzionante.
18
18
*[Freschezza del dato e cosa fa fede sull'approvazione](freschezza-e-autorevolezza.md) - il LOD non espone un "as-of" affidabile; per l'esito (approvato/respinto/promulgato) la fonte di verità è resoconto/scheda iter/GU. Distinzione "approvato da un ramo" ≠ "legge".
19
-
*[Dati anagrafici dei parlamentari](dati-anagrafici.md) - nascita, genere, luogo: due nodi alla Camera (persona vs deputato), doppia forma al Senato; gerarchia geografica presente nell'URI luogo Camera ma assente al Senato (solo città); trappole su formati data e filtro legislatura.
19
+
*[Dati anagrafici dei parlamentari](dati-anagrafici.md) - nascita, genere, luogo: due nodi alla Camera (persona vs deputato), doppia forma al Senato; geografia di nascita strutturata al Senato (`cittaNascita`/`provinciaNascita`/`nazioneNascita`) ma solo dentro l'URI luogo alla Camera; regione derivata da provincia con tabella SITUAS/ISTAT; trappole su formati data, filtro legislatura e parsing dello slug Camera.
0 commit comments