სტუმრის ვერიფიკაციის პროცესი
ეს სახელმძღვანელო აღწერს, როგორ გამოიყენოთ სასტუმროში მყოფი სტუმრების სია captive portal-ში: როგორ შეადაროთ სტუმრის მიერ შეყვანილი მონაცემები სიას, როდის უნდა დასრულდეს Wi-Fi სესია, რა სიხშირით განაახლოთ სია და რომელი ველები შეინახოთ თურქეთის №5651 კანონის ჩანაწერებისთვის.
რა უნდა მოითხოვოთ პორტალზე#
რადგან სია ოთახისა და პირადობის მონაცემებს ერთად გვაწვდის, ყველაზე გავრცელებული ფორმაა ოთახის ნომერი + გვარი. მხოლოდ ოთახის ნომერი საკმარისი არ არის; მეზობელი ოთახის ნომრის მცოდნე ნებისმიერი პირი შეძლებდა შესვლას. ალტერნატივებია ოთახის ნომერი + პირადობის/პასპორტის ნომერი ან გვარი + დაბადების თარიღი; ეს უკანასკნელი შეინარჩუნეთ სარეზერვო ვარიანტად იმ სტუმრებისთვის, რომელთა პირადობის ნომერი ცარიელია.
შედარების წესები#
სტუმრის მიერ შეყვანილი მნიშვნელობების სიის მნიშვნელობებთან შედარებამდე ორივე მხარის ნორმალიზება მოახდინეთ:
- ოთახის ნომერი: მოაცილეთ ჰარები და გადაიყვანეთ დიდ ასოებში.
roomNameსტრიქონია (შეიძლება იყოს"104","A-12"ან"Villa 3"); ნუ გადაიყვანთ მას რიცხვად და ნუ მოაცილებთ საწყის ნულებს. - გვარი: გადაიყვანეთ დიდ ასოებში (გაითვალისწინეთ თურქული
i → İშესაბამისობა) და ზედიზედ რამდენიმე ჰარი ერთით ჩაანაცვლეთ. სიის მნიშვნელობები ჩვეულებრივ პირადობის დოკუმენტიდან დიდი ასოებით იკითხება. - პირადობის ნომერი: მოაცილეთ ჰარები და გადაიყვანეთ დიდ ასოებში. თურქეთის პირადი ნომერი 11 ციფრისგან შედგება; პასპორტის ნომერი ასოებსა და ციფრებს შეიცავს.
- დაბადების თარიღი: სია აბრუნებს
DD.MM.YYYYფორმატს; თუ თქვენი ფორმა სხვა ფორმატს იყენებს, გადაიყვანეთ.
const norm = (s) => String(s ?? "")
.replace(/\s+/g, " ")
.trim()
.toLocaleUpperCase("tr-TR");
function findGuest(list, room, lastName) {
return list.find((g) =>
norm(g.roomName) === norm(room) && norm(g.lastName) === norm(lastName)
) || null;
}
const guest = findGuest(data.otelde, form.room, form.lastName);
if (!guest) {
// „ოთახის ნომერი და გვარი არ ემთხვევა“ — დათვალეთ წარუმატებელი მცდელობები, 5-ის შემდეგ შეზღუდეთ
}დამთხვეული ჩანაწერის unique მნიშვნელობა hotspot მომხმარებლის იდენტიფიკატორია. როცა იგივე სტუმარი მეორე მოწყობილობიდან შედის, ახლის შექმნის ნაცვლად გამოიყენეთ ამ მნიშვნელობაზე მიბმული ანგარიში და მოწყობილობების ლიმიტი ამ ანგარიშზე გაავრცელეთ.
სესიის ხანგრძლივობა#
checkout გაწერის დაგეგმილი თარიღია და ამ დღის 00:00 (UTC) მომენტზე მიუთითებს; დღის დროს არ შეიცავს. თუ სესიას ამ მომენტამდე გახსნით, სტუმარი წვდომას წასვლის დღის დილით დაკარგავს. სესიის დასასრული გამოთვალეთ თარიღზე სასტუმროს გაწერის საათის დამატებით:
const CHECKOUT_TIME = "12:00"; // სასტუმროს გაწერის საათი
const day = new Date(guest.checkout * 1000)
.toLocaleDateString("en-CA", { timeZone: "UTC" }); // "2026-09-10"
const sessionEnd = new Date(`${day}T${CHECKOUT_TIME}:00+03:00`);თუ სტუმარი გაწერის საათამდე წავა, იგი სიიდან გაქრება; ანგარიში შემდეგი სინქრონიზაციისას დახურეთ. თუ ყოფნა გახანგრძლივდა, checkout იცვლება; სინქრონიზაციისას შეადარეთ ეს ველი და სესიის დასასრული განაახლეთ. გვიანი გაწერისას უფრო უსაფრთხოა, წვდომა ღია დატოვოთ მანამ, სანამ სტუმარი სიაშია.
პერიოდული სინქრონიზაცია#
სია მომენტალური სურათია; ცვლილებების შეტყობინება (webhook) არ არსებობს. სია ფიქსირებული ინტერვალით მიიღეთ და წინასთან unique მნიშვნელობის მიხედვით შეადარეთ:
- ინტერვალი: სასტუმროების უმეტესობისთვის 5 წუთი საკმარისია. თუ სტუმრები ჩასახლებისთანავე ინტერნეტში შესვლას ელიან, შეგიძლიათ 1–2 წუთამდე შეამციროთ; 1 წუთზე ნაკლებს ნუ დააყენებთ.
- ახალი
unique: მოამზადეთ ანგარიში; სტუმარი პორტალზე პირველი შესვლისას დაემთხვევა. - გამქრალი
unique: სტუმარი გაწერილია ან ჯავშანი გაუქმდა. დაასრულეთ სესია და დახურეთ ანგარიში. - იგივე
unique, განსხვავებულიroomNameანcheckout: ოთახის შეცვლა ან ყოფნის გახანგრძლივება. განაახლეთ ანგარიში. - წარუმატებელი მოთხოვნა: დროის ლიმიტის ამოწურვის,
401ან5xxშემთხვევაში შეინარჩუნეთ ბოლო წარმატებული სია; შეცდომის პასუხის საფუძველზე ანგარიშები არასოდეს დახუროთ.
async function sync(prev) {
const res = await fetch(BASE + "/public/json/customer/inhotel", {
method: "POST",
headers: { "ApiKey": process.env.HMS_API_KEY, "HotelCode": HOTEL_CODE }
});
if (!res.ok) return prev; // 401 / 5xx: ძველი სია რჩება
const { success, otelde } = await res.json();
if (success !== 1) return prev;
const next = new Map(otelde.map((g) => [g.unique, g]));
for (const [id] of prev) {
if (!next.has(id)) await closeAccount(id); // გაწერილია
}
for (const [id, g] of next) {
const old = prev.get(id);
if (!old) await openAccount(g); // ახალი სტუმარი
else if (old.checkout !== g.checkout || old.roomName !== g.roomName) await updateAccount(g);
}
return next;
}რამდენიმე სტუმარი ერთ ოთახში#
ოთახის ყოველი სტუმარი ცალკე ჩანაწერია: rezervasyon_id საერთოა, unique — განსხვავებული. ანგარიშები გახსენით სტუმრების და არა ოთახების მიხედვით, რათა თითოეულ სტუმარს ჰქონდეს საკუთარი მოწყობილობა, სესია და №5651 კანონის ჩანაწერი. ოთახის ნომრითა და გვარით ძიებამ ერთი და იმავე გვარის მქონე სტუმრებისთვის (მაგ. ოჯახი) შეიძლება ერთზე მეტი ჩანაწერი დააბრუნოს; პირველი დამთხვევის აღების ნაცვლად განასხვავეთ ისინი სახელით ან დაბადების თარიღით, ან მათთვის საერთო ანგარიში გახსენით.
თურქეთის №5651 კანონის ჩანაწერები#
თურქეთის №5651 კანონით გათვალისწინებული წვდომის ჟურნალის წარმოების ვალდებულება hotspot სისტემას ეკისრება; HMS მხოლოდ პირადობის მონაცემებს აწვდის. სესიის გახსნისას MAC/IP მისამართთან და დროის ნიშნულთან ერთად შეინახეთ შემდეგი ველები: unique, rezervasyon_id, firstName, lastName, identityNumber, birthDate, roomName, checkin, checkout. სიიდან სტუმრის გაქრობის შემდეგ HMS ამ ინფორმაციას აღარ აწვდის; ჩანაწერი თქვენს მხარეს შეინახეთ.