mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
feat(roadtrip): a day after a booked night starts at the stay, a day before one ends there
A trip can now switch on roadtrip_hotel_bookends, a shared driving preference that is off until somebody sets it, so every trip drives exactly as before. Switched on, the planner in the browser and calculate_roadtrip on the server seat the hotel slept in at the start of the next day and tonight's hotel at the end of the day, both through seatNightBookends over the trip's stays in id order, with the earliest booking linked to each. A linked booking changes the hotel row and asks the router nothing. The switch sits in the desktop driving settings under the route line, and the phone's driving figures carry the same switch as the one control they offer; both write through the planner's own preference save, so a flip offline queues like any other. get_roadtrip_context reports the stays, calculate_roadtrip previews the switch through its settings, and the settings, corridor and day boundary tools say what it does and that missing means off.
This commit is contained in:
@@ -114,6 +114,8 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'ربط الأيام',
|
||||
'roadtrip.line.dayColors': 'لون لكل يوم',
|
||||
'roadtrip.line.hint': 'يحسب أيضًا المسافة بين يومين ويحتسبها على يوم الوصول.',
|
||||
'roadtrip.line.hotelBookends': 'ابدأ كل يوم وأنهِه في مكان إقامتك',
|
||||
'roadtrip.line.hotelBookendsHint': 'بعد ليلة محجوزة يبدأ اليوم حيث نمت، وقبل ليلة محجوزة ينتهي هناك.',
|
||||
'roadtrip.avoid.section': 'التجنب قدر الإمكان',
|
||||
'roadtrip.avoid.toll': 'الطرق ذات الرسوم',
|
||||
'roadtrip.avoid.motorway': 'الطرق السريعة',
|
||||
|
||||
@@ -115,6 +115,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Conectar os dias',
|
||||
'roadtrip.line.dayColors': 'Uma cor por dia',
|
||||
'roadtrip.line.hint': 'Também calcula o trecho entre dois dias e conta no dia de chegada.',
|
||||
'roadtrip.line.hotelBookends': 'Começar e terminar cada dia na hospedagem',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Depois de uma noite reservada, o dia começa onde você dormiu, e antes de uma ele termina lá.',
|
||||
'roadtrip.avoid.section': 'Evitar quando possível',
|
||||
'roadtrip.avoid.toll': 'Pedágios',
|
||||
'roadtrip.avoid.motorway': 'Rodovias',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Connecta els dies',
|
||||
'roadtrip.line.dayColors': 'Un color per dia',
|
||||
'roadtrip.line.hint': 'També calcula el tram entre dos dies i el compta al dia d’arribada.',
|
||||
'roadtrip.line.hotelBookends': 'Comença i acaba cada dia a l’allotjament',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Després d’una nit reservada, el dia comença on has dormit, i abans d’una acaba allà.',
|
||||
'roadtrip.avoid.section': 'Evita quan sigui possible',
|
||||
'roadtrip.avoid.toll': 'Peatges',
|
||||
'roadtrip.avoid.motorway': 'Autopistes',
|
||||
|
||||
@@ -115,6 +115,8 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Propojit dny',
|
||||
'roadtrip.line.dayColors': 'Barva na den',
|
||||
'roadtrip.line.hint': 'Spočítá i úsek mezi dvěma dny a připočte ho ke dni příjezdu.',
|
||||
'roadtrip.line.hotelBookends': 'Začínat a končit každý den v ubytování',
|
||||
'roadtrip.line.hotelBookendsHint': 'Po zarezervované noci začíná den tam, kde jste spali, a před ní tam končí.',
|
||||
'roadtrip.avoid.section': 'Vyhnout se, pokud to jde',
|
||||
'roadtrip.avoid.toll': 'Mýtné silnice',
|
||||
'roadtrip.avoid.motorway': 'Dálnice',
|
||||
|
||||
@@ -114,6 +114,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Tage verbinden',
|
||||
'roadtrip.line.dayColors': 'Farbe je Tag',
|
||||
'roadtrip.line.hint': 'Verbindungsfahrten zählen zum Ankunftstag.',
|
||||
'roadtrip.line.hotelBookends': 'Jeden Tag an der Unterkunft beginnen und beenden',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Nach einer gebuchten Nacht beginnt der Tag dort, wo du geschlafen hast, und vor einer endet er dort.',
|
||||
'roadtrip.avoid.section': 'Möglichst meiden',
|
||||
'roadtrip.avoid.toll': 'Mautstraßen',
|
||||
'roadtrip.avoid.motorway': 'Autobahnen',
|
||||
|
||||
@@ -114,6 +114,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Connect the days',
|
||||
'roadtrip.line.dayColors': 'A colour per day',
|
||||
'roadtrip.line.hint': 'Connecting drives count toward the arrival day.',
|
||||
'roadtrip.line.hotelBookends': 'Start and end each day at your stay',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'After a booked night the day starts where you slept, and before one it ends there.',
|
||||
'roadtrip.avoid.section': 'Avoid where possible',
|
||||
'roadtrip.avoid.toll': 'Toll roads',
|
||||
'roadtrip.avoid.motorway': 'Motorways',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Conectar los días',
|
||||
'roadtrip.line.dayColors': 'Un color por día',
|
||||
'roadtrip.line.hint': 'También calcula el tramo entre dos días y lo cuenta en el día de llegada.',
|
||||
'roadtrip.line.hotelBookends': 'Empezar y terminar cada día en tu alojamiento',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Tras una noche reservada, el día empieza donde dormiste, y antes de una termina allí.',
|
||||
'roadtrip.avoid.section': 'Evitar si es posible',
|
||||
'roadtrip.avoid.toll': 'Peajes',
|
||||
'roadtrip.avoid.motorway': 'Autopistas',
|
||||
|
||||
@@ -117,6 +117,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Relier les jours',
|
||||
'roadtrip.line.dayColors': 'Une couleur par jour',
|
||||
'roadtrip.line.hint': 'Calcule aussi le trajet entre deux jours et le compte au jour d’arrivée.',
|
||||
'roadtrip.line.hotelBookends': 'Commencer et finir chaque jour à votre hébergement',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Après une nuit réservée, la journée commence là où vous avez dormi, et avant une nuit réservée, elle s’y termine.',
|
||||
'roadtrip.avoid.section': 'Éviter si possible',
|
||||
'roadtrip.avoid.toll': 'Routes à péage',
|
||||
'roadtrip.avoid.motorway': 'Autoroutes',
|
||||
|
||||
@@ -118,6 +118,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Σύνδεση των ημερών',
|
||||
'roadtrip.line.dayColors': 'Ένα χρώμα ανά ημέρα',
|
||||
'roadtrip.line.hint': 'Υπολογίζει και το τμήμα ανάμεσα σε δύο ημέρες, στην ημέρα άφιξης.',
|
||||
'roadtrip.line.hotelBookends': 'Έναρξη και λήξη κάθε ημέρας στο κατάλυμα',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Μετά από μια κρατημένη νύχτα η ημέρα ξεκινά εκεί όπου κοιμηθήκατε, και πριν από μία τελειώνει εκεί.',
|
||||
'roadtrip.avoid.section': 'Αποφυγή όπου γίνεται',
|
||||
'roadtrip.avoid.toll': 'Δρόμοι με διόδια',
|
||||
'roadtrip.avoid.motorway': 'Αυτοκινητόδρομοι',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Napok összekötése',
|
||||
'roadtrip.line.dayColors': 'Naponta egy szín',
|
||||
'roadtrip.line.hint': 'A két nap közti szakaszt is kiszámolja, és az érkezés napjához adja.',
|
||||
'roadtrip.line.hotelBookends': 'Minden nap a szálláson kezdődjön és érjen véget',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Egy lefoglalt éjszaka után a nap ott kezdődik, ahol aludtál, egy lefoglalt éjszaka előtt pedig ott ér véget.',
|
||||
'roadtrip.avoid.section': 'Kerülés, ha lehet',
|
||||
'roadtrip.avoid.toll': 'Fizetős utak',
|
||||
'roadtrip.avoid.motorway': 'Autópályák',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Hubungkan hari',
|
||||
'roadtrip.line.dayColors': 'Satu warna per hari',
|
||||
'roadtrip.line.hint': 'Juga menghitung ruas antara dua hari dan memasukkannya ke hari kedatangan.',
|
||||
'roadtrip.line.hotelBookends': 'Mulai dan akhiri setiap hari di penginapan Anda',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Setelah malam yang dipesan, hari dimulai di tempat Anda menginap, dan sebelum malam yang dipesan, hari berakhir di sana.',
|
||||
'roadtrip.avoid.section': 'Hindari bila bisa',
|
||||
'roadtrip.avoid.toll': 'Jalan tol',
|
||||
'roadtrip.avoid.motorway': 'Jalan bebas hambatan',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Collega i giorni',
|
||||
'roadtrip.line.dayColors': 'Un colore per giorno',
|
||||
'roadtrip.line.hint': 'Calcola anche il tratto tra due giorni e lo conta nel giorno di arrivo.',
|
||||
'roadtrip.line.hotelBookends': 'Inizia e termina ogni giorno al tuo alloggio',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Dopo una notte prenotata la giornata parte da dove hai dormito, e prima di una finisce lì.',
|
||||
'roadtrip.avoid.section': 'Evita se possibile',
|
||||
'roadtrip.avoid.toll': 'Strade a pedaggio',
|
||||
'roadtrip.avoid.motorway': 'Autostrade',
|
||||
|
||||
@@ -116,6 +116,8 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': '日をつなぐ',
|
||||
'roadtrip.line.dayColors': '日ごとに色を分ける',
|
||||
'roadtrip.line.hint': '日と日の間の区間も計算し、到着した日に加えます。',
|
||||
'roadtrip.line.hotelBookends': '毎日を宿泊先で始めて宿泊先で終える',
|
||||
'roadtrip.line.hotelBookendsHint': '予約した夜の翌日は泊まった宿から始まり、予約した夜の日はその宿で終わります。',
|
||||
'roadtrip.avoid.section': 'できるだけ避ける',
|
||||
'roadtrip.avoid.toll': '有料道路',
|
||||
'roadtrip.avoid.motorway': '高速道路',
|
||||
|
||||
@@ -115,6 +115,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': '날짜 잇기',
|
||||
'roadtrip.line.dayColors': '날짜별 색상',
|
||||
'roadtrip.line.hint': '두 날 사이 구간도 계산해 도착한 날에 더합니다.',
|
||||
'roadtrip.line.hotelBookends': '매일 숙소에서 시작하고 숙소에서 끝내기',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'예약한 밤 다음 날은 묵은 곳에서 시작하고, 예약한 밤이 있는 날은 그곳에서 끝납니다.',
|
||||
'roadtrip.avoid.section': '가능하면 피하기',
|
||||
'roadtrip.avoid.toll': '유료 도로',
|
||||
'roadtrip.avoid.motorway': '고속도로',
|
||||
|
||||
@@ -117,6 +117,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Dagen verbinden',
|
||||
'roadtrip.line.dayColors': 'Een kleur per dag',
|
||||
'roadtrip.line.hint': 'Berekent ook het stuk tussen twee dagen en telt het bij de aankomstdag.',
|
||||
'roadtrip.line.hotelBookends': 'Elke dag bij je verblijf beginnen en eindigen',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Na een geboekte nacht begint de dag waar je sliep, en vóór een geboekte nacht eindigt hij daar.',
|
||||
'roadtrip.avoid.section': 'Vermijden waar het kan',
|
||||
'roadtrip.avoid.toll': 'Tolwegen',
|
||||
'roadtrip.avoid.motorway': 'Snelwegen',
|
||||
|
||||
@@ -115,6 +115,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Połącz dni',
|
||||
'roadtrip.line.dayColors': 'Kolor na dzień',
|
||||
'roadtrip.line.hint': 'Wyznacza też odcinek między dniami i liczy go do dnia przyjazdu.',
|
||||
'roadtrip.line.hotelBookends': 'Zaczynaj i kończ każdy dzień w noclegu',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Po zarezerwowanej nocy dzień zaczyna się w miejscu noclegu, a przed taką nocą tam się kończy.',
|
||||
'roadtrip.avoid.section': 'Omijaj, jeśli się da',
|
||||
'roadtrip.avoid.toll': 'Drogi płatne',
|
||||
'roadtrip.avoid.motorway': 'Autostrady',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Соединить дни',
|
||||
'roadtrip.line.dayColors': 'Цвет на день',
|
||||
'roadtrip.line.hint': 'Также считает участок между двумя днями и относит его ко дню прибытия.',
|
||||
'roadtrip.line.hotelBookends': 'Начинать и заканчивать каждый день в месте проживания',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'После забронированной ночи день начинается там, где вы ночевали, а перед ней заканчивается там.',
|
||||
'roadtrip.avoid.section': 'Избегать по возможности',
|
||||
'roadtrip.avoid.toll': 'Платные дороги',
|
||||
'roadtrip.avoid.motorway': 'Автомагистрали',
|
||||
|
||||
@@ -114,6 +114,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Koppla ihop dagarna',
|
||||
'roadtrip.line.dayColors': 'En färg per dag',
|
||||
'roadtrip.line.hint': 'Beräknar även sträckan mellan två dagar och räknar den på ankomstdagen.',
|
||||
'roadtrip.line.hotelBookends': 'Börja och avsluta varje dag vid ditt boende',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Efter en bokad natt börjar dagen där du sov, och före en bokad natt slutar den där.',
|
||||
'roadtrip.avoid.section': 'Undvik om det går',
|
||||
'roadtrip.avoid.toll': 'Avgiftsvägar',
|
||||
'roadtrip.avoid.motorway': 'Motorvägar',
|
||||
|
||||
@@ -116,6 +116,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Günleri birleştir',
|
||||
'roadtrip.line.dayColors': 'Her güne bir renk',
|
||||
'roadtrip.line.hint': 'İki gün arasındaki yolu da hesaplar ve varış gününe sayar.',
|
||||
'roadtrip.line.hotelBookends': 'Her güne konaklama yerinde başla ve orada bitir',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Rezerve edilmiş bir geceden sonra gün uyuduğunuz yerde başlar, böyle bir geceden önce de orada biter.',
|
||||
'roadtrip.avoid.section': 'Mümkünse kaçın',
|
||||
'roadtrip.avoid.toll': 'Paralı yollar',
|
||||
'roadtrip.avoid.motorway': 'Otoyollar',
|
||||
|
||||
@@ -115,6 +115,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'З’єднати дні',
|
||||
'roadtrip.line.dayColors': 'Колір на день',
|
||||
'roadtrip.line.hint': 'Також рахує ділянку між двома днями і зараховує її дню прибуття.',
|
||||
'roadtrip.line.hotelBookends': 'Починати й завершувати кожен день у місці проживання',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Після заброньованої ночі день починається там, де ви ночували, а перед нею там і закінчується.',
|
||||
'roadtrip.avoid.section': 'Уникати за можливості',
|
||||
'roadtrip.avoid.toll': 'Платні дороги',
|
||||
'roadtrip.avoid.motorway': 'Автомагістралі',
|
||||
|
||||
@@ -115,6 +115,9 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': 'Nối các ngày',
|
||||
'roadtrip.line.dayColors': 'Mỗi ngày một màu',
|
||||
'roadtrip.line.hint': 'Cũng tính đoạn giữa hai ngày và cộng vào ngày tới nơi.',
|
||||
'roadtrip.line.hotelBookends': 'Bắt đầu và kết thúc mỗi ngày tại nơi lưu trú',
|
||||
'roadtrip.line.hotelBookendsHint':
|
||||
'Sau một đêm đã đặt, ngày bắt đầu ở nơi bạn ngủ, và trước một đêm đã đặt, ngày kết thúc ở đó.',
|
||||
'roadtrip.avoid.section': 'Tránh nếu có thể',
|
||||
'roadtrip.avoid.toll': 'Đường thu phí',
|
||||
'roadtrip.avoid.motorway': 'Đường cao tốc',
|
||||
|
||||
@@ -109,6 +109,8 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': '連接各天',
|
||||
'roadtrip.line.dayColors': '每天一種顏色',
|
||||
'roadtrip.line.hint': '也會規劃兩天之間的路段,並計入抵達的那一天。',
|
||||
'roadtrip.line.hotelBookends': '每天從住宿地點出發,並在住宿地點結束',
|
||||
'roadtrip.line.hotelBookendsHint': '預訂的一晚之後,當天從你住的地方出發;預訂的一晚之前,當天在那裡結束。',
|
||||
'roadtrip.avoid.section': '盡量避開',
|
||||
'roadtrip.avoid.toll': '收費公路',
|
||||
'roadtrip.avoid.motorway': '高速公路',
|
||||
|
||||
@@ -109,6 +109,8 @@ const roadtrip: TranslationStrings = {
|
||||
'roadtrip.line.connect': '连接各天',
|
||||
'roadtrip.line.dayColors': '每天一种颜色',
|
||||
'roadtrip.line.hint': '也会规划两天之间的路段,并计入抵达的那一天。',
|
||||
'roadtrip.line.hotelBookends': '每天从住处出发,并在住处结束',
|
||||
'roadtrip.line.hotelBookendsHint': '预订的一晚之后,当天从你住的地方出发;预订的一晚之前,当天在那里结束。',
|
||||
'roadtrip.avoid.section': '尽量避开',
|
||||
'roadtrip.avoid.toll': '收费公路',
|
||||
'roadtrip.avoid.motorway': '高速公路',
|
||||
|
||||
@@ -20,6 +20,17 @@ describe('Roadtrip MCP contracts', () => {
|
||||
])('rejects invalid driving preferences %j', (settings) => {
|
||||
expect(roadtripPreferencesUpdateSchema.safeParse(settings).success).toBe(false);
|
||||
});
|
||||
it('takes the switch that starts and ends each day at the stay as a boolean, and nothing else', () => {
|
||||
expect(roadtripPreferencesUpdateSchema.parse({ roadtrip_hotel_bookends: true })).toEqual({
|
||||
roadtrip_hotel_bookends: true,
|
||||
});
|
||||
expect(roadtripPreferencesUpdateSchema.parse({ roadtrip_hotel_bookends: false })).toEqual({
|
||||
roadtrip_hotel_bookends: false,
|
||||
});
|
||||
for (const value of ['true', 1, null, 'on']) {
|
||||
expect(roadtripPreferencesUpdateSchema.safeParse({ roadtrip_hotel_bookends: value }).success).toBe(false);
|
||||
}
|
||||
});
|
||||
it('allows clearing settings and preserves manual controls', () => {
|
||||
expect(
|
||||
roadtripPreferencesUpdateSchema.parse({
|
||||
|
||||
@@ -22,6 +22,10 @@ export const roadtripPreferencesSchema = z
|
||||
roadtrip_service_stops_in_days: z.boolean().optional(),
|
||||
roadtrip_day_colors: z.boolean().optional(),
|
||||
roadtrip_show_hazards: z.boolean().optional(),
|
||||
// Whether a day after a booked night starts at the stay and a day before one ends
|
||||
// there (`hotelBookendsOn`). Missing means off, so a trip drives as it always has
|
||||
// until somebody switches it on.
|
||||
roadtrip_hotel_bookends: z.boolean().optional(),
|
||||
roadtrip_avoid: z
|
||||
.string()
|
||||
.max(32)
|
||||
|
||||
Reference in New Issue
Block a user