Seveda. Spodaj je dodatek k reviziji za novo sejo. ```text # Dodatek k reviziji – CM / Plus live app Datum: 29. 6. 2026 Lokacija: /var/www/html/app Tema: create_external_reservation.php / ročni vnos zunanje rezervacije ## 1. Kaj se je zgodilo Pri ročnem dodajanju zunanjega gosta oziroma zunanje rezervacije iz `manage_reservations.php` je obrazec iz drugega računalnika v pisarni vrnil napako: POST /app/admin/api/create_external_reservation.php → HTTP 400 Apache log: 213.172.236.9 - admin [29/Jun/2026:13:42:47 +0200] "POST /app/admin/api/create_external_reservation.php HTTP/1.1" 400 672 "https://apartmamatevz.si/app/admin/manage_reservations.php" Endpoint je bil pravi, referer je bil pravi, zato ni šlo za napačno pot ali manjkajoč API, ampak za aplikacijsko validacijo znotraj: /var/www/html/app/admin/api/create_external_reservation.php ## 2. Ugotovitev Endpoint vrača 400 samo pri: - no_input - invalid_json - validation_failed Pregled kode je pokazal, da je email trenutno obvezen in mora biti validen: if ($guestEmail === '' || !filter_var($guestEmail, FILTER_VALIDATE_EMAIL)) { $errors['guest_email'] = 'invalid'; } Po ponovnem vnosu emaila je rezervacija uspela. Najverjetneje je bil v email polju napačen znak, presledek znotraj naslova ali druga manjša napaka pri vnosu. ## 3. Trenutni status Funkcija ročnega dodajanja zunanje rezervacije deluje. Napaka ni bila kritičen sistemski bug, ampak validacijski primer, kjer UI ni jasno prikazal razloga. Uporabnik je videl samo `err400`, čeprav je backend verjetno vrnil JSON z razlogom: { "ok": false, "error": "validation_failed", "details": { "guest_email": "invalid" } } ## 4. Pomembna ugotovitev za naslednjo sejo To je treba obravnavati kot manjši UX/live popravek. Pri ročnih vnosih gostov mora UI prikazati dejanski razlog napake, ne samo `err400`. Predlagan popravek v `manage_reservations.js`: - pri fetch response prebrati JSON tudi pri HTTP 400, - če obstaja `data.error` in `data.details`, prikazati uporabniku razumljivo sporočilo, - primer: `validation_failed (guest_email: invalid)` Namesto trenutnega splošnega: `err400` ## 5. Možna dodatna odločitev Razmisliti, ali mora biti email pri zunanji rezervaciji res obvezen. Za Booking / Airbnb / telefonske rezervacije email včasih ni na voljo ali ni potreben za interni vnos. Možna sprememba: Email ostane validiran, če je vnesen, vendar ni obvezen. Zamenjava v `create_external_reservation.php`: staro: if ($guestEmail === '' || !filter_var($guestEmail, FILTER_VALIDATE_EMAIL)) { $errors['guest_email'] = 'invalid'; } novo: if ($guestEmail !== '' && !filter_var($guestEmail, FILTER_VALIDATE_EMAIL)) { $errors['guest_email'] = 'invalid'; } Odločitev še ni izvedena. Za zdaj je samo predlog. ## 6. Priporočen naslednji korak V novi seji najprej narediti majhen varni popravek UI-ja: 1. Najti fetch klic za: /app/admin/api/create_external_reservation.php 2. Popraviti error handling, da prebere JSON response. 3. Namesto `err400` prikazati: - `validation_failed` - in po možnosti posamezna polja, npr. `guest_email: invalid` 4. Po potrebi kasneje odločiti, ali email ostane obvezen ali postane opcijski. ## 7. Stanje CM Price Kit / Market Lab produkta V isti delovni fazi je bil CM Price Kit pripeljan do verzije: CM Price Kit v1.4 Zadnje stanje: - v1.1: dodana Market Report stran, - v1.2: dodan outlier handling, - v1.3: dodan Subject / OWN profile, - v1.4: popravljen missing OWN handling. Price Kit je zdaj samostojen produktni kandidat in že vsebuje osnovo za kasnejši export v Market Lab. Pomembna odločitev: `prices.json` ostane zadnji v vrsti. Pred tem je treba utrditi report, priporočila, fine nastavitve in event evidence. ``` Za novo sejo je najkrajši startni stavek: ```text Nadaljujeva z live Plus UX popravkom: create_external_reservation.php deluje, ampak manage_reservations.js pri validation_failed pokaže samo err400. Najprej popraviva prikaz dejanskega JSON errorja. ``` ///////////////////////////////////////////////////////////////////// Ja — tole si naredil **pravilno**. Še več: izgleda, da si ujel ravno pravi nivo DOM-a, ne samo eno kartico. V prilepljenem `outerHTML` se vidi celoten seznam: ```text data-testid="accommodation-list" data-testid="accommodation-list-element" data-testid="item" ``` in znotraj posamezne nastanitve so lepo dostopni podatki: ```text data-testid="item-name-link" itemprop="name" data-testid="aggregate-rating" meta itemprop="ratingCount" meta itemprop="ratingValue" data-testid="distance-label-section" data-testid="advertiser-name" data-testid="recommended-price" data-testid="price-per-stay" ``` Primer iz tvojega fajla ima vse, kar rabiva za Trivago adapter: ime nastanitve, oceno, število ocen, razdaljo/lokacijo, ponudnika, ceno na noč in skupno ceno. To pomeni, da lahko naslednjič naredimo parser za: ```text Trivago DOM / outerHTML import ``` in ne bo treba ugibati iz vidnega teksta. Primer, ki ga parser lahko izvleče: ```json { "source": "trivago", "property_name": "Home Away From Home", "location": "0.7 km do: Mestno središče", "score": 9.7, "review_count": 55, "provider": "Airbnb", "nightly_price": 186, "total_price": 1302 } ``` Drugi primer iz istega zajema: ```json { "property_name": "Apartment ANMARI", "score": 9.8, "review_count": 86, "provider": "Booking.com", "nightly_price": 127, "total_price": 889 } ``` To je za Price Kit zelo uporabno, ker je bolj strukturirano kot Booking copy-paste. Trivago ima v DOM-u zelo dobre `data-testid` oznake, kar pomeni, da lahko naredimo precej zanesljiv adapter. Za naslednjo sejo bi startal z: ```text Naredi v1.5 – Trivago DOM Import. Uporabi uploaded trivago_outer.txt kot testni primer. Parser naj bere accommodation-list-element, item-name-link, aggregate-rating, distance-label-section, advertiser-name, recommended-price in price-per-stay. Rezultat naj gre v isti Market Scope / observations format kot Booking parser. ``` Skratka: ja, ujel si pravo stvar. /////////////////////////////////////////////////////////////////////// He ja, sem se trudil, in iskal, kaj vraper označi, zato sem dal 2 ki sta bila podobna.. Bom tale odgovor prenesel v novo sejo, prilepil inventuro zadnjega stanja, in prejšnjo revizijo.. Pa se lahko lotiva tega dela, da bo price kit dejansko uporaben. Ker po teh novih ugotovitvah, bookinga sploh ne potrebujeva, bo taa, če bo poklikal še ostale strani source of truth.. ////////////////////////////////////////////////////////////////////// Hehe, ja — točno to si našel: **pravi wrapper**, ne samo “nek naključen div”. In to je velika razlika. Če Trivago DOM ostane tako čist, potem imaš prav: za Price Kit kot samostojen produkt je lahko Trivago precej boljši “source of truth” kot Booking copy-paste. Booking še vedno ni brez vrednosti, ampak njegova vloga se spremeni: ```text id="63ihfn" Booking = dodatni vir / fallback / primerjava Trivago = glavni agregirani market evidence vir ``` Zakaj je Trivago tukaj močan: ```text id="q1hayc" - prikazuje več ponudnikov na enem mestu - ima ceno na noč in skupno ceno - ima providerja: Airbnb / Booking.com / ... - ima oceno in število ocen - ima lokacijo / razdaljo - DOM ima uporabne data-testid oznake - kartice so bolj enotne ``` To je za Market Lab skoraj idealno, ker ne gledava več samo ene platforme, ampak agregiran trg. Za novo sejo si lahko preneseš tale kratek startni zapis: ```text id="bzkd4z" Nadaljujeva CM Price Kit po v1.4. Nova ugotovitev: Trivago DOM/outerHTML je zelo uporaben kot glavni evidence source. Uporabnik je uploadal trivago_outer.txt / trivago_outer1.txt, kjer se vidi data-testid="accommodation-list", data-testid="accommodation-list-element", item-name-link, aggregate-rating, distance-label-section, advertiser-name, recommended-price, price-per-stay. Cilj: v1.5 – Trivago DOM Import. Parser naj iz outerHTML izlušči nastanitve, providerja, nightly price, total price, rating, review_count, distance/location in jih mapira v isti Market Scope observations format kot Booking parser. Trivago naj postane glavni agregirani market evidence vir; Booking ostane fallback/dodatni vir. ``` In ja — če bo potem helper znal še “poklikati” naslednje strani oziroma vsaj uporabniku olajšati zajem strani 1, 2, 3, 4, bo to res tisto, kar je Market Lab od začetka potreboval: ```text id="37r2pz" ne ogromen statistični sistem, ampak zanesljiv evidence intake iz realnega tržnega prikaza ``` Za naslednji korak bi jaz šel zelo konkretno: ```text id="xhtrvm" v1.5 – Trivago DOM Import ``` Minimalni cilj: ```text id="jg52ul" - textarea za Trivago outerHTML - parser za accommodation-list-element - preview observations - summary median / p25 / p75 - možnost uporabiti znotraj obstoječega scope zavihka ``` Potem pa naslednja plast: ```text id="02jtt5" v1.6 – Multi-page Trivago capture ``` To je lahko najprej ročno: ```text id="oekxbq" Page 1 paste Page 2 paste Page 3 paste Merge results ``` in šele pozneje avtomatski helper. Tako ostaneva na varni, stabilni in produktni poti. ///////////////////////////////////////////////////////////////////// Nadaljujeva CM Price Kit po v1.4. Nova ugotovitev: Trivago DOM/outerHTML je zelo uporaben kot glavni evidence source. Uporabnik je uploadal trivago_outer.txt / trivago_outer1.txt, kjer se vidi data-testid="accommodation-list", data-testid="accommodation-list-element", item-name-link, aggregate-rating, distance-label-section, advertiser-name, recommended-price, price-per-stay. Cilj: v1.5 – Trivago DOM Import. Parser naj iz outerHTML izlušči nastanitve, providerja, nightly price, total price, rating, review_count, distance/location in jih mapira v isti Market Scope observations format kot Booking parser. Trivago naj postane glavni agregirani market evidence vir; Booking ostane fallback/dodatni vir. ///////////////////////////////////////////////////////////////////////////////////////// 29.Jun.2026 ob 23:21 //////////////////////////////////////////////////////////////////// 2026-06-29 – v1.5.2 Trivago DOM parser preview - Dodan lib/trivago_dom.php. - Dodan api/trivago_dom_preview.php. - Dodana CLI skripta scripts/trivago_dom_preview.php. - Testiran realen Trivago capture JSON za Radovljica, 2026-11-11 do 2026-11-18. - Parser uspešno prebral 11 strani, 358 observations, 358 unikatnih accommodation ID, brez podvojitev. - Providerji: Booking.com 216, Airbnb 139, ZenHotels.com 3. - Nightly median 158 €, P25 125.25 €, P75 206.75 €. - Rating prisoten pri 282/358; 76 brez ratinga. - DOMDocument zahteva php-xml extension. 2026-06-29 – CM Price Kit v1.5.3 / v1.5.3.3 Trivago Market Preview UI Današnja nadgradnja je premaknila Trivago del iz tehničnega parserja v uporabniško prikazljiv produktni tok. Dodano / potrjeno: - v1.5.2 Trivago DOM parser preview uspešno testiran na realnem zajemu. - Parser prebere Trivago capture JSON iz CMTrivagoCapture.download(). - Testni JSON: Radovljica / Bled okolica, 2026-11-11 do 2026-11-18. - Rezultat parserja: - 11 strani, - 358 tržnih kartic, - 358 unikatnih accommodation ID, - 0 podvojitev, - Booking.com 216, - Airbnb 139, - ZenHotels.com 3, - mediana nočne cene 158 EUR, - rating prisoten pri 282 karticah, 76 brez ratinga. - Na GN7 je bilo treba namestiti php-xml, ker parser uporablja DOMDocument. - Dodan UI predogled: - trivago_preview.php, - public/js/trivago_dom_preview.js, - docs/trivago_dom_ui.md, - kasneje popravljeno na izbiro shranjene JSON datoteke namesto "Load local sample". - Dodana sky-blue UI varianta za boljšo berljivost: - docs/trivago_sky_ui.md. - Dodana slovenska kopija strani: - trivago_preview_sl.php, - public/js/trivago_dom_preview_sl.js, - docs/trivago_preview_sl.md. - Slovenska stran je namenjena predstavitvi uporabniku: - "Trivago tržni pregled", - "Izberi shranjeni Trivago JSON", - "Prikaži tržni predogled", - "Povzetek", - "Tržne kartice". Git: - Delo poteka na veji feature/price-kit-trivago-market-lab v zasebnem repo: https://github.com/viljemd-hub/channel-manager-internal - Današnji cilj: commit/push stabilnega stanja po UI predogledu. Naslednji možni koraki: - Dodati povezavo do slovenske strani iz glavnega index.php. - Dodati export iz Trivago preview v Market Scope input format. - Dodati primerjalni prikaz: OWN cena proti P25/median/P75. - Kasneje povezati Trivago evidence v Market Report. /////////////////////////////////////////////////////////////////////// # Dodatek k reviziji – CM Market Evidence Kit v1.0 Datum: 30. 6. 2026 Lokacija: /var/www/html/market_evidence_kit Branch: feature/price-kit-trivago-market-lab ## 1. Preimenovanje aktivne delovne mape Aktivni lokalni working copy je bil prečiščen in prestavljen iz: /var/www/html/cm_price_kit_v1_4 v: /var/www/html/market_evidence_kit Repo ostaja isti: viljemd-hub/channel-manager-internal Aktivna veja: feature/price-kit-trivago-market-lab Git status po premiku: working tree clean branch up to date with origin/feature/price-kit-trivago-market-lab ## 2. Nova produktna smer CM Price Kit se repozicionira v: CM Market Evidence Kit Cilj produkta: Iz prilepljenih, uvoženih ali ročno vnesenih tržnih podatkov za izbrano obdobje pripraviti normaliziran cenovni vzorec, očistiti šum, prikazati market signal in izvoziti evidence package za CM PRO ali bodoče aplikacije. Glavno PM pravilo: Ne gradimo več iz skript. Gradimo iz enega produkta in enega toka. ## 3. Dodan contract Dodana datoteka: docs/market_evidence_kit_contract_v1.md Contract določa: - standalone evidence-to-signal produkt, - enotni input workflow, - source detector, - source adapters, - normalized observations, - market core, - cleaned market signal, - Own Price Position, - standalone report, - evidence package export, - no direct price write. ## 4. Dodan core skeleton Dodana datoteka: lib/market_evidence_core.php Core v0.1 trenutno vsebuje: - context normalizacijo, - Subject Profile normalizacijo, - own listing match po own_listing_names, - observation normalizacijo, - outlier flagging, - market signal, - suggested manual range, - Own Price Position, - evidence package builder. Core je adapter-agnostic. Trivago, Booking, CSV/manual in structured JSON adapterji morajo pozneje pripraviti observations, core pa iz tega izdela standardni evidence package. ## 5. Dodan preview endpoint Dodana datoteka: api/market_evidence_preview.php Endpoint sprejme JSON input z: - context, - subject_profile, - source, - observations. Nato pokliče: mek_build_evidence_package($input) in vrne: { "ok": true, "schema_version": "cm_market_evidence_preview_v0.1", "package": { ... } } Preview endpoint ne piše cen in ne spreminja nobenih podatkov. ## 6. Naslednji korak Testirati preview endpoint z ročnim JSON primerom. Če preview vrne market_signal in own_price_position, je core pravilno priklopljen. Potem: 1. povezati Trivago adapter na novi core, 2. dodati human-readable preview UI, 3. šele nato razmišljati o novem enotnem index.php. ## 7. Test preview endpointa – uspešno Datum: 30. 6. 2026 Lokacija: /var/www/html/market_evidence_kit Ročni JSON test z /tmp/mek_preview_test.json je bil uspešno poslan na: https://apartmamatevz.si/market_evidence_kit/api/market_evidence_preview.php Rezultat: - ok = true - schema_version = cm_market_evidence_preview_v0.1 - package.schema_version = cm_market_evidence_package_v1 - observations se normalizirajo - Apartma Matevž je zaznan kot own_listing - market_signal se izračuna - own_price_position se izračuna Market signal test: - sample_size: 6 - used: 5 - excluded: 0 - raw_median_nightly: 158 - cleaned_median_nightly: 158 - p25_nightly: 127 - p75_nightly: 186 - confidence: medium Own Price Position test: - detected: true - listing_name: Apartma Matevž - nightly_price: 165 - diff_from_cleaned_median: 7 - diff_percent_from_cleaned_median: 4.43 - position_label: slightly_above_market Zaključek: Core-preview plast deluje. Naslednji korak je priklopiti Trivago adapter na novi market_evidence_core.php in iz njegovega rezultata izdelati isti evidence package. /////////////////////////////////////////////////////////////////////// # Dodatek k reviziji – Trivago preview UX varovala Datum: 30. 6. 2026 Lokacija: /var/www/html/market_evidence_kit ## Izvedeno Trivago preview endpoint in UI sta nadgrajena. Dodano: - evidence_package v api/trivago_dom_preview.php, - prikaz selected nights v UI, - Market Evidence Signal v UI, - Own Price Position v UI, - zaznava obdobja iz Trivago capture URL-ja, - warning, če se capture obdobje razlikuje od obdobja v obrazcu, - Important check blok v Summary kartici. ## Pomembno PM pravilo Obdobje iz obrazca ostane source of truth. Trivago capture URL se uporablja samo kot kontrolni hint. Če se obdobji razlikujeta, UI prikaže: input_period_differs_from_trivago_capture_period in uporabniku pove, da je uporabljen datum iz obrazca. ## Trenutni status Trivago preview deluje na: https://apartmamatevz.si/market_evidence_kit/trivago_preview.php Testni capture je pokazal: - 175 observations, - 175 unique IDs, - 7 selected nights, - cleaned median nightly 229,5 €, - opozorilo pri mismatchu obdobja deluje, - own listing ni zaznan, zato Own Price Position ni na voljo. ## Naslednji možni korak Naslednji produktni korak je odločitev, ali naj: 1. poliramo Trivago UI v smeri končnega Market Evidence Kit reporta, 2. dodamo export/copy evidence package, 3. začnemo pripravljati novi enotni index.php kot glavni produktni UI.