feat(server): read visits and recorded routes from Dawarich

A new `integrations/dawarich` domain behind its own addon. Each reader
connects their own instance; the API key is encrypted at rest and never
returned. Nothing is written back to Dawarich, and no raw position is
kept in TREK: the recorded route is fetched per request for the window
being looked at and thrown away again.

What it produces are suggestions, never facts. A recorded stay becomes a
proposed place or journal entry, a country or city becomes a proposed
Atlas mark, and a stay near a wish becomes a proposed tick-off; each one
waits for the reader to confirm it. Identity is (user, Dawarich visit),
so a second sync neither duplicates nor overwrites what was accepted,
and deleting the result puts the suggestion back on the list.

The sync runs as a job on the central scheduler, one user at a time,
guarded against overlapping runs.
This commit is contained in:
Maurice
2026-09-12 23:34:54 +02:00
parent dad1316172
commit 218d8baf0a
55 changed files with 7469 additions and 29 deletions
+3
View File
@@ -612,6 +612,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'استيراد الأماكن من قائمة Naver Maps مشتركة',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'مزامنة الرحلات من خادم AirTrail الخاص بك',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'قراءة الزيارات والمسارات المسجَّلة من خادم Dawarich يربطه كل قارئ بنفسه',
'admin.addons.catalog.llm_parsing.name': 'التحليل بالذكاء الاصطناعي',
'admin.addons.catalog.llm_parsing.description': 'يقرأ الحجوزات التي يعجز المحلل المدمج عن فهمها، بنموذج ذكاء اصطناعي تختاره',
'admin.addons.enabled': 'مفعّل',
+3
View File
@@ -605,6 +605,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importe lugares de uma lista compartilhada do Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Sincronize voos da sua instância AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Leia visitas e rotas gravadas de uma instância do Dawarich que cada leitor conecta por conta própria',
'admin.addons.catalog.llm_parsing.name': 'Análise por IA',
'admin.addons.catalog.llm_parsing.description': 'Lê reservas que o analisador integrado não entende, usando um modelo de IA à sua escolha',
'admin.addons.enabled': 'Ativado',
+3
View File
@@ -224,6 +224,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importa llocs des d’una llista compartida de Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Sincronitza vols des de la teva instància d’AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Llegeix estades i recorreguts enregistrats d’una instància de Dawarich que cada lector connecta pel seu compte',
'admin.addons.catalog.llm_parsing.name': 'Anàlisi amb IA',
'admin.addons.catalog.llm_parsing.description': 'Llegeix reserves que l’analitzador integrat no entén, amb un model d’IA que triïs',
'admin.addons.enabled': 'Actiu',
+3
View File
@@ -594,6 +594,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importujte místa ze sdíleného seznamu Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Synchronizujte lety ze své instance AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Načtěte návštěvy a zaznamenané trasy z instance Dawarich, kterou si každý čtenář připojí sám',
'admin.addons.catalog.llm_parsing.name': 'Analýza pomocí AI',
'admin.addons.catalog.llm_parsing.description': 'Přečte rezervace, které vestavěný analyzátor nezvládne, pomocí zvoleného modelu AI',
'admin.addons.catalog.roadtrip.name': 'Cesta autem',
+3
View File
@@ -611,6 +611,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Orte aus einer geteilten Naver-Maps-Liste importieren',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Flüge aus deiner AirTrail-Instanz synchronisieren',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Aufenthalte und aufgezeichnete Routen aus einer Dawarich-Instanz lesen, die jeder selbst verbindet',
'admin.addons.catalog.llm_parsing.name': 'KI-Auswertung',
'admin.addons.catalog.llm_parsing.description': 'Liest Buchungen, an denen der eingebaute Parser scheitert, mit einem KI-Modell deiner Wahl',
'admin.addons.enabled': 'Aktiviert',
+3
View File
@@ -647,6 +647,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Import places from a shared Naver Maps list',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Sync flights from your AirTrail instance',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Read visits and recorded routes from a Dawarich instance each reader connects themselves',
'admin.addons.catalog.llm_parsing.name': 'AI Parsing',
'admin.addons.catalog.llm_parsing.description': 'Reads bookings the built-in parser cannot, using an AI model you choose',
'admin.addons.enabled': 'Enabled',
+3
View File
@@ -596,6 +596,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importa lugares desde una lista compartida de Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Sincroniza vuelos desde tu instancia de AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Lee estancias y rutas grabadas de una instancia de Dawarich que cada usuario conecta por su cuenta',
'admin.addons.catalog.llm_parsing.name': 'Análisis con IA',
'admin.addons.catalog.llm_parsing.description': 'Lee reservas que el analizador integrado no entiende, con un modelo de IA que tú elijas',
'admin.addons.enabled': 'Activo',
+3
View File
@@ -617,6 +617,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importez des lieux depuis une liste Naver Maps partagée',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Synchronisez les vols depuis votre instance AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Lisez les séjours et les trajets enregistrés depuis une instance Dawarich que chaque utilisateur connecte lui-même',
'admin.addons.catalog.llm_parsing.name': 'Analyse par IA',
'admin.addons.catalog.llm_parsing.description': 'Lit les réservations que l’analyseur intégré ne comprend pas, via un modèle d’IA de votre choix',
'admin.addons.enabled': 'Activé',
+3
View File
@@ -668,6 +668,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Εισαγωγή τοποθεσιών από κοινόχρηστη λίστα Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Συγχρονισμός πτήσεων από τη δική σας εγκατάσταση AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Ανάγνωση επισκέψεων και καταγεγραμμένων διαδρομών από μια εγκατάσταση Dawarich που συνδέει ο κάθε χρήστης μόνος του',
'admin.addons.catalog.llm_parsing.name': 'Ανάλυση με τεχνητή νοημοσύνη',
'admin.addons.catalog.llm_parsing.description': 'Διαβάζει κρατήσεις που δεν καταλαβαίνει ο ενσωματωμένος αναλυτής, με μοντέλο ΤΝ της επιλογής σας',
'admin.addons.enabled': 'Ενεργοποιημένο',
+3
View File
@@ -616,6 +616,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Helyek importálása megosztott Naver Maps-listából',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Járatok szinkronizálása az AirTrail-példányodból',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Tartózkodások és rögzített útvonalak olvasása egy Dawarich-példányból, amelyet minden olvasó maga köt be',
'admin.addons.catalog.llm_parsing.name': 'MI-elemzés',
'admin.addons.catalog.llm_parsing.description': 'Beolvassa azokat a foglalásokat, amelyeket a beépített értelmező nem tud, az általad választott MI-modellel',
'admin.addons.enabled': 'Engedélyezve',
+3
View File
@@ -657,6 +657,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Impor tempat dari daftar Naver Maps yang dibagikan',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Sinkronkan penerbangan dari instans AirTrail milikmu',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Baca kunjungan dan rute terekam dari instans Dawarich yang dihubungkan sendiri oleh tiap pembaca',
'admin.addons.catalog.llm_parsing.name': 'Analisis AI',
'admin.addons.catalog.llm_parsing.description': 'Membaca pemesanan yang tidak dipahami pengurai bawaan, dengan model AI pilihanmu',
'admin.addons.enabled': 'Aktif',
+3
View File
@@ -612,6 +612,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importa luoghi da un elenco condiviso di Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Sincronizza i voli dalla tua istanza AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Legge le soste e i percorsi registrati da un’istanza Dawarich che ogni utente collega da sé',
'admin.addons.catalog.llm_parsing.name': 'Analisi con IA',
'admin.addons.catalog.llm_parsing.description': 'Legge le prenotazioni che l’analizzatore integrato non riesce a interpretare, con un modello di IA a tua scelta',
'admin.addons.enabled': 'Abilitato',
+3
View File
@@ -621,6 +621,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': '共有された Naver マップのリストから場所をインポート',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': '自分の AirTrail から フライトを同期',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'各自が接続した Dawarich インスタンスから、滞在と記録されたルートを読み取ります',
'admin.addons.catalog.llm_parsing.name': 'AI 解析',
'admin.addons.catalog.llm_parsing.description': '内蔵パーサーが読めない予約を、選んだ AI モデルで読み取ります',
'admin.addons.enabled': '有効',
+3
View File
@@ -621,6 +621,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': '공유된 네이버 지도 목록에서 장소 가져오기',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'AirTrail 인스턴스에서 항공편 동기화',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'사용자가 각자 연결한 Dawarich 인스턴스에서 방문 기록과 기록된 경로를 읽어옵니다',
'admin.addons.catalog.llm_parsing.name': 'AI 분석',
'admin.addons.catalog.llm_parsing.description': '기본 분석기가 읽지 못하는 예약을 원하는 AI 모델로 읽어냅니다',
'admin.addons.enabled': '활성화됨',
+3
View File
@@ -609,6 +609,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importeer plaatsen uit een gedeelde Naver Maps-lijst',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Synchroniseer vluchten vanuit je AirTrail-instantie',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Lees bezoeken en opgenomen routes uit een Dawarich-instantie die elke lezer zelf koppelt',
'admin.addons.catalog.llm_parsing.name': 'AI-analyse',
'admin.addons.catalog.llm_parsing.description': 'Leest boekingen die de ingebouwde parser niet begrijpt, met een AI-model naar keuze',
'admin.addons.enabled': 'Ingeschakeld',
+3
View File
@@ -607,6 +607,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importuj miejsca z udostępnionej listy Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Synchronizuj loty ze swojej instancji AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Odczytuj pobyty i zapisane trasy z instancji Dawarich, którą każdy użytkownik podłącza sam',
'admin.addons.catalog.llm_parsing.name': 'Analiza AI',
'admin.addons.catalog.llm_parsing.description': 'Odczytuje rezerwacje, których nie rozumie wbudowany parser, przy użyciu wybranego modelu AI',
'admin.addons.enabled': 'Włączone',
+3
View File
@@ -612,6 +612,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Импорт мест из общего списка Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Синхронизация рейсов с вашего сервера AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Чтение посещений и записанных маршрутов из экземпляра Dawarich, который каждый пользователь подключает сам',
'admin.addons.catalog.llm_parsing.name': 'Разбор с помощью ИИ',
'admin.addons.catalog.llm_parsing.description': 'Читает брони, которые не понимает встроенный анализатор, с помощью выбранной вами модели ИИ',
'admin.addons.enabled': 'Включено',
+3
View File
@@ -670,6 +670,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Importera platser från en delad Naver Maps-lista',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Synkronisera flyg från din AirTrail-instans',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Läs vistelser och inspelade rutter från en Dawarich-instans som varje läsare ansluter själv',
'admin.addons.catalog.llm_parsing.name': 'AI-tolkning',
'admin.addons.catalog.llm_parsing.description': 'Läser bokningar som den inbyggda tolken inte klarar, med en AI-modell du väljer',
'admin.addons.enabled': 'Aktiverad',
+3
View File
@@ -655,6 +655,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Paylaşılan bir Naver Haritalar listesinden yerleri içe aktarın',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'AirTrail örneğinizden uçuşları eşitleyin',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Her kullanıcının kendi bağladığı bir Dawarich sunucusundan ziyaretleri ve kaydedilen rotaları okuyun',
'admin.addons.catalog.llm_parsing.name': 'Yapay zekâ ile ayrıştırma',
'admin.addons.catalog.llm_parsing.description': 'Yerleşik ayrıştırıcının okuyamadığı rezervasyonları, seçtiğiniz yapay zekâ modeliyle okur',
'admin.addons.enabled': 'Etkinleştirilmiş',
+3
View File
@@ -609,6 +609,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Імпорт місць зі спільного списку Naver Maps',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Синхронізація рейсів із вашого сервера AirTrail',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Читає перебування та записані маршрути із сервера Dawarich, який кожен користувач підключає сам',
'admin.addons.catalog.llm_parsing.name': 'Розбір за допомогою ШІ',
'admin.addons.catalog.llm_parsing.description': 'Читає бронювання, які не розпізнає вбудований аналізатор, за допомогою обраної вами моделі ШІ',
'admin.addons.enabled': 'Увімкнено',
+3
View File
@@ -611,6 +611,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': 'Nhập địa điểm từ danh sách Naver Maps được chia sẻ',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Đồng bộ chuyến bay từ máy chủ AirTrail của bạn',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'Đọc các điểm lưu trú và lộ trình đã ghi từ phiên bản Dawarich mà mỗi người tự kết nối',
'admin.addons.catalog.llm_parsing.name': 'Phân tích bằng AI',
'admin.addons.catalog.llm_parsing.description': 'Đọc các đặt chỗ mà bộ phân tích tích hợp không hiểu, bằng mô hình AI bạn chọn',
'admin.addons.enabled': 'Đã bật',
+3
View File
@@ -603,6 +603,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': '從共享的 Naver 地圖清單匯入地點',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': '從你的 AirTrail 執行個體同步航班',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'從各位使用者自行連接的 Dawarich 執行個體讀取造訪紀錄與記錄的路線',
'admin.addons.catalog.llm_parsing.name': 'AI 解析',
'admin.addons.catalog.llm_parsing.description': '用你選擇的 AI 模型讀取內建解析器無法識別的訂位',
'admin.addons.enabled': '已啟用',
+3
View File
@@ -563,6 +563,9 @@ const admin: TranslationStrings = {
'admin.addons.catalog.naver_list_import.description': '从共享的 Naver 地图列表导入地点',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': '从你的 AirTrail 实例同步航班',
'admin.addons.catalog.dawarich.name': 'Dawarich',
'admin.addons.catalog.dawarich.description':
'从每位使用者自行连接的 Dawarich 实例读取到访记录和记录的路线',
'admin.addons.catalog.llm_parsing.name': 'AI 解析',
'admin.addons.catalog.llm_parsing.description': '用你选择的 AI 模型读取内置解析器无法识别的预订',
'admin.addons.enabled': '已启用',