← All projects
01 / 03

Nuzul

Web + Mobile · Solo-built

Nuzul — Property Booking Marketplace

A full two-sided booking marketplace (Airbnb / Gathern-style) for short-term rentals in Saudi Arabia — guest and host web app, a native Flutter iOS app sharing one JSON API, and a full guest/host mode switch.

Architecture sketch

Web appLaravel · ReactiOS appFlutterJSON APILaravelDatabaseMySQLPaymentsMoyasarwebhook
nuzul.sa
Nuzul web home page — Arabic RTL, Mecca skyline hero, property search
nuzul.sa/search
Nuzul search results page with filters
nuzul.sa/property
Nuzul property detail page with booking widget
Nuzul mobile app — guest home screen

Guest — browse & book

Nuzul mobile app — host property list

Host — manage properties

Web appLaravel, Inertia.js, React 19 + TS, Tailwind v4
Mobile appNative Flutter (iOS), shared JSON API
Booking engineRace-safe date holds, auto refunds, post-stay reviews
PaymentsMoyasar, webhook confirmation, idempotent transactions
MessagingGuest/host chat with a strict, separate support channel
LanguageArabic RTL default + English, custom design system
175+Pest tests
2apps, one API
intmoney, not float
The payment callback and the webhook can land at the same moment — the row lock lets exactly one of them confirm the booking. · app/Actions/ConfirmBooking.php
DB::transaction(function () use ($booking, $payment, $valid): void {
    // Serialize the callback and the webhook: both can arrive at once.
    $fresh = Booking::query()->whereKey($booking->getKey())->lockForUpdate()->first();
    if ($fresh === null || $fresh->status !== BookingStatus::PendingPayment) {
        return; // another request got here first
    }

    $this->record($booking, $payment, $valid ? PaymentStatus::Paid : PaymentStatus::Failed);
    // …
});
→ كل المشاريع
٠١ / ٠٣

نُزُل

ويب + جوال · بناء فردي كامل

نُزُل — منصة حجز عقارات

بنيت بمفردي منصة حجز عقارات ثنائية الاتجاه (على غرار Airbnb أو Gathern) للإيجار قصير المدى في السعودية — تطبيق ويب للضيوف والمضيفين، وتطبيق جوال أصلي بـ Flutter لنظام iOS يشارك واجهة برمجية (API) واحدة مع تطبيق الويب، مع إمكانية التبديل الكامل بين وضع الضيف ووضع المضيف.

مخطط البنية

تطبيق الويبLaravel · Reactتطبيق iOSFlutterالواجهة البرمجيةLaravel · JSONقاعدة البياناتMySQLالدفعMoyasarWebhook
nuzul.sa
الصفحة الرئيسية لموقع نُزُل — عربي RTL، أفق مكة، بحث عن عقارات
nuzul.sa/search
نتائج البحث في نُزُل مع الفلاتر
nuzul.sa/property
صفحة تفاصيل العقار مع أداة الحجز
تطبيق نُزُل — شاشة الضيف الرئيسية

ضيف — تصفّح واحجز

تطبيق نُزُل — قائمة عقارات المضيف

مضيف — إدارة العقارات

تطبيق الويبLaravel وInertia.js وReact 19 مع TypeScript وTailwind v4
تطبيق الجوالFlutter أصلي لنظام iOS، بنفس الـ API
محرك الحجوزاتحجز آمن للتواريخ، استرداد تلقائي، تقييمات بعد الإقامة
الدفعMoyasar، تأكيد عبر Webhook، معالجة آمنة تمنع التكرار
المحادثاتمحادثات فورية ضيف/مضيف، دعم منفصل، خصوصية صارمة
اللغةعربي RTL أساسي وإنجليزي، هوية بصرية مخصصة
+١٧٥اختبار Pest
٢تطبيقين، API واحد
intمبالغ، لا كسور
رد بوابة الدفع والـ Webhook قد يصلان في اللحظة نفسها — قفل الصف يسمح لواحد فقط منهما بتأكيد الحجز. · app/Actions/ConfirmBooking.php
DB::transaction(function () use ($booking, $payment, $valid): void {
    // Serialize the callback and the webhook: both can arrive at once.
    $fresh = Booking::query()->whereKey($booking->getKey())->lockForUpdate()->first();
    if ($fresh === null || $fresh->status !== BookingStatus::PendingPayment) {
        return; // another request got here first
    }

    $this->record($booking, $payment, $valid ? PaymentStatus::Paid : PaymentStatus::Failed);
    // …
});