Los Lagos Hotel logo

Los Lagos Hotel

آخر تحديث

مقدمة

فندق Los Lagos فندق عائلي في إل كالافاتي، البلدة الباتاغونية التي يتخذها معظم المسافرين قاعدة لزيارة نهر بيريتو مورينو الجليدي. عند بدء هذا العمل كان الفندق ينتقل من Minihotel، وهو نظام إدارة أقدم، إلى Cloudbeds. وهذا الانتقال هو ما جعل بقية العمل ممكناً: فما إن صارت الغرف والأسعار والحجوزات في نظام له واجهة برمجية حقيقية، أمكن للفندق أخيراً أن يبيع مباشرة من موقعه الخاص وأن يتحكّم في أسعاره بنفسه.

لذلك بنيتُ له تطبيقَي ويب. الأول هو الموقع ثنائي اللغة الذي يحجز عليه النزلاء، والثاني أداة داخلية يحدّد بها الفندق أسعاره. لا يشبه أحدهما الآخر إطلاقاً، وهذا مقصود. أحدهما واجهة عرض والآخر غرفة عمليات. وما يتشاركانه هو الواجهة الخلفية، وكلاهما يتصل بحساب Cloudbeds نفسه.

المطلوب

لم تكن مشكلة المال معقّدة. فقد كان جزء كبير من حجوزات الفندق يصل عبر Booking.com ومنصات مشابهة، ولكل حجز منها عمولة. وكان للفندق موقع بالفعل، أي أن أولئك النزلاء كان بإمكانهم من حيث المبدأ الحجز مباشرة. لكن الموقع لم يكن يبدو مكاناً تسلّم فيه بطاقتك، ولم يكن سهل الاستخدام. وكلا الأمرين كان يكلّف تحويلات، فظلّت العمولات تُدفع.

يبدو البيع المباشر بسيطاً حتى تنظر إلى ما على الفندق أن يضبطه في الأرجنتين. فـ Cloudbeds يحصّل بالبيزو الأرجنتيني، لكن الفندق ومختصي الإيرادات الذين يسعّرون له يعملون بالدولار، لأن البيزو يتحرّك بما يكفي ليصبح أي سعر محدّد بالبيزو خاطئاً خلال أسبوع. كما أن النزلاء المقيمين خارج الأرجنتين معفَون من ضريبة القيمة المضافة البالغة 21% على الإقامة، وبذلك يكون للغرفة نفسها سعران مشروعان بحسب مكان إقامة النزيل.

وكان الأمران ينتهيان عند مكتب الاستقبال، يُحسمان حالةً بحالة. لذا تلخّص المطلوب في ثلاثة أمور: استقبال الحجوزات على موقع الفندق نفسه، وجعل ذلك الموقع جديراً بأن يُسلَّم فيه رقم بطاقة، وعرض السعر الذي ينطبق فعلاً على كل نزيل دون أن يحسب أحد يدوياً.

التقنيات

موقع النزلاء مبني بـ Next.js مع TypeScript، ومولَّد مسبقاً بشكل ثابت لكل لغة. أما الأداة الداخلية فهي تطبيق React أحادي الصفحة مبني بـ Vite. وSupabase هي الواجهة الخلفية المشتركة: Postgres، وأمان مستوى الصفوف، وEdge Functions. وينتهي كلا التطبيقين بالكتابة إلى واجهة Cloudbeds البرمجية.

Next.js icon
React icon
TypeScript icon
Supabase icon

الموقع الأول: موقع النزلاء

الموقع العام ثنائي اللغة. تحتفظ الإسبانية بالروابط بلا بادئة، محافظةً على المسارات التي يستخدمها موقع الفندق الحالي، وتقع الإنجليزية تحت المسار en. ولا يحتاج الزائر لأول مرة إلى البحث عن ذلك: فالموقع يقرأ اللغة التي يطلبها متصفّحه، ويوجّهه تبعاً لها، ويتذكّر الاختيار في ملف تعريف ارتباط لمدة عام، مع محدِّد في الترويسة لمن يفضّل اللغة الأخرى. وكل صفحة مولَّدة مسبقاً باللغتين حتى تتلقى برامج الزحف HTML حقيقياً بدل هيكل فارغ. وإلى جانب الغرف والفندق نفسه، وُجد معظم المحتوى للإجابة عن الأسئلة التي يطرحها الناس فعلاً قبل حسم رحلة إلى باتاغونيا: كم يبعد المركز، وكيف يصلون من المطار، وما الذي يمكن فعله بعد الوصول.

