Якість і актуальність даних
Правові довідкові дані застарівають непомітно: публікується нова процентна ставка, суд переїжджає, закон об'єднує два кантони. Ця сторінка пояснює, як пакет устигає за змінами і наскільки можна довіряти кожному набору даних.
Звідки береться кожен набір даних
| Набір даних | Джерело | Як будується | Змінюється, коли | Перегляд кожні |
|---|---|---|---|---|
| Апеляційні округи, судові округи | Gerechtelijk Wetboek / Code judiciaire, додаток, ст. 4–5 | Вручну | Закон перекроює судову карту (рідко; востаннє у 2014 році) | 24 місяці |
| Кантони | Gerechtelijk Wetboek / Code judiciaire, додаток, ст. 1 (nl + fr) | Генерується: pnpm build:cantons | Закон змінює додаток; громади об'єднуються | 12 місяців |
| Межі кантонів | NGI (geo.be) | Щотижня: знімки + pnpm build:data | NGI публікує нову версію | Щотижня |
| Громади | Відкриті дані Statbel | Генерується: pnpm build:cantons | Громади об'єднуються (2019, 2025) | 12 місяців |
| Регіони, провінції | Перелік кодів REFNIS від Statbel | Щотижня: знімки + pnpm build:data | Statbel змінює свій реєстр (востаннє у 1995 році) | Щотижня |
| Суди | tribunaux-rechtbanken.be | Щотижня: знімки + pnpm build:data | Суд переїжджає або змінює контакти чи години роботи | Щотижня |
| В'язниці | justitie.belgium.be | Щотижня: знімки + pnpm build:data | В'язниця відкривається, закривається або змінює контакти | Щотижня |
| Justitiehuizen / maisons de justice | vlaanderen.be, maisonsdejustice.be | Щотижня: знімки + pnpm build:data | Установа переїжджає або змінює контакти | Щотижня |
| Поштові індекси | Таблиця відповідності Statbel | Щотижня: знімки + pnpm build:data | Statbel публікує нову таблицю (об'єднання, нові коди) | Щотижня |
| Процентні ставки | FOD Financiën, Belgisch Staatsblad / Moniteur belge | Вручну | Щороку (законна) і щопівроку (комерційна) | 6 місяців |
Згенеровані набори даних ніколи не редагуються вручну. pnpm build:cantons розбирає офіційний текст і відмовляється щось записувати, якщо нідерландська і французька версії не збігаються або якщо охоплено не кожну громаду; pnpm build:data відмовляється, коли сторінку неможливо розпізнати, кантон не має суду або кантон не має межі у файлі NGI.
Як будуються дані
official site ──fetch──> snapshots (sources branch) ──parse──> data/*.json ──> pull request- Завантаження. Щопонеділка sources workflow завантажує кожну сторінку джерел (
scripts/sources), чемно: один запит на секунду на сайт, з user agent, що називає проєкт. Кожну сторінку він зберігає в гілціsources, з індексом того, що завантажено, коли, і хешем її вмісту. Сторінка зберігається знову лише тоді, коли змінюється її вміст, тож історія гілки показує, що змінилося і якого дня. Сторінка, яку не вдалося завантажити (помилка сервера, 404), зберігає свій останній вдалий знімок і зупиняє запуск, що відкриває issue: дані ніколи не перебудовуються з неповної картини. Сторінку, на яку джерело більше не посилається, вилучають зі знімків; її запис залишається в даних, виведений з ужитку зvalidTo(день перед перевіркою, яка її не знайшла), тож її id і далі працює, а пошук на раніший день і далі її знаходить. Нова сторінка отримує запис ізvalidFrom. - Розбір.
pnpm build:dataчитає знімки (scripts/parse) і записує суди, в'язниці, justitiehuizen / maisons de justice і межі кантонів. Він повідомляє, чого не може прочитати, і падає, коли сторінку неможливо розпізнати. - Тестування. Workflow перевіряє типи і запускає тести на нових даних.
- Перегляд. Якщо дані змінилися, він відкриває або оновлює один pull request із diff і списком значень, які не вдалося прочитати. Людина звіряє його з джерелами і зливає.
Щоб запустити самостійно: pnpm fetch:sources (записує .sources/), потім pnpm build:data.
Кантони й громади перебудовуються вручну командою pnpm build:cantons: сайт Belgisch Staatsblad / Moniteur belge (офіційного вісника Бельгії) відмовляє серверам GitHub (#52).
Автоматичні перевірки
За кожної зміни (CI)
- Валідація за схемою: кожен файл даних відповідає своїй JSON Schema.
- Цілісність: id унікальні й правильно сформовані; кожне посилання (судовий округ, кантон, громада, суд, межа) вказує на наявний запис; кожен кантон має одну межу — коректний GeoJSON у межах Бельгії, що в сумі дає площу країни без перекриттів; кожна громада належить рівно до одного кантону або поділена між кількома; кожен кантон лежить у межах провінцій свого судового округу; кожен кантон має рівно один vredegerecht / justice de paix; кожне відділення має тип і округ свого суду; кожен вид суду має ту кількість судів, яку встановлює закон; кожен кантон підпадає під один суд кожного типу (у Брюсселі — по одному на мову), а кантони суду лежать у його судовому та апеляційному округах.
- Парсери: протестовані наскрізно на скорочених копіях справжніх сторінок (
test/fixtures/sources), а кожен зчитувач (номери телефонів, IBAN, адреси, години роботи) — на формах, які трапляються в джерелах, і на тому, що він мусить відхилити. - Процентні ставки: періоди впорядковані, ніколи не перекриваються і не залишають прогалин; законна ставка діє за календарний рік, а комерційна — за півріччя; ставка за правилом дати договору 2013–2015 років з'являється лише в цьому проміжку.
- Контактні дані: кожен IBAN проходить контрольну суму ISO 13616, номери телефонів — це бельгійські номери у форматі E.164, адреси електронної пошти — в нижньому регістрі, а години роботи відповідають синтаксису
opening_hours. - Код: строгий TypeScript (включно з неперевіреним доступом за індексом і точними необов'язковими властивостями), ESLint із правилами з урахуванням типів, Prettier і 100 % покриття тестами
src/. - Пакування: зібраний пакет завантажується через
importі черезrequire(), з кожного entry point, на Node 22.12, 22, 24 і 26;publintіarethetypeswrongперевіряютьexportsта оголошення типів.
Щотижня (за розкладом)
Freshness workflow запускається щопонеділка і відкриває issue з міткою data-freshness, коли щось знаходить:
- Відсутні ставки: немає законної чи комерційної ставки на сьогодні, або немає комерційної ставки на наступні два тижні (FOD Financiën публікує її до початку півріччя).
- Прострочені перегляди: дата
lastReviewedнабору даних уdatapackage.jsonстарша за йогоreviewEveryMonths. - Мертві джерела: URL офіційного джерела в
datapackage.jsonбільше не відповідає.
Запустіть їх самостійно командою pnpm test:freshness (додайте FRESHNESS_ONLINE=1, щоб перевірити URL).
Як читати значення
- Відсутність — це не нуль.
getInterestRateповертаєnullдля дня, для якого ставка невідома, замість того щоб вгадувати; поле, якого джерело не надає (адреса суду, машинозчитувані години роботи), відсутнє, а не заповнене. Обробляйте обидва випадки. - Надто рано — це помилка. Пошук на день до початку охоплення набору даних викидає
RangeError: дані не можуть дати відповідь, а сьогоднішня відповідь виглядала б правильною. - Контактні дані найменш стабільні. Номери телефонів, адреси електронної пошти і години роботи змінюються без попередження. Кожен запис указує, з яких сторінок і коли його прочитано (
sources); коли це важливо, перевіряйте сторінку суду (website). - Текст закону має перевагу. Для поділених громад
territoryкантону — це власний текст закону, дослівно. Коли резюме чи межа від NGI розходяться з текстом, правий текст.
Як повідомити про помилку
Відкрийте виправлення даних з id запису і посиланням на офіційне джерело. Виправлення випускаються як patch-версії.