تفصيلان استمتعت ببنائهما بوجه خاص. تفصل بين الأقسام انتقالات منحنية بصيغة SVG بدل الخط المستقيم المعتاد. وتضم صفحة الموقع خريطة OpenStreetMap تفاعلية بعلامات مخصّصة للفندق وللمطاعم والمعالم والمصارف من حوله، إلى جانب أزمنة الوصول سيراً وبالسيارة إلى المركز ومحطة الحافلات والمطار والنهر الجليدي. كما جُمعت تقييمات TripAdvisor وGoogle وBooking في شريط واحد حتى لا يضطر النزيل إلى البحث عنها.

Los Lagos Hotel homepage hero with the availability search

الصفحة الرئيسية: الواجهة، وأسباب الحجز المباشر، والبحث عن التوافر

تطويع محرّك الحجز ليناسب الفندق

تضمّن صفحة الحجز مكوّن Immersive Experience من Cloudbeds، وهو مكوّن ويب من طرف ثالث يعرض مسار الدفع الخاص به داخل الموقع. وهو عملياً صندوق مغلق، لذا يُضاف كل ما احتاجه الفندق فوقه عبر مراقب واحد يرصد DOM المكوّن ويعيد تطبيق التعديلات في كل مرة يُعاد فيها الرسم. وما تضيفه هذه الطبقة:

  • مبدّل الإقامة. يحدّد النزيل ما إذا كان يقيم في الأرجنتين أم في الخارج، وهو ما يقرّر سريان ضريبة الـ21% على ما يراه، ويكتب علامة فوترة على الحجز ليُطبَّق الإعفاء لاحقاً بدل أن يسجّل موظفو الاستقبال الجنسية يدوياً.
  • أسعار تعود في أصلها إلى الدولار. فالسعر الدائم للفندق بالدولار بينما يُحصَّل من النزيل بالبيزو، ويستند التحويل إلى سعر يجلبه الموقع عبر واجهة برمجية مزوّدة بنطاق معقولية، وحدّ لعمر السعر، وآخر قيمة صالحة كخيار احتياطي، ووضع متدهور يمتنع عن التحويل بدل استخدام سعر مُخمَّن.
  • محدِّد نوع السرير الذي لا يوفّره Cloudbeds. يختار النزيل سريراً مزدوجاً أو سريرين منفصلين لكل غرفة، مع عدّادات محدودة بما هو متاح فعلاً تلك الليلة. أما معرّفات الغرف الفعلية التي يقوم عليها هذا الحساب فتبقى على الخادم ولا تصل إلى المتصفح أبداً.
  • تفصيل سعري مسجَّل. يُكتب الصافي والضريبة والإجمالي بالعملتين، مع سعر الصرف المستخدم، على كل حجز في حقول مخصّصة، بحيث يحصّل مكتب الاستقبال من أرقام التُقطت لحظة الحجز لا من أرقام يُعاد حسابها بعد أيام.
  • تخصيص الغرف تلقائياً. عند اكتمال الحجز يقرأ webhook توزيع الأسرّة الذي طلبه النزيل ويخصّص الغرف الفعلية المتوافقة. ويترك عمداً تخصيص Cloudbeds كما هو حين لا تتوفر غرفة متوافقة، بدل وضع أحدهم في السرير الخطأ.

جاء أكثر الأخطاء إفادةً من ذلك المراقب نفسه. فتحريك عدّاد الكمية الخاص بـ Cloudbeds كان يدفع المكوّن إلى إعادة الرسم، ما يعيد تشغيل المراقب، الذي يحرّك العدّاد من جديد. نقرة واحدة أنتجت أكثر من 600 ألف تغيير في DOM وجمّدت التبويب. وكان الحل حارساً يمنع إعادة الدخول حول مرحلة التعديلات، وصار على كل شيفرة تمسّ DOM الخاص بـ Cloudbeds أن تعمل داخله.

Cloudbeds booking engine with the residency toggle and bed-type selector

محرّك الحجز، مع مبدّل الإقامة ومحدِّد نوع السرير

الموقع الثاني: أداة إدارة الأسعار

تتضمّن بعض أنظمة إدارة الفنادق أدوات إيرادات تؤدي جزءاً من هذا العمل. لكن المشكلة هي الارتهان: إذ ينتهي منطق التسعير إلى العيش داخل منتج طرف آخر، ويصبح الخروج منه لاحقاً مكلفاً. وقد كانت المرونة أهم بالنسبة لهذا العميل، فصار منطق التسعير يقيم في تطبيق منفصل يخصّه، يتصل بـ Cloudbeds عبر واجهته البرمجية بدل أن يسكن داخله.

التطبيق الثاني هو المكان الذي يحدّد فيه الفندق أسعاره. وهو داخلي بحت. لا يوجد تسجيل عام، وينشئ المدير الحسابات. أما الدوران، أي التسعير وطاقم الفندق، فيُفرضان عبر أمان مستوى الصفوف في Postgres ويُعاد التحقق منهما داخل كل دالة ذات صلاحية، لا بإخفاء عناصر التنقل فحسب.

  • تقويم أسعار يعمل بالدولار. يستعين الفندق بشركات إدارة إيرادات خارجية، والدولار هو العملة التي تسعّر بها، ولذلك بالدولار تُدخل أرقامها: سعر أساسي ليوم واحد أو لمدى تواريخ كامل، أو رفع جماعي بملف CSV حين يُعاد تسعير موسم كامل دفعة واحدة. ويشتق كل نوع غرفة سعره الخاص من نسبة مئوية، ويقرّبه صعوداً إلى أقرب عشرين سنتاً، ويحوّله إلى البيزو بسعر Cloudbeds نفسه. والتسعير بالعملة التي تفكّر بها فعلاً هو ما يجعل التسعير الذكي عملياً هنا أصلاً.
  • نشر يتحقّق من عمله بنفسه. يجري النشر على مرحلتين، معاينة ثم تأكيد. تعرض المعاينة بالضبط أي صفوف ستُرسل وما الذي سيستقبله Cloudbeds، وبعد التأكيد يعيد التطبيق قراءة الأسعار من Cloudbeds ويضع لكل منها حالة مؤكَّد أو مُرسَل أو فاشل بحسب ما يعود به.
  • مراقب لسعر الصرف. تقرأ دالة مجدولة السعر الرسمي لمصرف الأمة، ولا تسجّله إلا إذا تغيّر فعلاً، ثم تعيد حساب كل سعر مخزَّن بالبيزو انطلاقاً من مصدره الدائم بالدولار، وتفتح مهمة للموظفين. ولا تُغلق تلك المهمة بمجرد ضغط زر. فإتمامها يعيد قراءة إعدادات العملة في Cloudbeds ولا ينجح إلا عند تطابقها.
  • المحيط التشغيلي: سجل نشاط، وإدارة للفريق، وقسم مساعدة مكتوب لطاقم الفندق لا للمطوّرين، وأمان للحساب بالتحقق بخطوتين ومفاتيح المرور.

وعدم أتمتة تلك الخطوة الأخيرة هو المقصود بالضبط. فعملة مثل البيزو الأرجنتيني قد تتحرّك بحدّة ودون إنذار كافٍ، وأي نظام يعيد تسعير كل الغرف بمجرد اهتزاز مصدر البيانات يصبح مصدر خطر لا وسيلة راحة: إذ تنتقل قراءة خاطئة أو عابرة تماماً مباشرة إلى الأسعار الحيّة، ويكتشف الفندق ذلك وهو يبيع غرفه بأرخص مما ينبغي. لذلك فإن رصد سعر جديد لا يحرّك أي سعر بذاته. بل يسجّل السعر، ويعيد حساب الأسعار الجديدة المحتملة، ويفتح مهمة. ولا تتحرّك الأسعار إلا حين يؤكّد شخص أن السعر مطبَّق فعلاً في Cloudbeds. صحيح أن لدى Cloudbeds تحويلاً تلقائياً خاصاً به يُحدَّث مرتين يومياً من تغذية عالمية، لكنه بالنسبة لهذا الفندق لا يكفي تواتراً ولا يصلح مرجعاً: فما يفوتر به هو السعر الرسمي لمصرف الأمة، لا سعراً وسطياً دولياً.

ونقطة الضعف في خطوة تأكيد بشرية هي أن على أحدهم أن ينتبه إليها. لذلك فإن الدوال نفسها التي تفتح مهمة FX ترسلها أيضاً إلى مجموعة على تيليغرام، عبر بوت كتبته للفندق: السعر السابق، والسعر الجديد، وهل جاء من التغذية التلقائية أم من إدخال يدوي، وزر ينقل مباشرة إلى صفحة المهام في أداة العمليات. ويعيد النشر حين يطبّق أحدهم السعر، مع ذكر من قام بذلك، وإذا عاد السعر إلى قيمته السابقة قبل أن يتحرّك أحد نشر إلغاءً حتى لا يقوم أحد بعمل زائد. والإشعار مصمَّم عمداً بمبدأ أفضل جهد ولا يمكن أن يطلق خطأً أبداً. فمهمة FX تكون مسجَّلة قبل محاولة الإرسال، ولذلك لا يجوز لرمز مفقود أو انقطاع في تيليغرام أن يعطّل تسجيل الأسعار.

Rate Ops dashboard with the latest USD/ARS rate and pending tasks

لوحة المعلومات: آخر سعر صرف، والمهام المعلّقة، ونسبة الإشغال

الخصوصية والموافقة والتحليلات

للأرجنتين نظامها الخاص لحماية البيانات، وهو القانون 25.326 الذي تشرف عليه هيئة AAIP، وقد بُني الموقعان وفقه لا بتعديلهما لاحقاً. يتضمّن موقع النزلاء سياسة خصوصية وسياسة ملفات تعريف ارتباط مكتوبتين وفق ذلك القانون، بما فيها حقوق Habeas Data التي يمنحها وكيفية ممارستها، ولا يجمع مسار الحجز إلا ما يحتاجه الحجز فعلاً.

الموافقة مطبَّقة في الشيفرة لا موصوفة في صفحة فحسب. توجد في موقع النزلاء فئة واحدة غير ضرورية بالضبط، وهي التحليلات، ولا يُحمَّل أي شيء متعلق بها حتى يوافق الزائر صراحةً. وثلاثة عناصر لا تُحجب أبداً: تفضيل اللغة، ومحرّك الحجز نفسه، وتسجيل الاختيار. وهذا ما يحقّق قاعدة الموافقة المسبقة في القانون 25.326، وكذلك اللائحة الأوروبية العامة لحماية البيانات وePrivacy للنزلاء الأوروبيين، وهم كثر.

وخلف تلك البوابة يقع PostHog لتحليلات المنتج وإعادة تشغيل الجلسات، إلى جانب Google Analytics، بحيث يرى الفندق كيف يتنقّل الناس في الموقع فعلاً وأين يتخلّون عن الحجز بدل التخمين. وللأداة الداخلية وثائقها الخاصة: إشعار خصوصية للموظفين، وسجل لأنشطة المعالجة، وسياسة احتفاظ مطبَّقة فعلياً، مع مهمة مجدولة تحذف سجل النشاط بعد 24 شهراً وسجلات طلبات Cloudbeds بعد 90 يوماً.

لماذا تطبيقان لا تطبيق واحد

للشقّين متطلبات مختلفة فعلاً. فموقع النزلاء عام وعليه أن يكون قابلاً للفهرسة، ولذلك يُولَّد مسبقاً لكل لغة. أما أداة العمليات فليس لها أي سطح للسيو، ولا تحتاج إلى عرض من جانب الخادم إطلاقاً، ولذلك فهي تطبيق أحادي الصفحة بسيط يتحدث مباشرة إلى Supabase. أصغر وأرخص وأسهل في التفكير فيه.

أما الواجهة الخلفية فهي النصف المشترك. فكل ما هو حسّاس يعمل داخل Postgres أو داخل Edge Function: رمز Cloudbeds، ومفتاح الخدمة، وكتابة أسعار الصرف. ولا يحمل أي من المتصفحين بيانات اعتماد Cloudbeds في أي وقت.

أين استقر الأمر

أداة العمليات تعمل في الإنتاج ويحدّد بها الفندق أسعاره: فصار تعديل الأسعار كتابة رقم واحد مرة واحدة، ثم معاينته ونشره والتحقق منه مقابل Cloudbeds، بدل مراجعة يدوية لكل نوع غرفة وكل تاريخ. وحتى أغسطس 2026 كان موقع النزلاء قد اكتمل وهو ينتظر التحوّل عن موقع الفندق الحالي؛ وعندها ستصل إليه الحجوزات المباشرة ويرى كل نزيل السعر الذي ينطبق عليه.

ولم يكن جزء لا بأس به من العمل برمجةً. فلأن الاستقبال هو من يحصّل من النزلاء فعلياً، أنتج المشروع أيضاً أدلة بالإسبانية للتحصيل عبر رابط دفع: كيف يتحقّق الموظف من الإقامة التي أعلنها النزيل، ويؤكّد أن سعر الصرف ما زال سارياً، ويطابق المبلغ مع Cloudbeds قبل تحصيل أي شيء.

تطبيقان لفندق صغير: واجهة عرض عليها أن تصمد أمام Google، وغرفة عمليات عليها أن تصمد أمام سعر صرف متحرّك.

شكراً لقراءتك،

خوليو ماسياس غونزاليس

تواصل معي